psycopg2关闭连接池

9
我正在开发一个Flask API,并使用Psycopg2创建一个连接池。我想知道当程序终止时是否应该考虑关闭连接池,如果是,应该如何做到这一点?
@contextmanager
def get_cursor(:
    global connection_pool
    if not cls.connection_pool:
        cls.connection_pool = ThreadedConnectionPool(5, 25, dsn=PoolingWrap.generate_conn_string())

    con = cls.connection_pool.getconn()
    try:
        yield con.cursor(cursor_factory=RealDictCursor)
    finally:
        cls.connection_pool.putconn(con)

1
在回答之前,我想知道您是否有使用SQLAlchemy的原因,它有助于处理这个问题。 - Luis Orduz
你正在使用哪个服务器? - Matthew Story
你可能需要返回con对象。在使用cursor.execute后,你需要使用con对象进行提交(commit)。调用commit函数后,你必须放置连接(connection)。 - Murali
2
这与Flask或SQLAlchemy无关。一般的问题是连接池是否需要以任何方式关闭,以及是否可以安全地完成。 - mart1n
2
@mart1n - 你尝试过使用'with'吗?https://www.python.org/dev/peps/pep-0343/ - Scott Skiles
显示剩余3条评论
1个回答

7
我认为只要在每个连接中正确地关闭事务,你就可以安全地离开全局池,这种情况下可能出现的最糟糕结果是一些数据库端的连接需要花费一段时间才能找出它们已经在客户端被关闭,但这不会导致任何数据一致性问题。如果你确实想在退出之前关闭连接池,一种方法是注册一个atexit函数。
import atexit

@atexit.register
def close_connection_pool():
    global connection_pool
    connection_pool.closeall()

我认为.close()会强制关闭任何正在处理事务的现有连接。是否有办法等待这些连接自行关闭(或在一定时间后强制关闭),然后再退出? - mart1n
@mart1n 可能有方法可以做到这一点,但是 "atexit" 处理程序只在程序关闭时调用一次。在那个阶段,所有事情都应该完成。你应该在更高的层面处理这种逻辑 - 在你的主线程退出之前。 - Michael Anderson
连接池有close方法吗?http://initd.org/psycopg/docs/pool.html 我没有看到。文档说:“这个池类主要设计用于与Zope交互,可能在通用应用程序中没有用处”,哎呀。它是一个客户端连接的容器,因此关闭连接是否更相关,而不是关闭“池”。如果真的必要,pool确实有一个closeall()方法,但正如你所说,这不会成为问题,因为连接对象将被GC删除,服务器最多需要一段时间来解决这个问题。 - Davos
@Davos - 你是对的,应该是 closeall - 我已经更新了。谢谢。 - Michael Anderson
1
@Davos - 我读到有关Zope的评论只涉及到PersistentConnectionPool子类,而不是ThreadedConnectionPoolSimpleConnectionPool - Michael Anderson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接