[英]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.