2009-08-15 50 views
17

オンラインで数時間オンラインに接続できるデータベース接続を開くPythonアプリケーションがありますが、データベースサーバが再起動し、Pythonに接続している間に時々OperationalErrorの例外が発生します。psycopg2データベースの接続が確実に行われている

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

ありがとう。

答えて

8

pg_connection_statusは、PQstatusを使用して実装されます。 psycopgはそのAPIを公開しないので、チェックは利用できません。 psycopgと呼ばれる唯一の2つの場所は、新しい接続が行われたときと、実行の開始時です。したがって、接続がまだ存在するかどうかを調べるには、簡単なSQL文を発行する必要があります。

+0

私はpsycopg2ソースを読みながら同じ結論に達しました。ありがとう。 – HardQuestions

+0

psycopg作成者にそのような機能を追加するように要求します。 – HardQuestions

+0

下記のJaymonの答えをご覧ください。 – sage88

30

この質問は本当に古いですが、まだGoogleでポップアップするので、私はそれがpsycopg2.connectionインスタンスが現在の接続があるときに、接続が開かれ、ゼロよりも大きい場合0なりますclosed attributeを持っていることを知っておく価値のあることだと思う検索します閉まっている。次の例を証明する必要があります

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

+0

@Vyktorあなたが正しいです!問題は、Pythonの接続は、dbと通信しようとするまで切断されたことを知らないということです。私は例を更新しました。良いニュースは、クエリ実行コードをラップしてエラー時に接続を確認し、必要に応じて再接続できることです。 – Jaymon

+0

データベースが再起動したため、クエリの実行中に接続が閉じられました。 'cur.execute( 'SELECT 1')'私のケースで 'cursor already closed'というメッセージで' InterfaceError'を投げました – raphael

6

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でテストされました - レベルは何に関係なく常にゼロです。 –

関連する問題