SQLAlchemy 联合查询括号问题

9

我需要生成类似以下查询语句的查询:

(select * from ... where .. and .. order by .. limit ..)
union all
(select * from ... where .. and .. order by .. limit ..)
order by ..

使用SQLAlchemy,我创建两个查询对象如下所示:
q1 = Session.query(..).filter(..).filter(..).order_by(..).limit(..)
q2 = Session.query(..).filter(..).filter(..).order_by(..).limit(..)
q = q1.union_all(q2).order_by(..).all()

然而它不起作用是因为SQLAlchemy生成的查询语句q1和q2没有放在括号内,这将导致错误。如何使得q1和q2的语句在联合后放在括号内以满足上述查询条件呢?
1个回答

19

你需要创建子查询,然后从这些子查询中进行选择:

from sqlalchemy import union_all

q1 = Session.query(..).filter(..).filter(..).order_by(..).limit(..).subquery()
q2 = Session.query(..).filter(..).filter(..).order_by(..).limit(..).subquery()
q = Session.query(..).select_entity_from(union_all(q1.select(), q2.select()).order_by(..).all()

.subquery() 方法 返回一个 Alias 对象,该对象不支持直接执行 union_all 查询。因此,我们需要构建一个 select_entity_from() 构造器,并传入 sqlalchemy.sql.expression.union_all() 函数 的结果,以便正确地映射结果到相应的对象。


嗨,Martijn。这里联合查询的query()函数的目的是什么? - Phil
你的情况与 此 sqlalchemy 列表线程 完全相同。它使用了相同的技术。.subquery() 返回一个别名对象,它没有 union_all 方法,所以我们必须使用 .select_from() 代替,并结合使用 union_all 函数。 - Martijn Pieters
确实如此,而且确实有效!谢谢。我已经在各个地方不停地搜索了一段时间,令人惊讶的是没有找到那个帖子。我真是太傻了。再次感谢! - Phil
这对我没有起作用(我得到了额外的行),直到我将 select_from 更改为 select_entity_from。不确定为什么我的情况不同。 - Greg Ennis
0.9版本中的行为发生了变化(此答案早于0.9版本),现在应该使用select_entity_from()方法。 - Martijn Pieters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接