2015-02-11 56 views
0

exists()包含另一個exists()會導致額外的From子句。sqlalchemy 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)))) 

這裏,「FROM表1」中的最後一個「存在」是不是必需的,因爲表1是已經在最上面的查詢。我如何強制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。

回答

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) 
      )) 
    ))) 
+0

謝謝!這是工作。除了我必須將關聯(Table1)替換爲關聯(Table1.table),因爲Table1是一個類。 – AhK 2015-02-12 05:54:49

+0

奇怪你*有*,因爲關聯也接受映射類作爲參數。但很高興它按預期工作。 – van 2015-02-12 06:00:20