sessionmaker()
це фабрика, там можна заохочувати розміщення параметрів конфігурації для створення нових Session
об’єктів лише в одному місці. Це необов'язково, оскільки ви могли так само легко зателефонувати в Session(bind=engine, expire_on_commit=False)
будь-який час, коли вам знадобилося новеSession
, за винятком того, що його багатослівний і зайвий, і я хотів зупинити розповсюдження дрібних "помічників", які кожен підходив до проблеми цієї надмірності в деяких нових і більш заплутаний спосіб.
Отже, sessionmaker()
це лише інструмент, який допоможе вам створити Session
об’єкти, коли вони вам потрібні.
Наступна частина. Я думаю, що питання полягає в тому, яка різниця між створенням нового Session()
в різних точках, а не просто використанням одного до кінця. Відповідь, не дуже. Session
є контейнером для всіх об'єктів, які ви вкладаєте в нього, а потім він також відстежує відкриту транзакцію. У той момент, коли ви дзвоните rollback()
або commit()
, транзакція закінчена, і Session
не має зв'язку з базою даних, поки не буде покликано знову випромінювати SQL. Посилання, які він тримає до ваших відображених об’єктів, є слабкими посиланнями, за умови, що об'єкти чисті від очікуючих змін, тому навіть у зв'язку з цим налаштуванням всі об'єкти закінчуються після фіксації. Якщо цеSession
воля випорожниться назад до абсолютно нового стану, коли ваша програма втратить усі посилання на відображені об’єкти. Якщо залишити його за замовчуванням"expire_on_commit"
Session
зависає протягом п’яти-двадцяти хвилин, і всі види речей змінилися в базі даних наступного разу, коли ви будете використовувати її, вона завантажить абсолютно новий стан наступного разу, коли ви отримаєте доступ до цих об'єктів, навіть якщо вони сидять у пам'яті двадцять хвилин.
У веб-додатках ми, як правило, кажемо, ей, чому б вам не зробити новенький Session
на кожен запит, а не використовувати один і той же раз і знову. Ця практика гарантує, що новий запит починається "чисто". Якщо деякі об'єкти з попереднього запиту ще не були зібрані сміттям, і якщо, можливо, ви його вимкнули "expire_on_commit"
, можливо, якийсь стан із попереднього запиту все ще зависає, і цей стан може бути навіть досить старим. Якщо ви обережно залишаєте expire_on_commit
увімкненим і обов'язково зателефонували commit()
або rollback()
на запит закінчились, тоді це добре, але якщо ви почнете з абсолютно нового Session
, тоді навіть не виникає жодних питань, з якими ви починаєте чисто. Тож ідея починати кожен запит з новогоSession
насправді просто найпростіший спосіб переконатися, що ви починаєте свіжим, і використовувати його в середині серії операцій. Не впевнений, чи відповідає це на ваше запитання.expire_on_commit
майже необов'язковим, оскільки цей прапор може спричинити багато додаткового SQL для операції, яка викликаєcommit()
Наступний раунд - це те, що ви згадуєте про нарізування різьби. Якщо ваш додаток багатопотокове, радимо переконатися, що Session
використання використовується локальним для чогось. scoped_session()
за замовчуванням робить його локальним для поточного потоку. У веб-додатку локальний запит насправді ще кращий. Flask-SQLAlchemy насправді надсилає користувацьку "функцію діапазону", щоб scoped_session()
ви отримали сеанс, що охоплює запит. Середня програма Pyramid вписує Сесію в реєстр "запитів". Використовуючи подібні схеми, ідея "створити нову сесію під час запиту" продовжує виглядати як найпростіший спосіб зробити все прямо.