Po pierwsze, wszystkie poniższe przykłady zakładają, że instancja ExampleClass
jest przynajmniej w stanie pending, jeśli nie jest stanem "trwałym" (to jest session.add(a)
). Innymi słowy, jeśli jeszcze nie wchodzisz w interakcję z obiektem Session
i nie dodano obiektu ExampleClass
do jednego, nie uzyskasz żadnego z poziomów bazy danych o wartości relationship()
, z których zachowanie wartości kolumny klucza obcego jest podstawowym cecha. Jesteś oczywiście wolny, aby to zadanie bezpośrednio:
a = ExampleClass(element_id=element_obj.id)
ale to oczywiście nie korzystające z automatyzacji dostarczonych przez relationship()
konstruktu.
Przypisanie obcych kluczowych atrybutów przez relationship()
występuje podczas flush, która jest procesem, który występuje tylko wtedy, gdy interakcja z bazą danych jest konieczne, tak jak przed emitują instrukcji SQL session.query()
lub przed sfinalizować transakcję przy użyciu session.commit()
.
Ogólnie filozofią relationship()
jest to, że zajmujesz się tu tylko atrybutami "element" i "element2", a atrybuty klucza obcego będą obsługiwane za kulisami. Można napisać zapytanie tak:
session.query(ExampleClass).\
filter_by(element=self.element).\
filter_by(element2=element2)
ORM odbędzie porównanie takiego jak SomeClass.somerelationship=someobject
i przekonwertować do klucza obcego wyrazu SomeClass.some_fk=some_id
, ale różnica polega na tym, ocenę ostateczną wartość „some_id” jest odroczony, aż do momentu, w którym zapytanie zostanie wykonane. Przed wykonaniem kwerendy obiekt Query()
mówi do "automatycznej przepuszczalności", która będzie skutkowała wstawieniem wiersza ExampleClass
wraz z głównym identyfikatorem klucza element_obj
przypisanym do atrybutu element_id
na obiekcie ExampleClass
.
można uzyskać podobny efekt, a jednocześnie przy użyciu FK atrybuty tak, to najczęściej tylko zrozumieć, jak to działa, choć:
session.query(ExampleClass).\
filter_by(element_id=bindparam(callable_=lambda: self.element_id)).\
filter_by(element2_id=element2.id)
lub nawet bardziej wyraźne, wykonaj równo pierwszy:
session.flush()
session.query(ExampleClass).\
filter_by(element_id=self.element_id).\
filter_by(element2_id=element2.id)
Jeśli chcesz wyraźnie opisać atrybuty klucza obcego, takie jak element_id
, musisz również zrobić to, co wyraźnie zrobisz, relationship()
.Jeśli zajmujesz się wyłącznie instancjami obiektów i atrybutem danych relationship()
i pozostawisz typowe ustawienia domyślne, takie jak autoflush
, to zwykle robisz "właściwą rzecz" i upewniasz się, że atrybuty są gotowe w razie potrzeby.
Wielkie dzięki za wyjaśnienie. Nie wiedziałem, czy mogę filtrować przez samą relację i nie chciałem tego zepsuć. Więc na pewno właśnie tak zamierzam to zrobić. –