Uso de Python 2.7 yManejo de errores clave principal elegante en Python/psycopg2
En [150]: psycopg2. versión Fuera [150]: '2.4.2 (dt diciembre ext PQ3)'
tengo unas simples scripts de Python que el procesamiento de las transacciones y escribe datos en una base de datos. Ocasionalmente hay una inserción que infringe mi clave principal. Esto está bien, solo quiero que ignore ese registro y continúe felizmente. El problema que estoy teniendo es que el error de clave primaria psycopg2 está abortando todo el bloque de transacción y todas las inserciones después de que el error falla. Aquí hay un error de ejemplo
ERROR: duplicate key value violates unique constraint "encounter_id_pkey"
DETAIL: Key (encounter_id)=(9012235) already exists.
Esto se encuentra en la siguiente inserción. no es una violación
Inserting: 0163168~9024065
ERROR: current transaction is aborted, commands ignored until end of transaction block
El segundo error se repite para cada inserción. Aquí hay un bucle simplificado. Estoy recorriendo un marco de datos de pandas, pero podría ser cualquier ciclo.
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()
Una vez más, la idea básica es manejar con elegancia el Error. En el dictamen del almirante Nelson de la Royal Navy: "Maldición, las maniobras van directo hacia ellos". O en nuestro caso, maldita sea, los errores van directamente hacia ellos ". Pensé, al abrir un cursor en cada inserción, que reiniciaría el bloque de transacciones. No quiero tener que restablecer la conexión solo por un error de clave principal. hay algo que sólo estoy perdiendo?
Gracias de ante mano por su tiempo.
John
Esto es casi es la respuesta. Pero necesito llamar al método rollback() en el objeto de conexión (conn) aquí. El cursor solo tiene commit no rollback. Gracias – jdennison
Más errores de método. Tienes que invocar commit en la conexión, no el cursor. – jdennison
Me preguntaba si la confirmación y la reversión son métodos de conexión. Piensa que alguien debería editar mi código para corregirlo. Lamentablemente, no estoy muy familiarizado con el uso directo de 'psycopg' ya que estoy usando ORM o bases de datos no relacionales por lo general. – lig