2016-02-26 124 views
7

我正在使用psycopg2 2.6.1。我有一堆需要按顺序执行的查询。psycopg2:光标已关闭

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 

假设q1不合格SSL connection has been closed unexpectedly。然后我的其余查询也以cursor already closed失败。我如何确保如果一个查询失败,那么以下查询将成功执行。

+0

检查此链接可能对您有帮助http://stackoverflow.com/questions/1281875/making-sure-that-psycopg2-database-connection-alive –

回答

9

据推测,如果连接已经降到你需要重新建立,并得到异常处理程序中的另一个光标:

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异常,并且如果要尝试另一个查询,则必须回滚连接。第二个查询应该成功。

这掩盖了例外处理程序本身引发的进一步异常的细节,例如,尝试重新建立连接时,connect(...)可能会失败,因此您也应该处理该问题。

+1

连接关闭时正在进行的查询将会抛出一个'OperationError ',然后后续的将会抛出'InterfaceError's – raphael

1

你应该明确地再生光标在除的情况下,一些集团出了错在较低的水平,查询:

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