Извлеченный первичный ключ Обработка ошибок в Python / psycopg2

Использование Python 2.7 и

В [150]: psycopg2. версия Out [150]: '2.4.2 (dt dec pq3 ext)'

У меня есть простые скрипты python, которые обрабатывают транзакции и записывают данные в базу данных. Иногда есть вставка, которая нарушает мой первичный ключ. Это прекрасно, я просто хочу, чтобы он проигнорировал эту запись и продолжал ее веселый путь. Проблема, с которой я столкнулась, заключается в том, что ошибка первичного ключа psycopg2 прерывает весь блок транзакции и все вставки после ошибки. Вот пример ошибки

ERROR: duplicate key value violates unique constraint "encounter_id_pkey" DETAIL: Key (encounter_id)=(9012235) already exists. 

Это будет следующая вставка. не является нарушением.

 Inserting: 0163168~9024065 ERROR: current transaction is aborted, commands ignored until end of transaction block 

Вторая ошибка повторяется для каждой вставки. Вот упрощенный цикл. Я просматриваю кадр данных pandas, но это может быть любой цикл.

 conn = psycopg2.connect("dbname='XXXX' user='XXXXX' host='XXXX' password='XXXXX'") cur = conn.cursor() for i, val in df2.iteritems(): try: cur = conn.cursor() cur.execute("""insert into encounter_id_table ( encounter_id,current_date ) values (%(create_date)s, %(encounter_id)s ) ;""", 'encounter_id':i.split('~')[1], 'create_date': datetime.date.today() }) cur.commit() cur.close() except Exception , e: print 'ERROR:', e[0] cur.close() conn.close() 

И снова основная идея – грациозно обрабатывать Error. В изречении адмирала Нельсона Королевского флота: «Черт, маневры идут прямо на них». Или в нашем случае проклятие Ошибки идут прямо на них ». Я подумал, открыв курсор на каждой вставке, что я бы сбросил транзакционный блок. Я не хочу перезаписывать соединение только из-за ошибки первичного ключа. там что-то я просто не хватает?

Спасибо за руку за ваше время.

Джон

2 Solutions collect form web for “Извлеченный первичный ключ Обработка ошибок в Python / psycopg2”

Вы должны откатить транзакцию при ошибке.

Я добавил еще одну try..except..else конструкцию в коде ниже, чтобы показать точное место, где будет происходить исключение.

 try: cur = conn.cursor() try: cur.execute("""insert into encounter_id_table ( encounter_id,current_date ) values (%(create_date)s, %(encounter_id)s ) ;""", 'encounter_id':i.split('~')[1], 'create_date': datetime.date.today() }) except psycopg2.IntegrityError: conn.rollback() else: conn.commit() cur.close() except Exception , e: print 'ERROR:', e[0] 

Прежде всего: CURRENT_DATE является зарезервированным словом в каждом стандарте SQL, а также в PostgreSQL. Вы не можете использовать его как идентификатор без двойного цитирования. Я бы настоятельно советовал не использовать его вообще. Я переименовал столбец в curdate в моем примере

Далее, я не эксперт в синтаксисе python, но вы, похоже, изменили порядок своих столбцов-вставок:

 (%(create_date)s, %(encounter_id)s ) 

Должно быть:

 ( %(encounter_id)s, %(create_date)s) 

На ваш главный вопрос: вы можете вообще избежать проблемы, проверяя, находится ли ключ в таблице перед его использованием в команде insert:

 INSERT INTO encounter_id_table (encounter_id, curdate) SELECT 1234, now()::date WHERE NOT EXISTS (SELECT * FROM encounter_id_table t WHERE t.encounter_id = 1234); 

В синтаксисе Python это должно быть:

 cur.execute("""INSERT INTO encounter_id_table (encounter_id, curdate) SELECT %(encounter_id)s, %(create_date)s, WHERE NOT EXISTS ( SELECT * FROM encounter_id_table t WHERE t.encounter_id = %(encounter_id)s);""", {'encounter_id':i.split('~')[1], 'create_date': datetime.date.today()}) 
  • Регулярное выражение для соответствия началу имени файла и расширению имени файла.
  • Лучший способ разбивать необработанный SQL-запрос в представлении списка Django REST ListAPI?
  • Самый эффективный способ выполнить SQL «INSERT IF NOT EXISTS»,
  • сделать python ждать, пока хранимая процедура завершит выполнение
  • Zeppelin: Какой лучший способ запросить данные с SQL и работать с ним?
  • Сохранить SQL в YAML как есть
  • Импорт CSV-файла в Oracle с использованием CX_Oracle & Python 2.7
  • Что эквивалентно «select max (column) from table» в pytables
  • Python - лучший язык программирования в мире.