Restaurar texto plano pg_dump con psql y --disable-triggers

8

Tuve que realizar algunas pruebas con un script corto para actualizar algunos datos "heredados" en una de mis tablas.

Cauteloso como soy, usando un script no probado, decidí hacer una copia de seguridad de la tabla relevante antes de hacerlo. La forma más sencilla de hacerlo fue:

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

Ahora hice lo que tenía que hacer, verifiqué los resultados y los encontré bastante insatisfactorios. Pensé para mí mismo: qué suerte tengo de tener una copia de seguridad de esa mesa.

Ya me habían advertido cuando hice una copia de seguridad de la mesa 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.

No pensé mucho en eso, pero ahora tenemos un problema. De hecho, la tabla en cuestión tiene múltiples desencadenantes adjuntos, pero no puedo restaurar la table.sqlopción --disable-triggers with del comando pg_restore.

Si intento seguir el comando, aparece un mensaje de error:

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

a saber:

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

¿Hay una bandera para el psqlcomando que exhibe el mismo comportamiento que --disable-triggers?

Ya he revisado la "página de manual" de psql , buscando activador y palabras clave similares, pero no encontré nada.

¿O es la única opción que tengo para soltar los disparadores en la tabla antes de restaurar los datos?

Nota al margen: estoy usando postgres v. 9.3 en un sistema Ubuntu 14.10


Se sugirió editar el archivo sql generado, para incluir la declaración:

ALTER TABLE table DISABLE TRIGGER ALL

Cuando ejecuté ahora: psql -d database -f table.sqlrecibí un mensaje de error sobre la violación de la restricción "Única" de la clave primaria.

Para solucionar esto, intenté envolver la copia en:

BEGIN TRANSACTION READ WRITE;
TRUNCATE TABLE table;

-- copy here

COMMIT;

Ahora el mensaje de error es:

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

La última advertencia se repite para cada uno \N(que simboliza el valor nulo) en el volcado.

Vogel612
fuente
2
Puede ir y editar su volcado en cualquier editor. Simplemente anteponga el COPYcon un ALTER TABLE table DISABLE TRIGGER ALLy vuelva a habilitarlos al final.
dezso
Anteponiendo solo la desactivación, recibo un error que indica que la copia viola la restricción única de la clave primaria. (Muy comprensiblemente) Cuando procedo a BEGIN TRANSACTION READ WRITE; TRUNCATE TABLE table;tener mis datos seguros, me duchan con mensajes sobre comandos no válidos :(
Vogel612
@ Vogel612 "comandos no válidos"? Mostrar los errores exactos por favor.
Craig Ringer
@CraigRinger Perdón por la espera, edité la pregunta para incluir lo que hice y los mensajes de error que recibí
Vogel612
Todo esto significa que algunos datos han sido actualizados, ¿verdad? Intente actualizarlos nuevamente, utilizando una tabla temporal donde copie los datos originales.
dezso

Respuestas:

4

@dezso tuvo la idea completamente correcta :

Todo esto significa que algunos datos han sido actualizados, ¿verdad? Intente actualizarlos nuevamente, utilizando una tabla temporal donde copie los datos originales

Lo único que quedaba ahora era hacerlo realidad.

Así que esto es lo que hice. Saqué una hoja de su libro y edité manualmente el archivo de volcado para usar una tabla llamada table_backup. Luego creé dicha tabla usando la definición proporcionada en mi pgAdmin (pero también se puede hacer manualmente).

Dejé de lado los desencadenantes y las restricciones, así como las claves externas, y luego procedí a "actualizar" la tabla original con los datos de la tabla de respaldo de la siguiente manera:

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;

Así que finalmente estoy de vuelta con mis datos originales, listos para la próxima prueba;)

Vogel612
fuente
0

Anteponga esta línea al volcado de datos .sql:

set session_replication_role = replica;

y psql no debería quejarse al restaurar.

Ivan Kozik
fuente