Wiederherstellen von Nur-Text-pg_dump mit psql und --disable-triggern

8

Ich musste einige Tests mit einem kurzen Skript durchführen, um einige "Legacy" -Daten in einer meiner Tabellen zu aktualisieren.

So vorsichtig ich auch bin, ich habe mich mit einem nicht getesteten Skript entschlossen, die entsprechende Tabelle vorher zu sichern. Der einfachste Weg, dies zu tun, war:

pg_dump -a --file table.sql -t table database

Jetzt tat ich, was ich tun musste, überprüfte die Ergebnisse und fand sie ziemlich unbefriedigend. Ich dachte mir: Wie viel Glück habe ich, ein Backup dieser Tabelle zu haben.

Ich war bereits gewarnt worden, als ich den Tisch gesichert hatte:

pg_dump: NOTICE: there are circular foreign-key constraints among these table(s):
pg_dump:   table
pg_dump: You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints.
pg_dump: Consider using a full dump instead of a --data-only dump to avoid this problem.

Ich habe nicht viel darüber nachgedacht, aber jetzt haben wir ein Problem. In der Tat sind an die betreffende Tabelle mehrere Trigger angehängt, aber ich kann die table.sqlOption with --disable-triggers des Befehls pg_restore nicht wiederherstellen .

Wenn ich den folgenden Befehl versuche, wird eine Fehlermeldung angezeigt:

pg_restore -a -d database -t table -h localhost --disable-triggers table.sql

nämlich:

pg_restore: [archiver] input file appears to be a text format dump. Please use psql.

Gibt es ein Flag für den psqlBefehl-, das dasselbe Verhalten aufweist wie --disable-triggers?

Ich habe bereits die psql "manpage" überprüft , nach Auslösern und ähnlichen Schlüsselwörtern gesucht, aber nichts gefunden.

Oder ist die einzige Option, bei der ich die Trigger in der Tabelle ablegen muss, bevor ich die Daten wiederherstelle?

Nebenbemerkung: Ich verwende Postgres v. 9.3 auf einem Ubuntu 14.10-System


Es wurde vorgeschlagen, die generierte SQL-Datei so zu bearbeiten, dass sie die folgende Anweisung enthält:

ALTER TABLE table DISABLE TRIGGER ALL

Als ich jetzt ausgeführt habe: psql -d database -f table.sqlIch habe eine Fehlermeldung über die Verletzung der "Eindeutigen" Einschränkung des Primärschlüssels erhalten.

Um dies zu beheben, habe ich versucht, die Kopie in Folgendes zu verpacken:

BEGIN TRANSACTION READ WRITE;
TRUNCATE TABLE table;

-- copy here

COMMIT;

Jetzt lautet die Fehlermeldung:

psql:project_backup.sql:18: ERROR:  cannot truncate a table referenced in a foreign key constraint
DETAIL:  Table "another" references "table".
HINT:  Truncate table "another" at the same time, or use TRUNCATE ... CASCADE.
psql:project_backup.sql:20: ERROR:  current transaction is aborted, commands ignored until end of transaction block
psql:project_backup.sql:21: invalid command \N
psql:project_backup.sql:22: invalid command \N

Die letztere Warnung wird für jeden \N(als Symbol für den Nullwert) im Speicherauszug wiederholt .

Vogel612
quelle
2
Sie können Ihren Speicherauszug in einem beliebigen Editor bearbeiten. Stellen Sie einfach das COPYmit einem vor ALTER TABLE table DISABLE TRIGGER ALLund aktivieren Sie diese am Ende wieder.
Dekso
Wenn ich nur die Deaktivierung vorstelle, wird eine Fehlermeldung angezeigt, dass die Kopie die eindeutige Einschränkung des Primärschlüssels verletzt. (Ganz verständlich) Wenn ich fortfahre, BEGIN TRANSACTION READ WRITE; TRUNCATE TABLE table;meine Daten sicher zu halten, werde ich mit Nachrichten über ungültige Befehle
überschüttet
@ Vogel612 "ungültige Befehle"? Zeigen Sie bitte die genauen Fehler.
Craig Ringer
@CraigRinger Entschuldigung für das Warten, ich habe die Frage so bearbeitet, dass sie enthält, was ich getan habe und welche Fehlermeldungen ich erhalten habe
Vogel612
All dies bedeutet, dass einige Daten aktualisiert wurden, oder? Versuchen Sie, sie mithilfe einer temporären Tabelle, in die Sie die Originaldaten kopieren, zurück zu aktualisieren.
Dekso

Antworten:

4

@dezso hatte die völlig richtige Idee :

All dies bedeutet, dass einige Daten aktualisiert wurden, oder? Versuchen Sie, sie mithilfe einer temporären Tabelle, in die Sie die Originaldaten kopieren, zurück zu aktualisieren

Jetzt musste es nur noch geschehen.

Also hier ist was ich getan habe. Ich nahm ein Blatt aus seinem Buch und bearbeitete die Dump-Datei manuell, um eine Tabelle mit dem Namen zu verwenden table_backup. Dann habe ich diese Tabelle mit der in meinem pgAdmin angegebenen Definition erstellt (dies kann aber auch manuell erfolgen).

Ich habe Trigger und Einschränkungen sowie Fremdschlüssel weggelassen und dann die ursprüngliche Tabelle mit den Daten aus der Sicherungstabelle wie folgt "aktualisiert":

BEGIN TRANSACTION;
ALTER TABLE table DISABLE TRIGGER ALL;

UPDATE table SET 
    (column1, column2, ...) = 
    (table_backup.column1, table_backup.colum2, ...)
FROM table_backup WHERE table.pk_column = table_backup.pk_column;

ALTER TABLE table ENABLE TRIGGER ALL;
-- I didn't but you can drop table_backup here
COMMIT;

Also bin ich endlich mit meinen Originaldaten zurück, bereit für den nächsten Testlauf;)

Vogel612
quelle
0

Stellen Sie diese Zeile dem .sql-Datendump voran:

set session_replication_role = replica;

und psql sollte sich bei der Wiederherstellung nicht beschweren.

Ivan Kozik
quelle