У меня есть SQLAlchemy CORE 1.0.9 с каркасом пирамиды 1.7. И я использую следующую конфигурацию для подключения к Postgres 9,4 базы данных:SQLAlchemy core + Pyramid не закрывающие соединения
# file __ini__.py
from .factories import root_factory
from pyramid.config import Configurator
from sqlalchemy import engine_from_config
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application."""
config = Configurator(settings=settings, root_factory=root_factory)
engine = engine_from_config(settings, prefix='sqlalchemy.')
# Retrieves database connection
def get_db(request):
connection = engine.connect()
def disconnect(request):
connection.close()
request.add_finished_callback(disconnect)
return connection
config.add_request_method(get_db, 'db', reify=True)
config.scan()
return config.make_wsgi_app()
Через несколько часов с помощью приложения я начинаю получать следующее сообщение об ошибке:
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) FATAL: remaining connection slots are reserved for non-replication superuser connections
Видимо я достиг максимальное количество подключений. Кажется, что connections.close() действительно не закрывает соединение, просто возвращает соединение с пулом. Я знаю, что могу использовать NullPool, чтобы отключить объединение, но, вероятно, это будет иметь огромное влияние на производительность.
Кто-нибудь знает, как правильно настроить SQLAlchemy Core, чтобы получить хорошую производительность и правильно закрыть соединения?
Пожалуйста, воздержитесь от отправки ссылок на pyramid tutorials. Я НЕ интересуется установками ORM SQLAlchemy. Только SQLAlchemy Core пожалуйста.
Я думаю, вы должны использовать Zope Transaction Manager (pyramid_tm). Это оболочка вашего приложения Pyramid, которая интегрируется с обработкой запроса. Он автоматически совершает транзакцию, если запрос завершается без инцидентов; альтернативно, если возникает исключение, оно прекратит транзакцию. [Подробнее] (http://pyramid-sqlalchemy.readthedocs.io/en/latest/transactions.html) – webjunkie
FWIW Я не вижу ничего плохого в вашем примере кода. ORM имеет 'Session.remove', чтобы убедиться, что вещи действительно удалены, но с использованием ядра SQLA' .close' должен работать. –