sqlalchemy exists() - 如何避免额外的From

时间:2015-02-11 14:25:51

标签: python sqlalchemy

exists()包含另一个exists()导致额外的From子句。

model.session.query(Table1.id).\
    filter(~ exists().\
         where(Table2.table1_id==Table1.id).\
         where(~ exists().\
                 where(Table3.contract_id==Table2.contract_id).\
                 where(Table3.session_id==Table1.session_id))
         )

这是产生:

SELECT table1.id AS table1_id FROM table1
WHERE NOT (EXISTS (SELECT * FROM table2
            WHERE table2.table1_id = table1.id
            AND NOT (EXISTS (SELECT * FROM table3, table1
                     WHERE table3.contract_id = table2.contract_id
                     AND table3.session_id = table1.session_id))))

这里,不需要最后一个“exists”中的“FROM table1”,因为table1已经在最顶层的查询中。如何强制sqlalchemy不添加额外的“FROM table1”?

我真正想要的是:

SELECT table1.id AS table1_id FROM table1
WHERE NOT (EXISTS (SELECT * FROM table2
          WHERE table2.table1_id = table1.id
          AND NOT (EXISTS (SELECT * FROM table3
                   WHERE table3.contract_id = table2.contract_id
                   AND table3.session_id = table1.session_id))))

我想知道如何实现这一目标。 有人可以帮帮我吗? 使用SQLAlchemy 0.7.9。

1 个答案:

答案 0 :(得分:0)

q = (session.query(Table1.id)
     .filter(~exists(
         select([Table2.id])
         .where(Table2.table1_id == Table1.id)
         .where(~exists(
             # changing exists to be implicit enables the 'important' below
             select([Table3.id])
             .where(Table3.contract_id == Table2.contract_id)
             .where(Table3.session_id == Table1.session_id)
             # this is important
             .correlate(Table1)
             .correlate(Table2)
             ))
     )))