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
предположим q1
выдает SSL connection has been closed unexpectedly
. Тогда мои остальные запросы также терпят неудачу с cursor already closed
. Как я могу гарантировать, что если один запрос не выполняется, то следующие запросы выполняются успешно.
2 ответов
предположительно, если соединение упало, вам нужно будет восстановить его и получить другой курсор в обработчике исключений:
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(...)
может произойти сбой при попытке восстановить соединение, поэтому вы должны справиться с этим тоже.
вы должны explicitely восстановить курсор в кроме блока в случае, если что-то пошло не так на более низком уровне, что запрос:
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()