确保psycopg2数据库连接存活

时间:2009-08-15 13:17:09

标签: python database connection psycopg2

我有一个python应用程序打开一个可以在线挂起一个小时的数据库连接,但有时数据库服务器重新启动,而python仍然有连接,它不能用于OperationalError异常。

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

感谢。

4 个答案:

答案 0 :(得分:44)

这个问题真的很老了,但仍会在Google搜索上弹出,所以我认为知道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

答案 1 :(得分:13)

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

答案 2 :(得分:7)

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")

答案 3 :(得分:0)

如何检查连接是否关闭:

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

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

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