我一直在努力为此整理正确的查询,并且需要一些帮助。我有两个具有多对多关系的表。我想使用表 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
对象上全局运行(这就是我的意图)。如有任何建议,我们将不胜感激 - 谢谢!
好吧,我想我已经解决了这个问题。答案是使用子查询:
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]