43

我有一个 python 应用程序,它打开一个可以在线挂起一个小时的数据库连接,但有时数据库服务器会重新启动,虽然 python 仍然有连接,但它无法正常工作OperationalError

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

谢谢。

4

4 回答 4

70

这个问题真的很老了,但仍然会在 Google 搜索中弹出,所以我认为知道psycopg2.connection实例现在有一个closed属性是很有价值的,即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
于 2013-09-09T23:29:24.520 回答
25

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

于 2009-08-15T14:36:08.980 回答
16

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

为了确保连接仍然有效,请阅读属性connection.isolation_level。这将引发一个带有 pgcode == "57P01" 的 OperationalError 以防连接失效。

这增加了往返数据库的一些延迟,但应该比一个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")
于 2013-11-20T08:39:32.687 回答
1

如何检查连接是否关闭:

  • conn.closed 如果关闭则为 1,否则为 0

  • 如果关闭,它except psycopg2.InterfaceError as exc:不仅会在查询中引发,而且会在上下文管理器中引发:with conn:足以引发。

  • 然后,您需要重新建立连接。例如读出密码并放入.connect(..)

于 2020-04-13T09:39:26.147 回答