2012-06-21 17 views
6

Come aggiungere 2 condizioni alla clausola ON quando si uniscono 2 tabelle. Ho 3 tre tabelle in gerarchia ognuna con il flag cancellato. Devo unire tutte queste tabelle in una singola query e filtrare anche in base al flag eliminato. Attualmente le condizioni vengono aggiunte alla clausola where della query, che non filtra i record eliminati. Deve essere aggiunto alla clausola ON. Si prega di suggerire.sqlalchemy - join child table con 2 condizioni

La mia domanda attuale è la seguente:

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() 

Grazie

risposta

5

È possibile specificare la clausola ON esplicitamente nel Query.join chiamata utilizzando onclause parametro. Poi si esegue una query dovrebbe essere simile di seguito (non testati):

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

Ciao Van, Questo non aggiunge i filtri al risultato. Grazie – Prasadnsr

+1

Potresti per favore stampare la query SQL risultante? (rimuovi * .all() * dal codice e stampalo) – van

13

contains_eager Prova invece di joinedload. Che cosa sta succedendo, probabilmente è che avete 4 unisce le due è stata definita con aderire e quindi poi i due dalle opzioni (joinedload (...))

Modificare il vostro codice, dovrebbe dare a questo:

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 (anche se nota che le espressioni composte devono essere tra parentesi per funzionare con il comportamento Python precedenza degli operatori): ci sono anche | for or_() e ~ for not_()

Quindi, utilizzando & operatore il codice sarà simile a questa:

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() 
)