我有两种模型:游戏和玩家。我想列出游戏模型中的所有玩家,以及其他领域的玩家之一。这是一个Flask服务器和一个sqlite数据库。
这是我的播放器型号:
class Player(db.Model):
id = db.Column(db.Integer, primary_key=True)
# other fields...
game_id = db.Column(db.Integer, db.ForeignKey('game.id'))
game = db.relationship('Game', back_populates='players', foreign_keys=game_id)
这是我的游戏模型:
class Game(db.Model):
id = db.Column(db.Integer, primary_key=True)
# other fields...
current_president_id = db.Column(db.Integer, db.ForeignKey('player.id'))
current_president = db.relationship("Player", foreign_keys=current_president_id)
# other one-to-one relationships to the Player Model, exactly like the first one...
players = db.relationship('Player', back_populates='game', foreign_keys=Player.game_id)
我基于this Response制作了两个模型。但是我仍然收到同样的警告:
SAWarning: Cannot correctly sort tables; there are unresolvable cycles between tables "game, player", which is usually caused by mutually dependent foreign key constraints. Foreign key constraints involving these tables will not be considered; this warning may raise an error in a future release.
就像警告说的那样,当使用这种配置时,我会在某个时候得到:
sqlalchemy.exc.CircularDependencyError: Circular dependency detected. (SaveUpdateState(<Game at 0x23009e00160>), SaveUpdateState(<Player at 0x23009e141c0>), ProcessState(ManyToOneDP(Game.current_president), <Game at 0x23009e00160>, delete=False), ProcessState(OneToManyDP(Game.players), <Game at 0x23009e00160>, delete=False))
我不知道该怎么办,我试图通读文档并测试了许多其他配置,但是没有任何效果。所有帮助,不胜感激。谢谢!
答案 0 :(得分:0)
因此,我尝试更深入地学习SQLAlchemy,并找到了解决方案。首先,以一对一关系将use_alter标志设置为True:
current_president_id = db.Column(db.Integer, db.ForeignKey('player.id', use_alter=True))
这使警告消失。但是您现在仍然需要小心。由于Player模型具有引用Game.id的列,而Game模型具有引用Player.id的列,因此您无法在一次提交中声明关系:
g, p1, p2 = Game(), Player(), Player()
db.session.add_all([g, p1, p2])
db.session.commit()
g.players = [p1, p2]
g.current_president = p3
db.session.commit()
这将引发CircularDependencyError。但这不会:
g, p1, p2 = Game(), Player(), Player()
db.session.add_all([g, p1, p2])
db.session.commit()
g.players = [p1, p2]
db.session.commit()
g.current_president = p3
db.session.commit()