Estoy usando SQLAlchemy con un backend de Postgres para hacer una inserción o actualización masiva. Para intentar mejorar el rendimiento, intento comprometerme solo una vez cada mil filas más o menos:¿Cómo realizo eficientemente una inserción o actualización masiva con SQLAlchemy?
trans = engine.begin()
for i, rec in enumerate(records):
if i % 1000 == 0:
trans.commit()
trans = engine.begin()
try:
inserter.execute(...)
except sa.exceptions.SQLError:
my_table.update(...).execute()
trans.commit()
Sin embargo, esto no funciona. Parece que cuando INSERT falla, deja las cosas en un estado extraño que impide que ocurra la ACTUALIZACIÓN. ¿Está revertiendo automáticamente la transacción? Si es así, ¿se puede detener esto? No quiero que se retrotraiga toda la transacción en caso de que haya un problema, por lo que estoy intentando detectar la excepción en primer lugar.
El mensaje de error que recibo, por cierto, es "sqlalchemy.exc.InternalError: (InternalError) la transacción actual se cancela, los comandos se ignoran hasta el final del bloque de transacción", y ocurre en la actualización(). Execute () llamada.
"Si ocurre un error en una transacción, obliga a que se revierte toda la transacción. Considero que esto es un error de diseño de Postgres". - ¿No es este el objetivo de las transacciones? De [Wikipedia] (http: //en.wikipedia.org/wiki/Database_transaction): "Las transacciones proporcionan una proposición 'todo o nada', que establece que cada unidad de trabajo realizada en una base de datos debe completarse en su totalidad o no tener ningún efecto en absoluto". – spiffytech
@Spiffytech Buena respuesta. Esto realmente me hizo jadear. –