2012-06-21 69 views
6

如何在加入2個表時將2個條件添加到ON子句中。 我有三個層次結構的三個表,每個都有刪除標誌。我必須在一個查詢中加入所有這些表格,並根據刪除的標誌進行過濾。目前條件被添加到查詢的where子句中,該子句不會過濾已刪除的記錄。 它需要被添加到ON子句中。請建議。sqlalchemy - 加入2個條件的子表

我當前的查詢如下:

result = session.query(Host).filter(and_(Host.id.in_(ids), Host.deleted == False)).\ 
    join(Switch).filter(Switch.deleted == False).\ 
    join(Port).filter(Port.deleted == False).\ 
    options(joinedload('switches')).\ 
    options(joinedload('ports')).\ 
    all() 

三江源

回答

5

您可以使用onclause參數Query.join調用明確地指定ON條款。然後你查詢應該如下(沒有測試):

from sqlalchemy import and_ 

result = (session.query(Host).filter(and_(Host.id.in_(ids), Host.deleted == False)). 
    join(Switch, and_(Switch.host_id==Host.id, Switch.deleted == False)). 
    join(Port, and_(Port.switch_id==Switch.id, Port.deleted == False)). 
    options(joinedload('switches')). 
    options(joinedload('ports')). 
    all() 
) 
+0

嗨範,這不是添加結果的過濾器。謝謝 – Prasadnsr

+1

您可以打印生成的SQL查詢嗎? (只需從代碼中刪除* .all()*並打印出來) – van

13

嘗試contains_eager而不是joinedload。什麼是可能發生的事情是,你有4加入你加入定義的兩個,然後再兩個從選項(joinedload(...))

修改代碼,應該給這個:

from sqlalchemy import and_ 

result = (session.query(Host).filter(and_(Host.id.in_(ids), Host.deleted == False)). 
    join(Switch, and_(Switch.host_id==Host.id, Switch.deleted == False)). 
    join(Port, and_(Port.switch_id==Switch.id, Port.deleted == False)). 
    options(contains_eager('switches')). 
    options(contains_eager('ports')). 
    all() 
) 
1

The and_() conjunction is also available using the Python & operator(但要注意的是複合表達式需要爲了使用Python運算符優先級行爲的功能被括號): 也有| for or_()~ for not_()

因此,使用&操作你的代碼看起來就像這樣:

result = session.query(Host).filter(Host.id.in_(ids) & (Host.deleted == False)). 
    join(Switch, (Switch.host_id==Host.id) & (Switch.deleted == False)). 
    join(Port, (Port.switch_id==Switch.id) & (Port.deleted == False)). 
    options(contains_eager('switches')). 
    options(contains_eager('ports')). 
    all() 
)