我正在尝试找到最好的方法来构建一个将许多常量映射到许多项的关系。
我最初的关系,一个项目有一个常量,看起来是这样的。
class Constant(Base):
__tablename__ = "Constant"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(64), nullable=False)
class Item(Base):
__tablename__ = "Item"
id = Column(Integer, primary_key=True, autoincrement=True)
constantId = Column(Integer, ForeignKey("Constant.id"))
constant = relationship("Constant")
然而,我真的需要我的项目有一个以上的常量,就像这样…
class Item(Base):
__tablename__ = "Item"
id = Column(Integer, primary_key=True, autoincrement=True)
constant1Id = Column(Integer, ForeignKey("Constant.id"))
constant1 = relationship("Constant")
constant2Id = Column(Integer, ForeignKey("Constant.id"))
constant2 = relationship("Constant")
我的第一个尝试是使用关联表...
item_to_constant_assoc = Table("itemToConstantAssoc", Base.metadata, Column("constantId", Integer, ForeignKey("Constant.id"), Column("itemId", Integer, ForeignKey("Item.id")))
同时相应地更新Item类:
Class Item(Base):
__tablename__ = "Item"
id = Column(Integer, primary_key=True, autoincrement=True)
constant1 = relationship("Constant", secondary=item_to_constant_assoc, uselist=False)
constant2 = relationship("Constant", secondary=item_to_constant_assoc, uselist=False)
这会失败(在查看创建的MySQL表时可以理解),因为Item.constant1和Item.constant2引用了关联表中的相同条目。
我的下一步是为第二个常量添加另一个关联表,但我不得不怀疑我是否创建了错误的树,因为我似乎正在为一个相对简单的映射创建大量的表。我已经看过文档了。它是详细和实质性的(感谢Michael Bayer!)我可能刚刚忽略了一个部分。有人能为我提供一些关于这个问题的建议,或者我应该在文档中寻找的东西吗?
谢谢!菲尔
发布于 2012-01-09 04:33:09
只见树木不见森林。这很容易通过在关系上使用primaryjoin
参数来实现。
class Item(Base):
__tablename__ = "Item"
id = Column(Integer, primary_key=True, autoincrement=True)
constant1Id = Column(Integer, ForeignKey("Constant.id"))
constant1 = relationship("Constant", primaryjoin="Constant.id==Item.constant1Id")
constant2Id = Column(Integer, ForeignKey("Constant.id"))
constant2 = relationship("Constant", primaryjoin="Constant.id==Item.constant2Id")
发布于 2012-01-09 11:11:12
多对多关联已经允许每个项具有无限数量的常量。你不需要比这更多的东西作为你的两个基表。
class Constant(Base):
__tablename__ = "Constant"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(64), nullable=False)
class Item(Base):
__tablename__ = "Item"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(64), nullable=False)
item_to_constant_assoc = Table("itemToConstantAssoc", Base.metadata, Column("constantId", Integer, ForeignKey("Constant.id"), Column("itemId", Integer, ForeignKey("Item.id")))
在这一点上,每个项目都有无限数量的常量。当您想要一个特定的常量时,您必须通过常量表中的名称属性来查询常量。您的关联表只是一个密钥对列表:(itemID,constantId)。
一个项目的所有常量的集合是一个包含三个表的连接,用于所有关联行,并与给定项目的匹配常量行连接。
常量的所有项的集合是针对所有关联行的三表连接,以及与给定常量的匹配项行的连接。
需要通过join检索项的特定常量。你可以把它想象成给定项目的所有常量的集合,其中项目和常量名称都是给定的。即使只检索了一行,SQL也涉及到联接。
我认为将常量与所有相关项相关联或将项与所有相关常量相关联的通用查询将如下所示。
query(Item). join(item_to_constant_assoc.itemId==Item.itemId). join(item_to_constant_assoc.contantId==Constant.constantId
https://stackoverflow.com/questions/8783282
复制