(更新:完整的工作代码示例为here。)
此Many-To-One关系
class City(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(32), index=True)
country_id = db.Column(db.Integer, db.ForeignKey('country.id'))
country = db.relationship('Country', back_populates='cities')
class Country(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(32), index=True)
cities = db.relationship('City', back_populates='country')
可以augmented区分众多之一,比如资本。
在这两个解决方案中,添加单独的表是可行的
class Capital(db.Model):
# https://stackoverflow.com/q/45767923/8099646
id = db.Column(db.Integer, primary_key=True)
country = db.Column(db.Integer, db.ForeignKey('country.id'))
capital = db.Column(db.Integer, db.ForeignKey('city.id'))
但更好的解决方案是避免额外的表格,只需插入一个字段:
class Country(db.Model):
...
capital = db.Column(db.Integer, db.ForeignKey('city.id'))
为什么SQLalchemy会在添加该行时抱怨AmbiguousForeignKeysError
?
答案 0 :(得分:1)
原因是现在SQLAlchemy不知道country
/ cities
关系所引用的连接条件,因为有两种可能性(即country_id
和capital
)。
解决此问题的方法是明确指定foreign_keys
:
class City(db.Model):
...
country = db.relationship('Country', foreign_keys=country_id, back_populates='cities')
class Country(db.Model):
...
cities = db.relationship('City', foreign_keys=City.country_id, back_populates='country')
请注意,这种循环模式在创建表时也会导致CircularDependencyError
(因为每个都不能在没有另一个的情况下创建)以及插入时具有两个相互依赖的关系(因为每个行都不能插入而没有另一个行的ID)。因此,完整的解决方案是在其中一个use_alter
上设置ForeignKey
(在创建表时发出ALTER
以便打破周期)并在其中一个上设置post_update
relationship
s(在插入时发出UPDATE
以打破周期):
class City(db.Model):
...
country_id = db.Column(db.Integer, db.ForeignKey('country.id'))
country = db.relationship('Country', foreign_keys=country_id, back_populates='cities')
class Country(db.Model):
...
capital_id = db.Column(db.Integer, db.ForeignKey('city.id', use_alter=True))
capital = db.relationship(City, foreign_keys=capital_id, post_update=True)
cities = db.relationship(City, foreign_keys=City.country_id, back_populates='country')