2016-02-26 16 views
7

Sto usando psycopg2 2.6.1. Ho un sacco di domande che devo eseguire in sequenza.psycopg2: cursore già chiuso

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 

Supponiamo q1 fallisce con SSL connection has been closed unexpectedly. Quindi anche il resto delle query non riesce con cursor already closed. Come posso assicurarmi che se una query fallisce, le seguenti query vengono eseguite correttamente.

+0

controllare questo collegamento potrebbe essere utile per voi http://stackoverflow.com/questions/1281875/making-sure-that-psycopg2-database-connection-alive –

risposta

9

Presumibilmente, se la connessione è sceso si avrebbe bisogno di ristabilire e ottenere un altro cursore nel gestore di eccezioni:

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

si dovrebbe essere più specifico con le eccezioni che si cattura. Supponendo un'eccezione InterfaceError se il cursore è in qualche modo chiuso si può prendere che in questo modo:

except psycopg2.InterfaceError as e: 

Ci possono essere altri problemi meno drastiche che impediscono l'esecuzione di query successive da, per esempio la transazione è stata interrotta. In questo caso è necessario eseguire il rollback la transazione corrente e quindi provare la query successiva:

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

Ecco una query viene provato su una tabella inesistente. Viene sollevata un'eccezione ProgrammingError e la connessione deve essere ripristinata se si tenta di tentare un'altra query. La seconda query dovrebbe avere successo.

Questo spiega i dettagli di ulteriori eccezioni sollevate negli stessi gestori di eccezioni, ad es. connect(...) potrebbe non riuscire nel tentativo di ristabilire la connessione, quindi dovresti gestirlo anche tu.

+1

La query in corso alla chiusura della connessione genererà un 'OperationError ', e poi quelli successivi getteranno' InterfaceError's – raphael

1

Si dovrebbe esplicitamente rigenerare il cursore in salvo blocco nel caso in cui qualcosa è andato storto a un livello inferiore che la query:

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