SQLAlchemy - Aktualisieren Sie ForeignKey, wenn Sie die Beziehung festlegen

8

Ich habe eine Klasse:

%Vor%

Ich möchte eine Suche basierend auf element_id und element2_id durchführen:

%Vor%

Das Problem, das ich finde, ist, dass, wenn ich ein neues Objekt ExampleClass instanziiere und ihm ein element zuweise, das Feld element_id nicht gesetzt ist:

%Vor%

Wie kann ich das lösen? Was ist der beste Weg, um mit dieser Art von Situation umzugehen?

    
Santiago Alessandri 25.12.2012, 05:09
quelle

1 Antwort

10

Als erstes nehmen alle folgenden Beispiele an, dass Ihre ExampleClass -Instanz mindestens in der ausstehend Status, wenn nicht der Status" persistent "(also session.add(a) ). Mit anderen Worten, wenn Sie noch nicht mit einem Session interagieren und das ExampleClass -Objekt nicht zu einem hinzugefügt haben, dann erhalten Sie kein Verhalten auf der Datenbankebene von relationship() , von dem Fremd verwaltet wird Schlüsselspaltenwerte ist das Hauptmerkmal. Sie können diese Aufgabe selbstverständlich direkt ausführen:

%Vor%

Aber das nutzt offensichtlich nicht die Automatisierung, die vom relationship() -Konstrukt bereitgestellt wird.

Die Zuweisung von Fremdschlüsselattributen nach relationship() erfolgt während eines Flush . Dies ist ein Prozess, der nur dann auftritt, wenn eine Interaktion mit der Datenbank erforderlich ist, z. B. bevor Sie eine SQL-Anweisung mit session.query() ausgeben oder bevor Sie Ihre Transaktion mit session.commit() abschließen.

Im Allgemeinen besteht die Philosophie von relationship() darin, dass Sie hier nur die Attribute "element" und "element2" behandeln und die Fremdschlüsselattribute hinter den Kulissen behandeln. Sie können Ihre Anfrage so schreiben:

%Vor%

Das ORM nimmt einen Vergleich wie SomeClass.somerelationship=someobject und konvertiert dieses in den Fremdschlüsselausdruck SomeClass.some_fk=some_id , aber der Unterschied besteht darin, dass die Bewertung des endgültigen Werts von "some_id" zurückgestellt bis rechts bevor die Abfrage ausgeführt wird. Bevor die Abfrage ausgeführt wird, teilt das Objekt Query() dem Session den Wert "autoflush" zu. Dies hat den Effekt, dass die Zeile ExampleClass zusammen mit der Primärschlüssel-ID element_obj dem% co_de zugewiesen wird Attribut% für das Objekt element_id .

Sie könnten einen ähnlichen Effekt erzielen, während Sie die FK-Attribute weiterhin verwenden. Dies ist meistens nur um zu verstehen, wie es funktioniert:

%Vor%

oder noch expliziter, mache zuerst den Flush:

%Vor%

Wenn Sie also explizit auf Fremdschlüsselattribute wie ExampleClass verweisen möchten, müssen Sie auch die Dinge tun, die element_id explizit für Sie tut. Wenn Sie streng mit Objektinstanzen und dem Attribut relationship() -bound umgehen und typische Standardwerte wie relationship() aktiviert lassen, wird im Allgemeinen das "Richtige" getan und sichergestellt, dass Attribute bei Bedarf bereit sind.

    
zzzeek 25.12.2012, 15:52
quelle

Tags und Links