2012-06-21 18 views
6

Cómo agregar 2 condiciones a la cláusula ON cuando une 2 tablas. Tengo 3 tres tablas en jerarquía, cada una con el indicador eliminado. Tengo que unir todas estas tablas en una sola consulta y filtro basado en el indicador eliminado también. Actualmente, las condiciones se agregan a la cláusula where de la consulta, que no filtra los registros eliminados. Se debe agregar a la cláusula ON. Por favor recomiende.sqlalchemy - join tabla hija con 2 condiciones

Mi consulta actual es la siguiente:

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

Gracias

Respuesta

5

Puede especificar la cláusula ON explícitamente en la llamada Query.join usando onclause parámetro. A continuación, se consulta debe ser similar a continuación (no probados):

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

Hi Van, Esto no agrega filtros al resultado. Gracias – Prasadnsr

+1

¿Podría imprimir la consulta SQL resultante? (simplemente elimine * .all() * del código e imprímalo) – van

13

contains_eager Try lugar de joinedload. Lo que está sucediendo probablemente es que tiene 4 se une a los dos que ha definido con unirse y luego los dos de entre las opciones (joinedload (...))

La modificación de su código, debe dar a este:

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 (aunque tenga en cuenta que las expresiones compuestos necesitan ser entre paréntesis con el fin de funcionar con el comportamiento del pitón operador de precedencia): Hay también | for or_() y ~ for not_()

Así, utilizando su código & operador tendrá el siguiente aspecto:

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