Als Erstes gehen alle folgenden Beispiele davon aus, dass Ihre ExampleClass
-Instanz mindestens im pending-Zustand ist, wenn nicht im Status "persistent" (dh session.add(a)
). Mit anderen Worten: Wenn Sie noch nicht mit einem Session
interagieren und das Objekt ExampleClass
nicht zu einem Objekt hinzugefügt haben, erhalten Sie kein Verhalten auf Datenbankebene von relationship()
, von dem das Beibehalten von Fremdschlüsselspaltenwerten das primäre ist Feature. Sie sind natürlich frei, diese Zuordnung zu machen direkt:
a = ExampleClass(element_id=element_obj.id)
aber das ist offensichtlich nicht die Nutzung der Automatisierung durch das relationship()
Konstrukt zur Verfügung gestellt.
Die Zuordnung der Fremdschlüsselattribute von relationship()
während eines flush auftritt, was ein Prozess, der nur dann auftritt, wenn die Interaktion mit der Datenbank erforderlich ist, wie zum Beispiel, bevor Sie eine SQL-Anweisung session.query()
emittieren oder bevor Sie die Transaktion abschließen session.commit()
mit .
Im Allgemeinen lautet die Philosophie von relationship()
, dass Sie hier nur die Attribute "element" und "element2" behandeln und die Fremdschlüsselattribute hinter den Kulissen behandeln. Sie können Ihre Abfrage wie folgt schreiben:
session.query(ExampleClass).\
filter_by(element=self.element).\
filter_by(element2=element2)
Die ORM wie SomeClass.somerelationship=someobject
einen Vergleich nehmen und wandeln die in den Fremdschlüssel Ausdruck SomeClass.some_fk=some_id
, aber der Unterschied ist, die Auswertung der endgültige Wert von „some_id“ ist aufgeschoben bis rechts bevor die Abfrage ausgeführt wird. Bevor die Abfrage ausgeführt wird, teilt das Query()
-Objekt die Session
an "autoflush", was die Auswirkung hat, dass Ihre ExampleClass
Zeile zusammen mit der Primärschlüssel-ID element_obj
dem Attribut element_id
auf dem Objekt ExampleClass
zugewiesen wird.
Sie könnte einen ähnlichen Effekt erhalten, während immer noch die FK-Attribute wie diese verwenden, dies meist nur zu verstehen, wie es funktioniert aber:
session.query(ExampleClass).\
filter_by(element_id=bindparam(callable_=lambda: self.element_id)).\
filter_by(element2_id=element2.id)
oder noch deutlicher, tun die bündig zuerst:
session.flush()
session.query(ExampleClass).\
filter_by(element_id=self.element_id).\
filter_by(element2_id=element2.id)
Also in dem Maße, in dem Sie explizit auf Fremdschlüssel-Attribute wie element_id
verweisen möchten, müssten Sie auch die Dinge tun, die relationship()
explizit für Sie tut.Wenn Sie sich ausschließlich mit Objektinstanzen und dem Attribut relationship()
-bound befassen und typische Standardwerte wie autoflush
aktiviert lassen, wird im Allgemeinen das "Richtige" ausgeführt und sichergestellt, dass die Attribute bei Bedarf bereit sind.
Vielen Dank für die Erklärung. Ich wusste nicht, ob ich nach der Beziehung selbst filtern konnte und ich wollte die Dinge nicht durcheinander bringen. Also werde ich das definitiv tun. –