SQLAlchemy并排放置子查询,而不是嵌套

时间:2020-03-16 15:35:18

标签: python postgresql flask sqlalchemy

我有一个包含两个子查询的查询。在SQL中,它大致如下所示:

SELECT sq2.foo,
       sq2.bar
FROM (
      SELECT foo FROM bar WHERE foo = '123'
) AS sq1,
LATERAL (
      SELECT foo, bar FROM bar WHERE s1.foo = 'zomething'
) AS sq2
WHERE sq2.foo = 'something';

这是我从SQLAlchemy中需要的。当我将其翻译为Alchemy时,我大致得到了这样的信息:

sq1 = session.query(Bar.foo).filter(Bar.foo == '123').subquery()
sq2 = session.query(Bar.foo).filter(sq1.foo == 'zomething').subquery().lateral()
session.query(sq2.foo, sq2.bar).filter(sq.foo = 'something').all()

但是,这并不等同于顶级SQL,而是像这样嵌套查询:

SELECT sq2.foo,
       sq2.bar
FROM LATERAL (
    SELECT foo, bar FROM (
        SELECT foo FROM bar WHERE foo = '123'
    ) AS sq1,
    bar
    WHERE sq1.foo = 'zomething'
) AS sq2
WHERE sq2.foo = 'something';

基于这个简化的示例,可能由于太复杂而难以解释的原因,因此无法产生相同的结果。但是,如果我将最终查询更改为包含sq1中不需要的内容,则SQLAlchemy会做正确的事情,例如:

session.query(sq2.foo, sq2.bar, sq1.foo).filter(sq.foo = 'something').all()

现在,它将返回具有正确结构的查询。有没有办法在不包含毫无价值的数据的情况下并排执行子查询?

1 个答案:

答案 0 :(得分:1)

您需要使用select_from

sq1 = session.query(Bar.foo).filter(Bar.foo == '123').subquery().alias('sq1')
sq2 = session.query(Bar.foo, Bar.bar).filter(sq1.c.foo == 'zomething').subquery().lateral('sq2')
q = session.query(sq2.c.foo, sq2.c.bar).select_from(sq1, sq2).filter(sq2.c.foo == 'something')

# >> print(q)
# SELECT sq2.foo AS sq2_foo, sq2.bar AS sq2_bar 
# FROM LATERAL (SELECT bar.foo AS foo, bar.bar AS bar 
# FROM bar 
# WHERE sq1.foo = %(foo_1)s) AS sq2, (SELECT bar.foo AS foo 
# FROM bar 
# WHERE bar.foo = %(foo_2)s) AS sq1
# WHERE sq2.foo = %(foo_3)s
相关问题