2014-02-12 4 views
30

После того, что мы прокомментировали в How to close sqlalchemy connection in MySQL, я проверяю соединения, которые SQLAlchemy создает в моей базе данных, и я не могу закрыть их, не выходя из Python.Как закрыть сеанс SQLAlchemy?

Если я запускаю этот код в консоли питона, она сохраняет сеанс не открыт, пока я не выход из питона:

from sqlalchemy.orm import sessionmaker 
from models import OneTable, get_engine 

engine = get_engine(database="mydb") 
session = sessionmaker(bind=engine)() 

results = session.query(OneTable.company_name).all() 

# some work with the data # 

session.close() 

и единственный обходной путь я нашел, чтобы закрыть это назвать engine.dispose() в конце.

Согласно комментариям в ссылке, которую я дал выше, мой вопрос теперь:

  • Почему engine.dispose() необходимо закрыть сессии?
  • Не хватает session.close()?
+1

Работа с 'sqlalchemy.pool.NullPool' не решит вашу проблему? –

+0

Mmmm @xndrme, как его использовать? – fedorqui

+0

Я надеюсь, что эти две ссылки помогут вам http://docs.sqlalchemy.org/en/rel_0_8/glossary.html?highlight=release и http://docs.sqlalchemy.org/en/rel_0_8/core/pooling.html? highlight = pooling # change-pool-реализация –

ответ

42

Существует центральное замешательство здесь по слову «сессия». Я не уверен здесь, но кажется, что вы можете ввести в заблуждение SQLAlchemy Session с MySQL @@session, который относится к области, когда вы впервые подключились к MySQL и когда вы отключились.

Эти две концепции: не то же самое. Сессия SQLAlchemy обычно представляет область действия одной или нескольких транзакций при подключении конкретной базы данных.

Таким образом, ответ на ваш вопрос в буквальном смысле слова - это вызов session.close(), то есть «как правильно закрыть сеанс SQLAlchemy».

Однако остальная часть вашего вопроса указывает на то, что вам нужна какая-то функциональность, когда закрывается конкретный Session, вы хотите, чтобы и фактическое соединение DBAPI было закрыто.

Это означает, что вы хотите отключить connection pooling. Который, как упоминают другие ответы, достаточно прост, use NullPool.

+2

Это полностью сделало это. Вы указали, что я заметил, что я смешивал сеансы SQLAlchemy и MySQL. Теперь с 'get_engine (database =" mydb ", poolclass = NullPool)' Я закрываю его после того, как я 'session.close()'. Большое спасибо! – fedorqui

+0

Я предполагаю, что у меня проблема, потому что сессии не закрыты должным образом. Мой api дает мне случайное количество строк. например У меня 10 строк в моей таблице (mysql). И когда я ударил свой api, я получаю результаты 10, 0, 9 и т. Д. Постскриптум Я использую sqlalchemy (не коллоидная sqlalchemy). Пожалуйста, направляйте меня. – Hussain

24

session.close() вернет соединение в пул соединений двигателя и не закроет соединение.

engine.dispose() будет закрывать все соединения пула соединений.

Двигатель не будет использовать пул соединений, если вы установили poolclass=NullPool. Таким образом, соединение (сеанс SQLAlchemy) будет закрываться непосредственно после session.close().

Смежные вопросы