首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >此关系是否需要多个关联表?

此关系是否需要多个关联表?
EN

Stack Overflow用户
提问于 2012-01-09 10:20:51
回答 2查看 306关注 0票数 0

我正在尝试找到最好的方法来构建一个将许多常量映射到许多项的关系。

我最初的关系,一个项目有一个常量,看起来是这样的。

代码语言:javascript
代码运行次数:0
运行
复制
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")

然而,我真的需要我的项目有一个以上的常量,就像这样…

代码语言:javascript
代码运行次数:0
运行
复制
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")

我的第一个尝试是使用关联表...

代码语言:javascript
代码运行次数:0
运行
复制
item_to_constant_assoc = Table("itemToConstantAssoc", Base.metadata, Column("constantId", Integer, ForeignKey("Constant.id"), Column("itemId", Integer, ForeignKey("Item.id")))

同时相应地更新Item类:

代码语言:javascript
代码运行次数:0
运行
复制
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!)我可能刚刚忽略了一个部分。有人能为我提供一些关于这个问题的建议,或者我应该在文档中寻找的东西吗?

谢谢!菲尔

EN

回答 2

Stack Overflow用户

发布于 2012-01-09 12:33:09

只见树木不见森林。这很容易通过在关系上使用primaryjoin参数来实现。

代码语言:javascript
代码运行次数:0
运行
复制
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")
票数 2
EN

Stack Overflow用户

发布于 2012-01-09 19:11:12

多对多关联已经允许每个项具有无限数量的常量。你不需要比这更多的东西作为你的两个基表。

代码语言:javascript
代码运行次数:0
运行
复制
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也涉及到联接。

我认为将常量与所有相关项相关联或将项与所有相关常量相关联的通用查询将如下所示。

代码语言:javascript
代码运行次数:0
运行
复制
  query(Item). join(item_to_constant_assoc.itemId==Item.itemId). join(item_to_constant_assoc.contantId==Constant.constantId
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8783282

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档