web-dev-qa-db-ja.com

psycopg2データベース接続が有効であることを確認します

pythonアプリケーションがデータベース接続を開き、1時間オンラインでハングする可能性がありますが、データベースサーバーが再起動し、pythonがまだ接続している間OperationalError例外では機能しません。

したがって、データベースを「ping」して接続が有効であることを確認するための信頼できる方法を探しています。 psycopg2のドキュメントを確認しましたが、そのようなものは見つかりません。確かに、SELECT 1のような単純なSQLステートメントを発行して例外をキャッチできますが、PHP pg_connection_status のようなネイティブメソッドがあることを願っています

ありがとう。

30
HardQuestions

pg_connection_statusはPQstatusを使用して実装されます。 psycopgはそのAPIを公開しないため、チェックは利用できません。 psycopgがPQstatus自体を呼び出す場所は、新しい接続が確立されたときと実行の開始時の2つだけです。そうです、接続がまだ存在するかどうかを確認するには、簡単なSQLステートメントを発行する必要があります。

13

この質問は本当に古いですが、それでも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
46
Jaymon

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