Pregunta

Estoy usando SQLAlchemy 0.5rc, y me gustaría agregar un filtro automático a una relación, de modo que cada vez que intente buscar registros para esa relación, ignore el "remoto". unos si están marcados como " logically_deleted " (un campo booleano de la tabla secundaria)

Por ejemplo, si un objeto '' padre '' tiene un " niños " relación que tiene 3 registros, pero uno de ellos se elimina lógicamente, cuando busco " Parent " Me gustaría que SQLA buscar el objeto padre con solo dos hijos ..
¿Cómo debería hacerlo? Al agregar un " y " condición para la unión primaria parámetro de la relación? (por ejemplo, " Children.parent_id == Parent.id and Children.logically_deleted == False " ;, pero ¿es correcto escribir " y " de esta manera?)

Editar:
Logré hacerlo de esta manera

children = relation("Children", primaryjoin=and_(id == Children.parent_id, Children.logically_deleted==False))

pero, ¿hay alguna forma de usar una cadena como uniones primarias?

¿Fue útil?

Solución

La función and_ () es la forma correcta de hacer conjunciones lógicas en SQLAlchemy, junto con & amp; operador, pero tenga cuidado con este último ya que tiene reglas de precedencia sorprendentes, es decir, mayor precedencia que los operadores de comparación.

También podría usar una cadena como una unión primaria con el constructor text (), pero eso hará que su código se rompa con cualquier alias de tabla que venga con eagerloading y combinaciones.

Para la eliminación lógica, podría ser mejor asignar toda la clase sobre una selección que ignora los valores eliminados:

mapper(Something, select([sometable], sometable.c.deleted == False))

Otros consejos

  

pero, ¿hay alguna forma de usar una cadena como uniones primarias?

Puede usar lo siguiente:

children = relationship("Children", primaryjoin="and_(Parent.id==Children.parent_id, Children.logically_deleted==False)"

¡Esto funcionó para mí!

Actualmente solo estoy desarrollando contra 0.4.algo, pero así es como lo sugeriría:

db.query(Object).filter(Object.first==value).filter(Object.second==False).all()

Creo que eso es lo que estás tratando de hacer, ¿verdad?

(Nota: ¡escrito en un navegador web, no en código real!)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top