SQLAlchemy 从过滤后的多对多关系中查询不同值

问题描述 投票:0回答:1

我一直在努力为此整理正确的查询,并且需要一些帮助。我有两个具有多对多关系的表。我想使用表 A 中的过滤值对表 B 中的所有不同值进行高性能查询:

association_table = Table(
    "a_b",
    BaseModel.metadata,
    Column("a_id", ForeignKey("a.id"), primary_key=True),
    Column("b_id", ForeignKey("b.id"), primary_key=True),
)


class A(BaseModel):
    __tablename__ = "a"

    id: Mapped[int] = mapped_column(primary_key=True)

    field_a: Mapped[str] = mapped_column(nullable=False)
    field_b: Mapped[str] = mapped_column(nullable=False)
 
    b: Mapped[List["B"]] = relationship(
        secondary=job_tag_association_table, 
        back_populates="a", 
        passive_deletes=True
    )


class B(BaseModel):
    __tablename__ = "b"

    id: Mapped[int] = mapped_column(primary_key=True)

    name: Mapped[str] = mapped_column(nullable=False)

    b: Mapped[List["A"]] = relationship(
        secondary=job_tag_association_table, 
        back_populates="b", 
        passive_deletes=True
    )

我有一个预先过滤的 A 对象查询 (

sqlalchemy.orm.query.Query
),我从类似
A.query.where(A.field_a == 'something')
的东西中获得。我无权访问此查询的内部结构,但为了解决此问题,我们需要知道它相当于
A.query
返回的过滤查询。

我想将此查询与 B 结合起来,并获取这些过滤后的 A 对象的子集的 B.name 的不同值。下面是我尝试做的一些示例:


filtered_a = A.query

[i for i in filtered_a.join(A.b).distinct(B.name)]

上面返回了

A
对象的列表,但我正在寻找
B
对象的列表(而且我似乎无法获取,因为
i.b
似乎不起作用。我也是不确定 distinct 是否在单个对象级别上运行,或者是否在所有
A
对象上全局运行(这就是我的意图)。如有任何建议,我们将不胜感激 - 谢谢!

python sqlalchemy orm many-to-many
1个回答
0
投票

好吧,我想我已经解决了这个问题。答案是使用子查询:

b = B.query.join(
    B.a.of_type(aliased(A, filtered_a.subquery()))
).distinct(B.name)

# List of strings as intended
[i.name for i in b]
© www.soinside.com 2019 - 2024. All rights reserved.