如何关闭SQLAlchemy会话?

fed*_*qui 54 python session sqlalchemy

按照我们在如何关闭MySQL中的sqlalchemy连接中所评论的内容,我正在检查SQLAlchemy在我的数据库中创建的连接,并且我无法在不退出Python的情况下关闭它们.

如果我在python控制台中运行此代码,它将保持会话打开,直到我退出python:

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()
Run Code Online (Sandbox Code Playgroud)

我发现关闭它的唯一解决方法是engine.dispose()在最后调用.

根据我上面给出的链接中的评论,我现在的问题是:

  • 为什么有engine.dispose()必要结束会议?
  • session.close()不够吗?

zzz*_*eek 74

这里有一个关于"会话"这个词的中心混淆.我不确定这里,但看起来你可能会将SQLAlchemy SessionMySQL @@会话混淆,后者指的是你第一次连接MySQL和断开连接时的范围.

这两个概念不一样.SQLAlchemy会话通常表示特定数据库连接上的一个或多个事务的范围.

因此,按字面意思询问您的问题的答案是调用session.close(),即"如何正确关闭SQLAlchemy会话".

但是,你的问题的其余部分表明你想要一些功能,当特定Session关闭时,你也希望关闭实际的DBAPI连接.

这基本上意味着您希望禁用连接池.正如其他答案所提到的那样,使用NullPool很容易.

  • 这完全成功了.你指着它我注意到我正在混合SQLAlchemy和MySQL会话.现在使用`get_engine(database ="mydb",poolclass = NullPool)`一旦我`session.close()`我就把它关闭了.非常感谢! (5认同)

小智 55

session.close() 将连接返回到Engine的连接池,并且不关闭连接.

engine.dispose() 将关闭连接池的所有连接.

如果设置,引擎将不使用连接池poolclass=NullPool.所以连接(SQLAlchemy会话)将在之后直接关闭session.close().

  • `.dispose` 会等待所有待处理的提交吗? (4认同)
  • @matanster 不,根据文档:“当引擎被处置或垃圾收集时,签出的连接不会被丢弃”。因此,任何未关闭的会话都将被“engine.dispose()”有效忽略 (4认同)