[英]SqlAlchemy Foreign Key Error on Many to Many Relationship
我正在嘗試在 SqlAlchemy 中建立基本的多對多關系。 我能夠使用 db.create_all() 成功創建數據庫,但是在嘗試從數據庫中檢索任何記錄時遇到錯誤。
class Geo(db.Model):
__tablename__ = 'geos'
geo = db.Column(db.Integer, primary_key=True)
states = db.relationship("State", secondary='geos_states')
class State(db.Model):
__tablename__ = 'states'
state_short = db.Column(db.String, primary_key=True)
geos = db.relationship("Geo", secondary='geos_states')
class GeoState(db.Model):
__tablename__ = 'geos_states'
id = db.Column(db.Integer, primary_key=True)
geo_id = db.Column(db.Integer, db.ForeignKey('geos.geo')),
state_short_id = db.Column(db.String, db.ForeignKey('states.state_short'))
錯誤如下:
sqlalchemy.exc.InvalidRequestError: One or more mappers failed to initialize - can't proceed with initialization of other mappers. Original exception was: Could not determine join condition between parent/child tables on relationship Geo.states - there are no foreign keys linking these tables via secondary table 'geos_states'. Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or specify 'primaryjoin' and 'secondaryjoin' expressions.
您使用的模式是 SQLAlchemy 中多對多關系模式的變體。
通常你會做的是以下
geostates_association_table = Table(
'geo_states', Base.metadata,
db.Column(
'geo_id', db.Integer,
db.ForeignKey('geos.geo')
),
db.Column(
'state_short_id', db.String,
db.ForeignKey('states.state_short')
)
)
class Geo(db.Model):
__tablename__ = 'geos'
geo = db.Column(db.Integer, primary_key=True)
states = db.relationship(
"State",
secondary= geostates_association_table,
back_populates='geos'
)
class State(db.Model):
__tablename__ = 'states'
state_short = db.Column(
db.String,
primary_key=True
)
geos = db.relationship(
"Geo",
secondary=geostates_association_table,
back_populates='states'
)
我認為這是您所需要的,因為在多對多關系中的映射表上似乎不需要任何其他列。 但是,如果您這樣做了,則需要使用您最初正在做的 Association Object 模式。 在這種情況下
class Geo(db.Model):
__tablename__ = 'geos'
geo = db.Column(
db.Integer,
primary_key=True
)
states = db.relationship(
"GeoState",
back_populates="geos"
)
class State(db.Model):
__tablename__ = 'states'
state_short = db.Column(
db.String,
primary_key=True
)
geos = db.relationship(
"GeoState",
back_populates="states"
)
class GeoState(db.Model):
__tablename__ = 'geos_states'
# Notice how we set primary keys on both the fields
geo_id = db.Column(
db.Integer,
db.ForeignKey('geos.geo'),
primary_key=True
),
state_short_id = db.Column(
db.String,
db.ForeignKey('states.state_short'),
primary_key=True
),
some_other_field = db.Column(
db.String
)
geos = relationship("Geo", back_populates="states")
states = relationship("State", back_populates="geos")
請注意,在這種情況下,您將在State
和Geo
的關系列表中獲得的內容實際上是GeoState
對象。 如果您想使用關聯 Object 模式,但讓關系列表由它們各自的對應對象填充。 您可以使用 AssociationProxy sqlalchemy 擴展,您可以在此處找到文檔
供你參考,
此處記錄了關聯 Object 模式
此處記錄了基本的多對多模式
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.