代码之家  ›  专栏  ›  技术社区  ›  HardQuestions

确保psycopg2数据库连接处于活动状态

  •  27
  • HardQuestions  · 技术社区  · 15 年前

    我有一个python应用程序,它打开一个数据库连接,这个连接可以在线挂起一个小时,但有时数据库服务器会重新启动,而python仍然有它无法使用的连接。 OperationalError 例外。

    所以我正在寻找任何可靠的方法来“ping”数据库,并知道连接是活动的。我查过psycopg2文档,但找不到类似的东西。当然,我可以发布一些简单的SQL语句,比如 SELECT 1 捕获异常,但我希望有一个本机方法,类似于php pg_connection_status

    谢谢。

    3 回复  |  直到 6 年前
        1
  •  13
  •   Martin v. Löwis    15 年前

    pg_connection_status 使用pqstatus实现。psycopg不公开该API,因此检查不可用。只有两个地方psycopg调用pqstatus本身是在建立新的连接时,并在开始执行时。所以是的,您需要发出一个简单的SQL语句来查明连接是否仍然存在。

        2
  •  40
  •   leoschet    6 年前

    这个问题真的很古老,但仍然会出现在谷歌搜索中,所以我认为知道 psycopg2.connection 实例现在有一个 closed attribute 那将是 0 当连接打开时,大于零(当连接关闭时)。以下示例应演示:

    import psycopg2
    import subprocess
    
    connection = psycopg2.connect(
        dbname=database,
        user=username,
        password=password,
        host=host,
        port=port
    )
    
    print connection.closed # 0
    
    # restart the db externally
    subprocess.check_call("sudo /etc/init.d/postgresql restart", shell=True)
    
    # this query will fail because the db is no longer connected
    try:
        cur = connection.cursor()
        cur.execute('SELECT 1')
    except psycopg2.OperationalError:
        pass
    
    print connection.closed # 2
    
        3
  •  6
  •   mike921    11 年前

    connection.closed 不反映服务器关闭/断开的连接。它只表示客户端使用 connection.close()

    为了确保连接仍然有效,请读取属性 connection.isolation_level . 这将在连接断开时引发一个操作错误,pgcode==“57p01”。

    这为数据库的往返增加了一点延迟,但应该比 SELECT 1 或类似的。

    import psycopg2
    dsn = "dbname=postgres"
    conn = psycopg2.connect(dsn)
    
    # ... some time elapses, e.g. connection within a connection pool
    
    try:
        connection.isolation_level
    except OperationalError as oe:
        conn = psycopg2.connect(dsn)
    
    c = conn.cursor()
    c.execute("SELECT 1")