Trước hết, tất cả các ví dụ dưới đây giả định rằng trường hợp ExampleClass
của bạn ít nhất ở trạng thái pending nếu không phải trạng thái "liên tục" (nghĩa là, session.add(a)
). Nói cách khác, nếu bạn chưa tương tác với một Session
và chưa thêm đối tượng ExampleClass
vào một đối tượng, thì bạn sẽ không nhận được bất kỳ hành vi cấp cơ sở dữ liệu nào của relationship()
, trong đó duy trì các giá trị cột khóa ngoài là chính đặc tính. Bạn hoàn toàn có thể thực hiện nhiệm vụ này trực tiếp:
a = ExampleClass(element_id=element_obj.id)
nhưng điều này rõ ràng là không sử dụng tự động được cung cấp bởi cấu trúc relationship()
.
Việc chuyển nhượng thuộc tính quan trọng nước ngoài bởi relationship()
xảy ra trong một flush, mà là một quá trình mà chỉ xảy ra khi tương tác với cơ sở dữ liệu là cần thiết, chẳng hạn như trước khi bạn phát ra một câu lệnh SQL sử dụng session.query()
hoặc trước khi bạn hoàn tất giao dịch của bạn sử dụng session.commit()
.
Nói chung, triết lý của relationship()
là bạn chỉ xử lý thuộc tính "phần tử" và "phần tử2" ở đây và để các thuộc tính khóa ngoài được xử lý sau hậu trường. Bạn có thể viết truy vấn của bạn như thế này:
session.query(ExampleClass).\
filter_by(element=self.element).\
filter_by(element2=element2)
Các ORM sẽ mất một so sánh như SomeClass.somerelationship=someobject
và chuyển đổi đó vào biểu foreign-key SomeClass.some_fk=some_id
, nhưng sự khác biệt là, việc đánh giá giá trị cuối cùng của "some_id" được hoãn lại cho đến khi quyền truy vấn được thực thi ngay trước khi thực hiện. Trước khi truy vấn được thực thi, đối tượng Query()
cho biết số Session
để "tự động điền", sẽ có hiệu lực của hàng ExampleClass
được chèn cùng với mã nhận dạng khóa chính của element_obj
được gán cho thuộc tính element_id
trên đối tượng ExampleClass
.
bạn có thể có được một hiệu ứng tương tự trong khi vẫn sử dụng FK thuộc tính như thế này, đây là chủ yếu chỉ để hiểu làm thế nào nó hoạt động mặc dù:
session.query(ExampleClass).\
filter_by(element_id=bindparam(callable_=lambda: self.element_id)).\
filter_by(element2_id=element2.id)
hoặc thậm chí rõ ràng hơn, làm tuôn ra đầu tiên:
session.flush()
session.query(ExampleClass).\
filter_by(element_id=self.element_id).\
filter_by(element2_id=element2.id)
Vì vậy, ở mức độ bạn muốn tham chiếu đến các thuộc tính khóa ngoài như element_id
một cách rõ ràng, bạn cũng cần phải làm những điều relationship()
cũng cho bạn một cách rõ ràng.Nếu bạn xử lý nghiêm ngặt với các cá thể đối tượng và thuộc tính ràng buộc relationship()
và để mặc định thông thường như được kích hoạt autoflush
, thông thường nó sẽ làm "điều đúng" và đảm bảo các thuộc tính sẵn sàng khi cần.
Cảm ơn rất nhiều vì đã giải thích. Tôi không biết liệu tôi có thể lọc chính mối quan hệ đó và tôi không muốn làm mọi thứ rối tung lên. Vì vậy, chắc chắn đó là cách tôi sẽ làm điều đó. –