SQLAlchemy一对多关系澄清

时间:2016-03-16 02:15:08

标签: sqlalchemy

在阅读了SQLAlchemy文档之后,我仍然不清楚实际上应该如何指定一对多关系。我将细分文档并解释为什么我感到困惑(http://docs.sqlalchemy.org/en/latest/orm/basic_relationships.html#one-to-many):

  

一对多关系将外键放在子表上   引用父母。

看起来我要在模型上放置一些Column属性,这些属性将出现在"很多"关系的一面。

  然后在父项上指定

relationship(),作为引用子项表示的项集合:

这意味着父母有一些属性指定参与"许多"关系的一面。

如果不是因为可能存在我想要与关系两边的相同参与者定义两个一对多关系的情况,那么这对我来说是完全合理的。< / p>

SQLAlchemy如何知道&#34;很多&#34;上的ForeignKey列。关系的一侧对应于放置在&#34;一个&#34;上的relationship属性。侧?

1 个答案:

答案 0 :(得分:1)

这样设置了一对多的关系:

class Group(Base):
    id = Column(Integer, primary_key=True)
    users = relationship(lambda: User)

class User(Base):
    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey(Group.id))

SQLAlchemy推断您打算使用parent_id作为users的连接条件,因为它是连接两个表的唯一外键。

如果您有循环关系:

class Group(Base):
    id = Column(Integer, primary_key=True)
    owner_id = Column(Integer, ForeignKey("users.id"))
    users = relationship(lambda: User)

class User(Base):
    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey(Group.id))
    owned_groups = relationship(Group)

如果您尝试这样做,它将无法工作,因为SQLAlchemy抱怨它无法推断出为每个关系使用的外键。相反,你必须明确告诉它使用什么:

class Group(Base):
    id = Column(Integer, primary_key=True)
    owner_id = Column(Integer, ForeignKey("users.id"))
    users = relationship(lambda: User, foreign_keys=lambda: User.parent_id)

class User(Base):
    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey(Group.id))
    owned_groups = relationship(Group, foreign_keys=Group.owner_id)

带有backrefs的更完整示例:

class Group(Base):
    id = Column(Integer, primary_key=True)
    owner_id = Column(Integer, ForeignKey("users.id"))
    users = relationship(lambda: User, foreign_keys=lambda: User.parent_id, back_populates="parent")
    owner = relationship(lambda: User, foreign_keys=owner_id, back_populates="owned_groups")

class User(Base):
    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey(Group.id))
    owned_groups = relationship(Group, foreign_keys=Group.owner_id, back_populates="owner")
    parent = relationship(Group, foreign_keys=parent_id, back_populates="users")