Ripristino pg_dump di testo semplice con psql e --disable-trigger


8

Ho dovuto eseguire alcuni test con un breve script per aggiornare alcuni dati "legacy" in una delle mie tabelle.

Cautamente come sono, usando uno script non testato, ho deciso di eseguire il backup della tabella pertinente prima di farlo. Il modo più semplice per farlo era:

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

Ora ho fatto quello che dovevo fare, ho controllato i risultati e li ho trovati piuttosto insoddisfacenti. Ho pensato a me stesso: quanto sono fortunato ad avere un backup di quel tavolo.

Ero già stato avvertito quando ho eseguito il backup del tavolo che:

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.

Non ci ho pensato molto, ma ora abbiamo un problema. In effetti alla tabella in questione sono associati più trigger, ma non riesco a ripristinare l' table.sqlopzione with --disable-triggers del comando pg_restore.

Se provo a seguire il comando ricevo un messaggio di errore:

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

vale a dire:

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

Esiste una bandiera per il psqlcomando che presenta lo stesso comportamento di --disable-triggers?

Ho già controllato la "manpage" di psql , cercando parole chiave trigger e simili ma non ho trovato nulla.

O è l'unica opzione che devo rilasciare i trigger sul tavolo prima di ripristinare i dati?

Sidenote: sto usando Postgres v. 9.3 su un sistema Ubuntu 14.10


È stato suggerito di modificare il file sql generato, per includere l'istruzione:

ALTER TABLE table DISABLE TRIGGER ALL

Quando ora eseguito: psql -d database -f table.sqlho ricevuto un messaggio di errore sulla violazione del vincolo "Unico" della chiave primaria.

Per risolvere questo problema ho cercato di avvolgere la copia in:

BEGIN TRANSACTION READ WRITE;
TRUNCATE TABLE table;

-- copy here

COMMIT;

Ora il messaggio di errore è:

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

Quest'ultimo avviso si ripete per ciascuno \N(che simboleggia il valore null) nel dump.


2
Puoi andare e modificare il tuo dump in qualsiasi editor. Basta anteporre il COPYcon un ALTER TABLE table DISABLE TRIGGER ALLe riattivare questi alla fine.
dezso

Preparando solo la disabilitazione, viene visualizzato un errore che indica che la copia viola il vincolo univoco della chiave primaria. (Abbastanza comprensibile) Quando procedo a BEGIN TRANSACTION READ WRITE; TRUNCATE TABLE table;proteggere i miei dati, mi vengono inondati di messaggi su comandi non validi :(
Vogel612

@ Vogel612 "comandi non validi"? Mostra gli errori esatti per favore.
Craig Ringer

@CraigRinger Mi dispiace per l'attesa, ho modificato la domanda per includere ciò che ho fatto e i messaggi di errore che ho ricevuto
Vogel612

Tutto ciò significa che alcuni dati sono stati aggiornati, giusto? Prova ad aggiornarli di nuovo, usando una tabella temporanea in cui copi i dati originali.
dezso

Risposte:


4

@dezso ha avuto l' idea assolutamente giusta :

Tutto ciò significa che alcuni dati sono stati aggiornati, giusto? Prova ad aggiornarli di nuovo, usando una tabella temporanea in cui copi i dati originali

L'unica cosa rimasta ora era farlo accadere.

Quindi ecco cosa ho fatto. Ho preso una foglia dal suo libro e modificato manualmente il file di dump per utilizzare una tabella denominata table_backup. Quindi ho creato detta tabella usando la definizione fornita nel mio pgAdmin (ma può essere eseguita anche manualmente).

Ho lasciato fuori trigger e vincoli, nonché chiavi esterne, e poi ho proceduto a "aggiornare" la tabella originale con i dati della tabella di backup come il seguente:

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;

Quindi sono finalmente tornato con i miei dati originali, pronto per il prossimo test;)


0

Prepara questa riga al dump di dati .sql:

set session_replication_role = replica;

e psql non dovrebbe lamentarsi al ripristino.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.