【发布时间】:2023-04-09 09:04:01
【问题描述】:
对于可以具有角色子组的组,我有以下简化代码:
from sqlalchemy import (
CheckConstraint,
Column,
ForeignKey,
PrimaryKeyConstraint,
String,
create_engine,
)
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship
Base = declarative_base()
class Group(Base):
__tablename__ = 'groups'
name = Column(String, primary_key=True)
group_roles = relationship('GroupRole', back_populates='group')
class GroupRole(Base):
__tablename__ = 'group_roles'
name = Column(String, ForeignKey(Group.name))
group_name = Column(String, ForeignKey(Group.name))
role = Column(String, nullable=False)
__table_args__ = (
CheckConstraint('name != group_name'),
PrimaryKeyConstraint('name', 'group_name'),
)
group = relationship(Group,
foreign_keys=[name],
back_populates='group_roles')
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
session = sessionmaker(bind=engine)()
session.add(Group(name='test'))
当我运行它时,我得到sqlalchemy.exc.AmbiguousForeignKeysError: Could not determine join condition between parent/child tables on relationship Group.group_roles - there are multiple foreign key path
s linking the tables. Specify the 'foreign_keys' argument, providing a list of those columns which should be counted as containing a foreign key reference to the parent table.
我还尝试在GroupRole 表下方添加以下内容,以代替Group 中已经定义的相应行:
Group.group_roles = relationship('GroupRole', foreign_keys=[Column(String, ForeignKey(GroupRole.name))], back_populates='group')
但我遇到了同样的错误,而且看起来其他人不必这样做。我究竟做错了什么?如何让我的GroupRole 表引用我的Group 表?我正在使用 SQLAlchemy 1.3 和 python 3.7。
【问题讨论】:
-
你为什么认为你首先需要这个“对父级的双重引用”?在
GroupRole中,您将name和group_name显式定义为相同的外键,并且您还将group定义为关系。这实际上看起来更像是“对我的三重引用”。也许尝试只使用一个。 -
所以这大大简化了,我还在实际代码中的组中获得了用户角色:在一天结束时,我希望每个组都有一个 user_roles 属性,该属性链接到用户角色和另一个链接到(子)group_roles。 IE。一个组由其他组和用户组成,每个组和用户都有自己的角色
-
也许这是少有的例子之一,不太简化的例子是有意义的,我想说在
GroupRole.group关系上使用简单的backref,但我忍不住感觉我从这张图片中遗漏了一些东西,双外键业务与检查约束配对。无论如何,我的直觉是,这更多是数据模型本身的问题。 -
例如,在下面查看我的答案。我仍然不确定
Group.name上GroupRole.name的外键,也许更详细的例子可以解释。
标签: python sqlalchemy foreign-keys