sessionmaker()
là một nhà máy, ở đó để khuyến khích đặt các tùy chọn cấu hình để tạo các đối tượng Session
mới chỉ ở một nơi. Nó là tùy chọn, trong đó bạn có thể dễ dàng gọi Session(bind=engine, expire_on_commit=False)
bất cứ khi nào bạn cần một Session
mới, ngoại trừ chi tiết và dư thừa của nó, và tôi muốn ngăn chặn sự gia tăng của "người trợ giúp" quy mô nhỏ mà mỗi người tiếp cận vấn đề dư thừa này một số cách mới mẻ và khó hiểu hơn.
Vì vậy, sessionmaker()
chỉ là một công cụ giúp bạn tạo các đối tượng Session
khi bạn cần chúng.
Phần tiếp theo. Tôi nghĩ rằng câu hỏi là, sự khác biệt giữa việc tạo ra một Session()
mới tại các điểm khác nhau so với chỉ sử dụng một trong tất cả các cách thức thông qua. Câu trả lời, không phải rất nhiều. Session
là một vùng chứa cho tất cả các đối tượng bạn đưa vào nó, và sau đó nó cũng theo dõi một giao dịch mở. Tại thời điểm bạn gọi rollback()
hoặc commit()
, giao dịch kết thúc và Session
không có kết nối với cơ sở dữ liệu cho đến khi nó được gọi để phát ra lại SQL. Các liên kết mà nó nắm giữ đối với các đối tượng được ánh xạ của bạn là tham chiếu yếu, miễn là các đối tượng được xóa sạch các thay đổi đang chờ xử lý, vì vậy ngay cả trong trường hợp đó, Session
sẽ tự dọn sạch trở lại trạng thái hoàn toàn mới khi ứng dụng của bạn mất tất cả các tham chiếu đến các đối tượng được ánh xạ. Nếu bạn để nó với thiết lập mặc định là "expire_on_commit"
, thì tất cả các đối tượng sẽ hết hạn sau một lần commit. Nếu điều đó Session
treo trong khoảng năm hoặc hai mươi phút và tất cả mọi thứ đã thay đổi trong cơ sở dữ liệu trong lần sử dụng tiếp theo, nó sẽ tải tất cả trạng thái hoàn toàn mới vào lần tiếp theo bạn truy cập các đối tượng đó ngay cả khi chúng đang ngồi bộ nhớ trong hai mươi phút.
Trong các ứng dụng web, chúng tôi thường nói, tại sao bạn không tạo một thương hiệu mới Session
trên mỗi yêu cầu, thay vì sử dụng cùng một lần lặp đi lặp lại. Thực hành này đảm bảo rằng yêu cầu mới bắt đầu "sạch". Nếu một số đối tượng từ yêu cầu trước đó chưa được thu thập rác và nếu có thể bạn đã tắt "expire_on_commit"
, có thể một số trạng thái từ yêu cầu trước đó vẫn bị treo xung quanh và trạng thái đó thậm chí có thể khá cũ. Nếu bạn cẩn thận để bật expire_on_commit
bật và chắc chắn gọi commit()
hoặc rollback()
khi kết thúc yêu cầu, thì tốt, nhưng nếu bạn bắt đầu với một thương hiệu mới Session
, thì thậm chí không có bất kỳ câu hỏi nào mà bạn bắt đầu sạch sẽ.Vì vậy, ý tưởng để bắt đầu mỗi yêu cầu với Session
mới thực sự là cách đơn giản nhất để đảm bảo bạn đang bắt đầu mới và sử dụng expire_on_commit
nhiều tùy chọn, vì cờ này có thể phải chịu rất nhiều SQL bổ sung cho một hoạt động gọi số commit()
ở giữa một loạt các hoạt động. Không chắc chắn nếu điều này trả lời câu hỏi của bạn.
Vòng tiếp theo là những gì bạn đề cập đến về luồng. Nếu ứng dụng của bạn đa luồng, chúng tôi khuyên bạn nên đảm bảo sử dụng Session
là cục bộ để ... một cái gì đó. scoped_session()
theo mặc định làm cho địa phương trở thành chuỗi hiện tại. Trong một ứng dụng web, địa phương để yêu cầu là trong thực tế, thậm chí tốt hơn. Flask-SQLAlchemy thực sự gửi một "phạm vi chức năng" tùy chỉnh đến scoped_session()
để bạn nhận được một phiên yêu cầu phạm vi. Ứng dụng Kim tự tháp trung bình sẽ gắn phiên vào trong sổ đăng ký "yêu cầu". Khi sử dụng các lược đồ như thế này, ý tưởng "tạo phiên mới khi bắt đầu yêu cầu" tiếp tục trông giống như cách đơn giản nhất để giữ mọi thứ thẳng thắn.
Ồ, điều này trả lời tất cả câu hỏi của tôi về phần SQLAlchemy và thậm chí thêm một số thông tin về Flask a nd Kim tự tháp! Tiền thưởng thêm: nhà phát triển trả lời;) Tôi ước tôi có thể bỏ phiếu nhiều lần. Cảm ơn nhiều! – javex
Một làm rõ, nếu có thể: bạn nói expire_on_commit "có thể phát sinh thêm nhiều SQL" ... bạn có thể cung cấp thêm chi tiết không? Tôi nghĩ expire_on_commit chỉ liên quan đến những gì xảy ra trong RAM, chứ không phải những gì xảy ra trong cơ sở dữ liệu. – Veky
expire_on_commit có thể dẫn đến SQL nhiều hơn nếu bạn sử dụng lại cùng một phiên, và một số đối tượng vẫn còn treo trong phiên đó, khi bạn truy cập chúng, bạn sẽ nhận được một hàng SELECT cho mỗi một đối tượng. làm mới trạng thái của họ về giao dịch mới. – zzzeek