Ich benutze SQLAlchemy mit einem Postgres-Backend, um ein Bulk-Insert-or-update durchzuführen. Um zu versuchen, die Leistung zu verbessern, versuche ich, nur einmal alle tausend Zeilen oder so festschreiben:Wie führe ich eine Masseneinfügung oder -aktualisierung mit SQLAlchemy effizient durch?
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()
Allerdings funktioniert dies nicht. Es scheint, dass wenn die INSERT fehlschlägt, Dinge in einem seltsamen Zustand bleiben, der das UPDATE verhindert. Wird die Transaktion automatisch zurückgesetzt? Wenn ja, kann dies gestoppt werden? Ich möchte nicht, dass meine gesamte Transaktion im Falle eines Problems zurückgesetzt wird. Deshalb versuche ich, die Ausnahme überhaupt zu erfassen.
Die Fehlermeldung, die ich bekomme, BTW, ist "sqlalchemy.exc.InternalError: (InternalError) aktuelle Transaktion wird abgebrochen, Befehle bis zum Ende des Transaktionsblocks ignoriert", und es geschieht auf dem update().) Anruf.
"Wenn in einer Transaktion ein Fehler auftritt, wird die gesamte Transaktion rückgängig gemacht. Dies ist ein Postgres-Designfehler." - Ist das nicht der Punkt der Transaktionen? Aus [Wikipedia] (http: //en.wikipedia.org/wiki/Database_transaction): "Transaktionen bieten einen Alles-oder-Nichts-Vorschlag, der besagt, dass jede Arbeitseinheit, die in einer Datenbank ausgeführt wird, entweder vollständig ausgeführt werden muss oder überhaupt keinen Effekt hat." – spiffytech
@ Spiffytech Gute Antwort. Das hat mich wirklich LOL gemacht. –