Python 如何关闭SQLAlchemy会话?
根据我们在中的评论,我正在检查SQLAlchemy创建到我的数据库中的连接,如果不退出Python,我无法关闭它们 如果我在python控制台中运行此代码,它将保持会话打开,直到我退出python:Python 如何关闭SQLAlchemy会话?,python,session,sqlalchemy,Python,Session,Sqlalchemy,根据我们在中的评论,我正在检查SQLAlchemy创建到我的数据库中的连接,如果不退出Python,我无法关闭它们 如果我在python控制台中运行此代码,它将保持会话打开,直到我退出python: from sqlalchemy.orm import sessionmaker from models import OneTable, get_engine engine = get_engine(database="mydb") session = sessionmaker(bind=engi
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()是否足够
- 关于“会话”一词,这里有一个中心混淆。这里我不确定,但看起来您可能会混淆了a,它指的是首次连接MySQL和断开连接时的范围
这两个概念并不相同。SQLAlchemy会话通常表示特定数据库连接上一个或多个事务的范围
因此,您的问题的答案是调用
session.close()
,即“如何正确关闭SQLAlchemy会话”
但是,问题的其余部分表明,您需要一些功能,即当特定的会话
关闭时,您还需要关闭实际的DBAPI连接
这基本上意味着您希望禁用。正如其他答案所提到的,非常简单。session.close()
会将连接返回到引擎的连接池,而不会关闭连接
engine.dispose()
将关闭连接池的所有连接
如果设置poolclass=NullPool
,引擎将不使用连接池。因此连接(SQLAlchemy会话)将在session.close()之后直接关闭。在中,我进行了一系列的单元测试。每个测试在运行之前都复制了一个sqlite数据库,如下所示:
copyfile(src=nw_source, dst=nw_loc)
def tearDown(file: str, started_at: str, engine: sqlalchemy.engine.base.Engine, session: sqlalchemy.orm.session.Session):
"""
close session & engine, banner
:param file: caller, usually __file__
:param started_at: eg, str(datetime.now())
:param engine: eg, nw.logic import session, engine
:param session: from nw.logic import session, engine
:return:
"""
session.close()
engine.dispose(). # NOTE: close required before dispose!
print("\n")
print("**********************")
print("** Test complete, SQLAlchemy session/engine closed for: " + file)
print("** Started: " + started_at + " Ended: " + str(datetime.now()))
print("**********************")
每个测试单独运行,但在discover
模式下失败。很明显,不知何故,数据库拷贝没有发生
看起来,也许unittest并不是连续运行的。事实上,单元测试是连续运行的。所以这不是问题所在(记录下来,也许是为了节省一些时间)
经过大量的颠簸之后,这似乎是因为数据库没有从先前的测试中完全关闭。不知怎的,这干扰了上面的副本。我不想知道为什么
多亏了上面的帖子,我解决了这个问题:
copyfile(src=nw_source, dst=nw_loc)
def tearDown(file: str, started_at: str, engine: sqlalchemy.engine.base.Engine, session: sqlalchemy.orm.session.Session):
"""
close session & engine, banner
:param file: caller, usually __file__
:param started_at: eg, str(datetime.now())
:param engine: eg, nw.logic import session, engine
:param session: from nw.logic import session, engine
:return:
"""
session.close()
engine.dispose(). # NOTE: close required before dispose!
print("\n")
print("**********************")
print("** Test complete, SQLAlchemy session/engine closed for: " + file)
print("** Started: " + started_at + " Ended: " + str(datetime.now()))
print("**********************")
使用sqlalchemy.pool.NullPool
并不能解决您的问题?我希望这两个链接可以帮助您,以及在执行select
查询后如何清除postgres关系上的AccessShareLock
,这完全解决了问题。通过你指出它,我注意到我混合了SQLAlchemy和MySQL会话。现在,使用get\u引擎(database=“mydb”,poolclass=NullPool)
我在我session.close()时将其关闭。谢谢!我想我有一个问题,因为会议没有正确关闭。我的api给了我随机数目的行。e、 我的表中有10行(mysql)。当我点击api时,我得到10、0、9等结果。另外,我用的是sqlalchemy(不是sqlalchemy)。请指导我。是否将.dispose
等待所有挂起的提交?@matanster no,如文档所示:“当引擎被释放或垃圾回收时,不会丢弃签出的连接”。因此,engine.dispose()