Frage

Ich verwende SQLAlchemy 0.5rc, und ich möchte einen automatischen Filter auf eine Beziehung hinzuzufügen, so dass jedes Mal, er versucht, für diese Beziehung Aufzeichnungen zu holen, es ignoriert die „remote“ aus, wenn sie markiert sind als "logically_deleted" (ein boolean Feld der untergeordneten Tabelle)

Zum Beispiel, wenn ein Objekt „Eltern“ hat eine „Kinder“ Beziehung, die hat 3 Datensätze, aber einer von ihnen ist logisch gelöscht, wenn ich für „Parent“ abfragen, ich möchte SQLA zu holt das übergeordnete Objekt mit nur zwei Kindern ..
Wie soll ich es tun? Durch das Hinzufügen eines „und“ Zustand der primaryjoin Parameter der Beziehung? (Zum Beispiel „Children.parent_id == Parent.id and Children.logically_deleted == False“, aber ist es richtig zu schreiben „und“ auf diese Weise?)

Bearbeiten
Ich schaffte es auf diese Weise tun

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

aber ist es eine Möglichkeit, eine Zeichenfolge als primaryjoin stattdessen zu verwenden?

War es hilfreich?

Lösung

Die and_ () Funktion ist der richtige Weg logische Konjunktionen in SQLAlchemy zu tun, zusammen mit dem Operator &, aber mit diesem vorsichtig sein, da es überraschend, Vorrangregeln hat, das heißt höhere Priorität als Vergleichsoperator.

Sie auch eine Zeichenfolge als eine primäre verbinden mit dem Text () Konstruktor verwenden könnte, aber das wird Ihren Code Bruch mit jedem Tisch Aliasing, die mit eagerloading und verbindet kommt machen.

Für logisches Löschen, könnte es besser sein, die ganze Klasse über eine ausgewählte abzubilden, die Werte gelöscht ignoriert:

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

Andere Tipps

  

aber ist es eine Möglichkeit, eine Zeichenfolge als primaryjoin stattdessen zu verwenden?

Sie können das folgende:

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

Das funktioniert für mich!

Ich bin nur zur Zeit der Entwicklung agains 0.4.something, aber hier ist, wie ich es vorschlagen würde:

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

Ich denke, das ist, was Sie zu tun versuchen, nicht wahr?

(Hinweis: in einem Web-Browser geschrieben, nicht echter Code)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top