Restauration de pg_dump en texte brut avec psql et --disable-triggers

8

J'ai dû effectuer des tests avec un court script pour mettre à jour certaines données "héritées" dans l'une de mes tables.

Aussi prudent que je sois, en utilisant un script non testé, j'ai décidé de sauvegarder la table appropriée avant de le faire. La façon la plus simple de le faire était:

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

Maintenant, j'ai fait ce que j'avais à faire, vérifié les résultats et les ai trouvés plutôt insatisfaisants. Je me suis dit: quelle chance j'ai d'avoir une sauvegarde de cette table.

J'avais déjà été averti lorsque j'ai sauvegardé la table que:

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.

Je n'y pensais pas beaucoup, mais maintenant nous avons un problème. En effet, la table en question possède plusieurs déclencheurs, mais je ne peux pas restaurer l' table.sqloption with --disable-triggers de la commande pg_restore.

Si j'essaie de suivre la commande, j'obtiens un message d'erreur:

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

à savoir:

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

Existe-t-il un indicateur pour la psqlcommande qui présente le même comportement --disable-triggers?

J'ai déjà vérifié la "page de manuel" psql , recherchant le déclencheur et des mots clés similaires, mais je n'ai rien trouvé.

Ou est-ce la seule option que je dois supprimer les déclencheurs sur la table avant de restaurer les données?

Sidenote: J'utilise postgres v. 9.3 sur un système Ubuntu 14.10


Il a été suggéré de modifier le fichier sql généré, pour inclure la déclaration:

ALTER TABLE table DISABLE TRIGGER ALL

Quand j'ai maintenant exécuté: psql -d database -f table.sqlj'ai reçu un message d'erreur sur la violation de la contrainte "Unique" de la clé primaire.

Pour résoudre ce problème, j'ai essayé d'envelopper la copie dans:

BEGIN TRANSACTION READ WRITE;
TRUNCATE TABLE table;

-- copy here

COMMIT;

Maintenant, le message d'erreur est:

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

Le dernier avertissement se répète pour chacun \N(symbolisant la valeur nulle) dans le vidage.

Vogel612
la source
2
Vous pouvez aller modifier votre vidage dans n'importe quel éditeur. Ajoutez simplement le COPYavec un ALTER TABLE table DISABLE TRIGGER ALLet réactivez-les à la fin.
dezso
En prévoyant uniquement la désactivation, j'obtiens une erreur indiquant que la copie viole la contrainte unique de la clé primaire. (Tout à fait compréhensible) Lorsque je procède à BEGIN TRANSACTION READ WRITE; TRUNCATE TABLE table;la sécurisation de mes données, je reçois des messages sur des commandes invalides :(
Vogel612
@ Vogel612 "commandes invalides"? Montrez les erreurs exactes s'il vous plaît.
Craig Ringer
@CraigRinger Désolé pour l'attente, j'ai modifié la question pour inclure ce que j'ai fait et les messages d'erreur que j'ai reçus
Vogel612
Tout cela signifie que certaines données ont été mises à jour, non? Essayez de les mettre à jour en utilisant une table temporaire dans laquelle vous copiez les données d'origine.
dezso

Réponses:

4

@dezso a eu la bonne idée :

Tout cela signifie que certaines données ont été mises à jour, non? Essayez de les mettre à jour en utilisant une table temporaire dans laquelle vous copiez les données d'origine

Il ne restait plus qu'à y arriver.

Voici donc ce que j'ai fait. J'ai sorti une feuille de son livre et édité manuellement le fichier de vidage pour utiliser une table nommée table_backup. Ensuite, j'ai créé ladite table en utilisant la définition fournie dans mon pgAdmin (mais cela peut aussi être fait manuellement).

J'ai omis les déclencheurs et les contraintes, ainsi que les clés étrangères, puis j'ai "mis à jour" la table d'origine avec les données de la table de sauvegarde comme suit:

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;

Je suis donc enfin de retour avec mes données d'origine, prêt pour le prochain test;)

Vogel612
la source
0

Ajoutez cette ligne au vidage de données .sql:

set session_replication_role = replica;

et psql ne devrait pas se plaindre de la restauration.

Ivan Kozik
la source