【发布时间】:2019-03-10 01:51:53
【问题描述】:
请注意:这个问题与我当前未解决的问题SQLAlchemy secondary join relationship on multiple foreign keys 相关但独立。
单个类中的SQLAlchemy documentation describes handling multiple join paths用于多个关系:
from sqlalchemy import Integer, ForeignKey, String, Column
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
Base = declarative_base()
class Customer(Base):
__tablename__ = 'customer'
id = Column(Integer, primary_key=True)
name = Column(String)
billing_address_id = Column(Integer, ForeignKey("address.id"))
shipping_address_id = Column(Integer, ForeignKey("address.id"))
billing_address = relationship("Address")
shipping_address = relationship("Address")
class Address(Base):
__tablename__ = 'address'
id = Column(Integer, primary_key=True)
street = Column(String)
city = Column(String)
state = Column(String)
zip = Column(String)
在同一部分中,文档显示了定义关系的三种不同方法:
billing_address = relationship("Address", foreign_keys=[billing_address_id])billing_address = relationship("Address", foreign_keys="[Customer.billing_address_id]")billing_address = relationship("Address", foreign_keys="Customer.billing_address_id")
正如您在 (1) 和 (2) 中看到的那样,SQLAlchemy 允许您定义一个外键列表。事实上,文档明确指出:
在这个具体的例子中,列表在任何情况下都不是必需的,因为我们只需要一个列:
billing_address = relationship("Address", foreign_keys="Customer.billing_address_id")
但我无法确定如何使用列表表示法在单个关系中指定多个外键。
对于课程
class PostVersion(db.Model):
id = db.Column(db.Integer, primary_key=True)
...
tag_1_id = db.Column(db.Integer, db.ForeignKey("tag.id"))
tag_2_id = db.Column(db.Integer, db.ForeignKey("tag.id"))
tag_3_id = db.Column(db.Integer, db.ForeignKey("tag.id"))
tag_4_id = db.Column(db.Integer, db.ForeignKey("tag.id"))
tag_5_id = db.Column(db.Integer, db.ForeignKey("tag.id"))
class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True)
tag = db.Column(db.String(127))
我已经尝试了以下所有方法:
-
tags = db.relationship("Tag", foreign_keys=[tag_1_id, tag_2_id, tag_3_id, tag_4_id, tag_5_id])导致
sqlalchemy.exc.AmbiguousForeignKeysError:无法确定关系 AnnotationVersion.tags 上的父/子表之间的连接条件 - 有多个外键路径链接表。指定 'foreign_keys' 参数,提供应计为包含对父表的外键引用的列的列表。
-
tags = db.relationship("Tag", foreign_keys="[tag_1_id, tag_2_id, tag_3_id, tag_4_id, tag_5_id]")导致
sqlalchemy.exc.InvalidRequestError:初始化映射器 Mapper|AnnotationVersion|annotation_version 时,表达式 '[tag_1_id, tag_2_id, tag_3_id, tag_4_id, tag_5_id]' 未能找到名称(“名称 'tag_1_id' 未定义”)。如果这是一个类名,请考虑在定义了两个依赖类之后将此 relationship() 添加到该类中。
以及列表样式的许多其他变体,在内部和外部使用引号,使用表名和类名。
我实际上已经在这个问题的过程中解决了这个问题。由于似乎没有直接的文档,所以我会自己回答而不是删除这个问题。
【问题讨论】:
-
似乎关联表也很合适,而不是重复的外键和复杂的连接。
-
@IljaEverilä ,我已经听过好几次了,但是关联表的问题(我假设您的意思是
Tag-PostVersion上的多对多)是我想要对每个 PostVersion 可以包含的标签数量进行硬性限制。我之所以得出这个架构,基本上是因为我认真思考了 stackoverflow 如何通过编辑实现标签和问题版本控制。如果标签发生变化,那就是编辑,并且很容易根据它存储新版本的问题。但是,如果它是一个多对多表,这似乎很困难。等待。我得了!我想我刚刚意识到了一个简单的方法!谢谢 Ilj
标签: python sqlalchemy