Fortsetzen einer Transaktion nach dem Fehler der Primärschlüsselverletzung

8

Ich mache eine Masseneinfügung von Datensätzen aus einer Protokolldatei in eine Datenbank. Gelegentlich (~ 1 Zeile von jedem Tausend) verletzt eine der Zeilen den Primärschlüssel und bewirkt, dass die Transaktion fehlschlägt. Derzeit muss der Benutzer die Datei, die den Fehler verursacht hat, manuell durchsuchen und die fehlerhafte Zeile entfernen, bevor er erneut importieren möchte. Angesichts der Tatsache, dass es Hunderte von diesen Dateien zu importieren gibt, ist es unpraktisch.

Meine Frage: Wie kann ich das Einfügen von Datensätzen überspringen, die gegen die Primärschlüsseleinschränkung verstoßen, ohne eine SELECT -Anweisung vor jeder Zeile eingeben zu müssen, um festzustellen, ob sie bereits existiert?

Hinweis: Mir ist die sehr ähnliche Frage bekannt # 1054695 , aber es scheint eine SQL Server-spezifische Antwort zu sein, und ich verwende PostgreSQL (Import über Python / psycopg2).

    
John 03.03.2010, 10:19
quelle

4 Antworten

12

Sie können SAVEPOINTs auch in einer Transaktion verwenden.

Python-Pseudocode wird von der Anwendungsseite her veranschaulicht:

%Vor%

Bearbeiten: Hier ist ein aktuelles Beispiel in Aktion in psql basierend auf einer leichten Variation des Beispiels in der Dokumentation (SQL-Anweisungen mit dem Präfix "& gt;"):

%Vor%

Beachten Sie, dass der Wert 3 nach dem Fehler eingefügt wurde, aber immer noch innerhalb derselben Transaktion!

Die Dokumentation für SAVEPOINT ist Ссылка .

    
Matthew Wood 03.03.2010, 16:27
quelle
4

Ich würde eine gespeicherte Prozedur verwenden, um die Ausnahmen für Ihre eindeutigen Verletzungen abzufangen. Beispiel:

%Vor%     
Frank Heikens 03.03.2010 10:32
quelle
1

Sie können ein rollback für die Transaktion oder ein Rollback für einen Sicherungspunkt vor dem Code ausführen, der die Ausnahme auslöst (cr ist der Cursor):

%Vor%

In diesem Code wird davon ausgegangen, dass eine Transaktion ausgeführt wird. Andernfalls erhalten Sie diese Fehlermeldung nicht.

Django postgresql Backend erstellt Cursor direkt aus psycopg . Vielleicht werden sie in Zukunft eine Proxy-Klasse für den Django-Cursor erstellen, ähnlich dem Cursor von odoo . Sie erweitern den Cursor mit dem folgenden Code (self ist der Cursor):

%Vor%

Auf diese Weise vereinfacht der Kontext Ihren Code:

%Vor%

und der Code ist besser lesbar, weil die Transaktionssache nicht da ist.

    
yucer 03.02.2017 09:25
quelle
0

Oder Sie können SSIS verwenden und die fehlerhaften Zeilen haben einen anderen Pfad als die erfolgreichen.

Wenn Sie eine andere Datenbank verwenden, können Sie die Dateien in eine Staging-Tabelle einfügen und dann mit SQL-Code nur die Datensätze auswählen, für die keine ID existiert?

    
HLGEM 03.03.2010 15:35
quelle