SQLAlchemy如何反映多对多关系

Posted

技术标签:

【中文标题】SQLAlchemy如何反映多对多关系【英文标题】:SQLAlchemy how to reflect many-to-many relationships 【发布时间】:2021-07-22 12:09:47 【问题描述】:

我有两个具有多对多关系的现有表。 我正在尝试从这些表中查询,但似乎我无法反映它们的多对多关系。

假设我有两个模型和这样的参考表

from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import declarative_base, relationship
from sqlalchemy import Table

Base = declarative_base()

family_tree = Table(
    "family_tree",
     Base.metadata,
     Column("brother_id", Integer, ForeignKey("brother.id"), primary_key=True),
     Column("sister_id", Integer, ForeignKey("sister.id"), primary_key=True),
)

class Sister(Base):
    __tablename__ = 'sister'
    id = Column(Integer, autoincrement=True, primary_key=True)
    brothers = relationship("Brother", secondary=family_tree, back_populates="sisters", 
    uselist=True)

class Brother(Base):
    __tablename__ = 'brother'
    id = Column(Integer, autoincrement=True, primary_key=True)
    sisters = relationship("Sister", secondary=family_tree, back_populates="brothers", 
    uselist=True)

并且我已经填充了所有三个表。我现在想访问给定Sister 表条目的brothers 信息。

我尝试像这样访问sister

class SisterInspector(Base):
     __tablename__ = 'sister'
     __table_args__ = 'autoload': True

session.query(SisterInspector).first()

很好用

session.query(SisterInspector.id)

但在尝试时抛出AttributeError

session.query(SisterInspector.brothers)
>>> AttributeError: 'Sister' object has no attribute 'brothers'

我尝试用这种替代方式访问我的表

from sqlalchemy.schema import Table, MetaData
meta = MetaData()
meta.reflect(bind=engine)
foo = Table('sister', meta, autoload_with=engine)
print(foo.columns)
>>>> ImmutableColumnCollection(sister.id)

我了解关系不是定义为列,而是

foo
>>>> Table('sister',...)

也没有提及上述关系。如何从我的数据库中获取多对多关系?

【问题讨论】:

【参考方案1】:

我不确定 SisterInspector 类为你做了什么,我的 SQLAlchemy 实现没有使用这样的特殊检查器类——我想知道它使用与 Sisters 类相同的表名是否是是什么导致了问题。

你能给我们类似的输出吗

first_sister = session.query(Sister).first()

打印(first_sister.brothers)

【讨论】:

以上是关于SQLAlchemy如何反映多对多关系的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 SQLAlchemy 建立多对多关系:一个很好的例子

SqlAlchemy 和 Flask,如何查询多对多关系

如何在 SQLAlchemy ORM 上实现对同一属性的自引用多对多关系?

sqlalchemy 如何使用 automap_base 生成(多对多)关系

具有多个多对多关系的 SQLAlchemy

如何从 SqlAlchemy 中的多对多集合中删除所有项目?