gpt4 book ai didi

python - 未关闭的连接 SQLAlchemy

转载 作者:行者123 更新时间:2023-11-30 22:44:28 27 4
gpt4 key购买 nike

我最近在我使用 SQLAlchemy 运行的守护进程的应用程序日志中看到 MySQL 服务器已经消失

我将每个数据库查询或更新包装在装饰器中,装饰器应在完成后关闭所有 session 。理论上,这也应该关闭连接

我的装饰器看起来像

  def dbop(meth):
@wraps(meth)
def nf(self, *args, **kwargs):
self.session = self.sm()
res = meth(self, *args, **kwargs)
self.session.commit()
self.session.close()
return res
return nf

我还在 Python 脚本的顶部初始化了数据库:

  def initdb(self):
engine = create_engine(db_url)
Base.metadata.create_all(engine)
self.sm = sessionmaker(bind=engine,
autocommit=False,
autoflush=False,
expire_on_commit=False)

据我了解,我收到该错误是因为我的连接超时。如果我将每个方法包装在上面的装饰器中,为什么会出现这种情况?这是因为即使在连接关闭后 expire_on_commit 也会导致查询并可能重新打开它们吗?这是因为 Base.metadata.create_all 导致执行 SQL,从而打开一个未关闭的连接吗?

最佳答案

您的 session 绑定(bind)到“引擎”,而“引擎”又使用连接池。每次 SQLAlchemy 需要一个连接时,它都会从池中 check out 一个连接,如果完成,它会返回到池中,但它不会关闭!这是减少打开/关闭连接开销的常用策略。您在上面设置的所有选项只会影响 session ,不会影响连接!

默认情况下,池中的连接将无限期保持打开状态。

但 MySQL 会在一定数量的不活动后自动关闭连接(参见 wait_timeout)。

这里的问题是,如果您的 Python 进程处于不活动超时状态,MySQL 服务器将不会通知您连接已关闭。相反,下一次向该连接发送查询时,Python 将发现该连接不再可用。如果由于其他原因导致连接丢失,也会发生类似的事情,例如强制服务重启,不等待打开的连接完全关闭(例如,在 postgres 重启中使用“立即”选项)。

这是您遇到异常的时候。

SQLAlchemy 为您提供了各种处理此问题的策略,这些策略在@lukas-graf 提到的“Dealing with Disconnects”部分中有详细记录

如果您跳过一些障碍,您可以获得对 session 当前正在使用的连接的引用。您可以那样关闭它,但我强烈建议反对这样做。相反,请引用上面的“处理断开连接” session ,让 SQLAlchemy 透明地为您处理这个问题。在您的情况下,设置 pool_recycle option可能会解决您的问题。

关于python - 未关闭的连接 SQLAlchemy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30036597/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com