确保psycopg2数据库连接有效

确保psycopg2数据库连接有效

问题描述:

我有一个python应用程序,它打开一个数据库连接,可以在线挂上几个小时,但有时候数据库服务器会重新启动,而python仍然有连接,它将无法使用OperationalError异常。确保psycopg2数据库连接有效

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

感谢。

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

+0

我在阅读psycopg2来源时得出了同样的结论。谢谢。 – HardQuestions 2009-08-15 14:43:39

+0

将向psycopg作者提交请求以添加此功能。 – HardQuestions 2009-08-15 14:46:43

+0

请参阅下面的Jaymon的回答。 – sage88 2017-02-03 08:24:39

这个问题确实是老了,但还是弹出在谷歌搜索,所以我认为这是有价值知道psycopg2.connection实例现在有一个closed attribute这将是0当连接是开放的,且大于零当连接关闭。下面的例子说明了:

import psycopg2 
import subprocess 

connection = psycopg2.connect(
    database=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

您是否尝试过杀死数据库连接TCP句柄(在Windows上)。 'connection.closed'不幸的是不会改变值。 – Vyktor 2014-11-19 10:01:46

+0

@Vyktor你是对的!问题是,Python的连接不知道它已经被切断,直到它试图与数据库进行通信。我更新了这个例子。好消息是,您可以封装执行代码的查询来检查错误连接并根据需要重新连接。 – Jaymon 2014-12-11 23:17:13

+0

我的连接在查询过程中因为数据库重新启动而关闭'cur.execute('SELECT 1')'在我的情况下抛出了一个'InterfaceError',消息'cursor already closed' – raphael 2016-08-19 13:57:33

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

用psycopg2 2.5.2和psql 8.4测试 - 隔离无论如何,等级总是零。 – 2014-02-03 12:05:46