- Что именно менеджер контекста делает с соединениями и сессиями?
Закрытие сеанса и удаление соединения или что?
Менеджер контекста в Python используется для создания контекста времени выполнения для использования с оператором with. Просто, когда вы запускаете код:
with session_scope() as session:
entity = session.query(SomeEntity).first()
сессия - полученная сессия. Итак, на ваш вопрос, что делает менеджер контекста с соединениями и сессиями. Все, что вам нужно сделать, это посмотреть, что происходит после выхода, чтобы увидеть, что происходит. В этом случае это просто посмотреть:
try:
yield session
session.commit()
except:
session.rollback()
raise
Если вы не вызовете никаких исключений, это будет session.commit (), который в соответствии с документацией SQLAlchemy будет «сбрасывать ожидающие изменения и фиксировать текущую транзакцию».
- Почему первый рабочий пример кода ведет себя как пример с проблемой
без NullPool в качестве пулакласса в методе «connect»?
Аргумент poolclass просто говорит SQLAlchemy, почему использовать подкласс Pool
. Однако в случае, когда вы передаете здесь NullPool
, вы говорите SQLAlchemy не использовать пул, вы фактически отключаете пул соединений, когда вы передаете NullPool
. Из документов: «чтобы отключить пул, установите вместо« poolclass »значение NullPool.» Я не могу сказать наверняка, но использование NullPool
, вероятно, способствует вашим max_connection
проблемам.
- Почему в первом примере я получил только 1 соединение с БД для всех запросов
но во втором примере я получил отдельное соединение для каждого запроса?
(поправьте меня, если я неправильно понял, проверял
"Pgbouncer")
Я не совсем уверен. Я думаю, что это связано с тем, как в первом примере вы используете менеджер контекста, поэтому все в блоке with
будет использовать генератор session
. Во втором примере вы создали функцию, которая инициализирует новый Session
и возвращает его, поэтому вы не получите генератор. Я также думаю, что это связано с вашим NullPool
использованием, которое предотвращает пул соединений. С NullPool
каждое выполнение запроса получает соединение самостоятельно.
- Каковы лучшие практики для открытия и закрытия соединений (и / или работы
с сеансом), когда вы используете SQLAlchemy и PostgreSQL DB для нескольких
экземпляры скрипта (или отдельных потоков в скрипте), который слушает
запросы и должен иметь отдельный сеанс для каждого из них? (Я имею в виду сырой
SQLAlchemy не Flask-SQLAlchemy или что-то вроде этого)
См. Раздел Безопасен ли сеанс для потока? для этого, но вам нужно использовать подход "ничего не передавать" к вашему параллелизму. Так что в вашем случае вам нужен каждый экземпляр скрипта, чтобы ничего не делить между собой.
Возможно, вы захотите проверить Работа с двигателями и соединениями , я не думаю, что возиться с сессиями - это то, где вы хотите быть, если вы работаете над параллелизмом. Там есть больше информации о NullPool и параллелизме:
Для многопроцессорного приложения, использующего системный вызов os.fork,
или, например, многопроцессорный модуль Python, он обычно
требуется, чтобы отдельный Engine использовался для каждого дочернего процесса. это
потому что Engine поддерживает ссылку на пул соединений, который
в конечном итоге ссылается на соединения DBAPI - они, как правило, не
портативный через границы процесса. Двигатель, который не настроен
использовать пул (что достигается с помощью NullPool) не
есть это требование.