【问题标题】:How to close sqlalchemy connection in MySQL如何在 MySQL 中关闭 sqlalchemy 连接
【发布时间】:2021-09-03 22:25:43
【问题描述】:

这是我要运行的示例代码:

for i in range(1,2000):
    db = create_engine('mysql://root@localhost/test_database')
    conn = db.connect()
    #some simple data operations
    conn.close()
    db.dispose()

有没有办法在不从 MySQL 收到“Too many connections”错误的情况下运行它? 我已经知道我可以以其他方式处理连接或拥有连接池。我只想了解如何正确关闭来自 sqlalchemy 的连接。 提前致谢!

【问题讨论】:

  • IMO:您介绍了两种选择:池化或循环外。
  • 看起来已经像您的示例了。这里没有“连接太多”(因为连接在循环内打开/关闭)
  • @martincho 即使我无法从您的代码中生成错误“连接太多”:(.

标签: mysql sqlalchemy


【解决方案1】:

以下是正确编写该代码的方法:

db = create_engine('mysql://root@localhost/test_database')
for i in range(1,2000):
    conn = db.connect()
    #some simple data operations
    conn.close()
db.dispose()

也就是说,Engine 是连接的工厂以及连接的,而不是连接本身。当您说conn.close() 时,连接返回到引擎内的连接池,实际上并未关闭。

如果您确实希望连接真正关闭,即不被池化,请通过NullPool 禁用池化:

from sqlalchemy.pool import NullPool
db = create_engine('mysql://root@localhost/test_database', poolclass=NullPool)

使用上述Engine 配置,每次调用conn.close() 都会关闭底层DBAPI 连接。

如果 OTOH 你真的想在每次调用时连接到不同的数据库,也就是说,你的硬编码 "localhost/test_database" 只是一个例子,你实际上有很多不同的数据库,那么使用 @ 的方法987654332@ 可以;它将关闭所有未从池中签出的连接。

在上述所有情况下,重要的是Connection 对象是通过close() 关闭的。如果您使用任何类型的“无连接”执行,即engine.execute()statement.execute(),则应该完全读取从该执行调用返回的ResultProxy 对象,或者通过close() 明确关闭。仍然打开的ConnectionResultProxy 将禁止NullPooldispose() 方法关闭每个最后一个连接。

【讨论】:

  • dispose()!!我需要它来关闭会话,因为 session.close() 还不够。我建议将此添加到 SQLAlchemy 文档中,根据我的经验,尚不清楚如何正确关闭会话。
  • 您调用 close(),如文档所述。 dispose() 是不需要的,实际上在正常的 SQLAlchemy 使用中几乎不需要显式调用 dispose() 。请随时通过电子邮件向mailing list 发送有关您的特定问题的信息,也许您在会话中执行了一些特殊指令,例如“SET”,这些指令在使用池时未被清除(有不同的处理方式)。
  • 我刚刚在一个新问题中发布了信息:How can I properly close a SQLAlchemy session? 如果您可以在这里回答。否则我会通过邮件列表联系。非常感谢!
  • @zzzeek 参加聚会有点晚了,但只是想感谢您出色的工作。我已经成为赞助人了! (其他阅读本文的人也应该:patreon.com/join/zzzeek
【解决方案2】:

试图找出一个解决方案,为一个不相关的问题断开与数据库的连接(必须在分叉之前断开连接)。

你也需要invalidate连接池中的连接。

在你的例子中:

for i in range(1,2000):
    db = create_engine('mysql://root@localhost/test_database')
    conn = db.connect()
    # some simple data operations
    # session.close() if needed
    conn.invalidate()
    db.dispose()

【讨论】:

    猜你喜欢
    • 2018-06-21
    • 2019-12-28
    • 1970-01-01
    • 2015-05-16
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    • 2015-07-28
    相关资源
    最近更新 更多