web-dev-qa-db-ja.com

psycopg2:カーソルはすでに閉じています

psycopg2 2.6.1を使用しています。一連のクエリを順番に実行する必要があります。

conn = psycopg2.connect(database=redshift_database,
                        user=redshift_user,
                        password=os.environ.get("PGPASSWORD"),
                        Host=redshift_cluster,
                        port=redshift_port)
cursor = conn.cursor()

queries = [q1, q2, q3....] ## a list of queries 
for query in queries:
    try:
        cursor.execute(query)
    except:
        print e.message

q1SSL connection has been closed unexpectedlyで失敗したとします。次に、残りのクエリもcursor already closedで失敗します。 1つのクエリが失敗した場合、次のクエリが正常に実行されるようにするにはどうすればよいですか。

11
nish

おそらく、接続が切断された場合は、接続を再確立して、例外ハンドラーで別のカーソルを取得する必要があります。

_for query in queries:
    try:
        cursor.execute(query)
    except Exception as e:
        print e.message
        conn = psycopg2.connect(....)
        cursor = conn.cursor()
_

キャッチする例外を除いて、より具体的にする必要があります。カーソルが何らかの方法で閉じられている場合にInterfaceError例外を想定すると、次のようにそれをキャッチできます。

_except psycopg2.InterfaceError as e:
_

後続のクエリの実行を妨げる、それほど大きくない他の問題がある可能性があります。トランザクションは中止されます。その場合、現在のトランザクションをロールバックしてから、次のクエリを試す必要があります。

_queries = ['select count(*) from non_existent_table', 'select count(*) from existing_table']
for query in queries:
    try:
        cursor.execute(query)
    except psycopg2.ProgrammingError as exc:
        print exc.message
        conn.rollback()
    except psycopg2.InterfaceError as exc:
        print exc.message
        conn = psycopg2.connect(....)
        cursor = conn.cursor()
_

ここでは、存在しないテーブルに対してクエリが試行されます。 ProgrammingError例外が発生し、別のクエリを試行する場合は接続をロールバックする必要があります。 2番目のクエリは成功するはずです。

これにより、例外ハンドラー自体で発生するその他の例外の詳細がわかりにくくなります。たとえば、接続を再確立しようとすると、connect(...)が失敗する可能性があるため、それも処理する必要があります。

16
mhawke

クエリよりも低いレベルで問題が発生した場合に備えて、明示的にregenerate例外ブロック内のカーソルを指定する必要があります。

for query in queries:
    try:
        cursor.execute(query)
    except:
        print e.message
        try:
            cursor.close()
            cursor = conn.cursor()
        except:
            conn.close()
            conn = psycopg2.connect(...)
        cursor = conn.cursor()
2
Serge Ballesta