Pergunta

Eu estou usando SQLAlchemy 0.5rc, e eu gostaria de adicionar um filtro automático para uma relação, de modo que cada vez que ele tenta buscar registros para essa relação, ele ignora os "remotos" queridos se eles estão sinalizadas como "logically_deleted" (um campo booleano da tabela filho)

Por exemplo, se um "pai" objeto tem um "crianças" relação que tem 3 registros, mas um deles é logicamente apagado, quando eu consultar "Pai" Eu gostaria SQLA para buscar o objeto pai com apenas duas crianças ..
Como devo fazer isso? Ao adicionar um "e" condição ao primaryjoin parâmetro da relação? (Por exemplo, "Children.parent_id == Parent.id and Children.logically_deleted == False", mas é correta de escrever "e" desta maneira?)

Editar:
Consegui fazê-lo desta maneira

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

mas existe uma maneira de usar uma corda como primaryjoin vez?

Foi útil?

Solução

A função and_ () é a maneira correta de fazer conjunções lógicas em SQLAlchemy, juntamente com o operador &, mas tenha cuidado com o último, pois tem regras de precedência surpreendentes, ou seja, maior precedência do que os operadores de comparação.

Você também pode usar uma string como uma primária juntar-se com o construtor de texto (), mas que vai fazer a sua pausa de código com qualquer aliasing tabela que vem com eagerloading e junta-se.

Para exclusão lógica, talvez seja melhor para mapear toda a classe sobre uma escolha que ignora excluídos valores:

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

Outras dicas

mas existe uma maneira de usar uma corda como primaryjoin vez?

Você pode usar o seguinte:

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

Isso funcionou para mim!

Eu só estou actualmente a desenvolver agains 0.4.something, mas aqui está como eu sugiro que:

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

Eu acho que isso é o que você está tentando fazer, certo?

(Nota: escrito em um navegador da web, não o código real)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top