Domanda

Sto usando SQLAlchemy 0.5rc e vorrei aggiungere un filtro automatico a una relazione, in modo tale che ogni volta che tenta di recuperare i record per quella relazione, ignora " remote " quelli se sono contrassegnati come " logically_deleted " (un campo booleano della tabella figlio)

Ad esempio, se un oggetto " parent " ha un " figli " relazione che ha 3 record, ma uno di questi viene logicamente eliminato quando eseguo una query per "Parent" Vorrei SQLA recupera l'oggetto genitore con solo due figli ..
Come dovrei farlo? Aggiungendo un " e " condizione al primario parametro della relazione? (ad es. " Children.parent_id == Parent.id e Children.logically_deleted == False " ;, ma è corretto scrivere " e " in questo modo?)

Modifica
Sono riuscito a farlo in questo modo

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

ma c'è un modo per usare una stringa comejojoin invece?

È stato utile?

Soluzione

La funzione and_ () è il modo corretto di fare congiunzioni logiche in SQLAlchemy, insieme a & amp; operatore, ma fai attenzione a quest'ultimo in quanto ha regole di precedenza sorprendenti, ovvero una precedenza più elevata rispetto agli operatori di confronto.

Potresti anche usare una stringa come join principale con il costruttore text (), ma ciò comporterà la rottura del codice con qualsiasi aliasing di tabella fornito con eagerloading e join.

Per l'eliminazione logica, potrebbe essere meglio mappare l'intera classe su una selezione che ignora i valori eliminati:

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

Altri suggerimenti

  

ma c'è un modo per usare una stringa comejojoin invece?

È possibile utilizzare quanto segue:

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

Questo ha funzionato per me!

Attualmente sto sviluppando di nuovo solo 0.4.qualcosa, ma ecco come lo consiglierei:

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

Penso che sia quello che stai cercando di fare, giusto?

(Nota: scritto in un browser web, non in codice reale!)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top