tables postgres in_ create and python sqlalchemy

python - postgres - ¿Cómo agregar un filtro automático a una relación con SQLAlchemy?



sqlalchemy postgresql python (3)

Actualmente solo estoy desarrollando algo nuevo en 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 intentas hacer, ¿verdad?

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

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 obtener registros para esa relación, ignore los "remotos" si están marcados como "logically_deleted" "(un campo booleano de la tabla secundaria)

Por ejemplo, si un objeto "padre" tiene una relación "secundarios" que tiene 3 registros, pero uno de ellos se elimina lógicamente, cuando consulto "Padre" me gustaría que SQLA busque el objeto padre con solo dos hijos. .
¿Cómo debería hacerlo? ¿Al agregar una condición "y" al parámetro primaryjoin 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:
Me las arreglé para hacerlo de esta manera

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

pero, ¿hay alguna manera de usar una cadena como primaryjoin en su lugar?


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

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

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

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


pero, ¿hay alguna manera de usar una cadena como primaryjoin en su lugar?

Puedes usar lo siguiente:

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

¡Esto funcionó para mí!