Восстановление простого текста pg_dump с помощью psql и --disable-triggers

8

Мне пришлось выполнить несколько тестов с помощью короткого сценария, чтобы обновить некоторые «устаревшие» данные в одной из моих таблиц.

Осторожно, используя непроверенный сценарий, я решил сделать резервную копию соответствующей таблицы, прежде чем делать это. Простейший способ сделать это был:

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

Теперь я сделал то, что должен был, проверил результаты и нашел их довольно неудовлетворительными. Я подумал про себя: как мне повезло, что у меня есть резервная копия этой таблицы.

Меня уже предупредили, когда я сделал резервную копию таблицы, что:

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.

Я не особо об этом думал, но теперь у нас проблема. Действительно, к рассматриваемой таблице прикреплено несколько триггеров, но я не могу восстановить table.sqlпараметр --disable-triggers with команды pg_restore.

Если я пытаюсь выполнить следующую команду, я получаю сообщение об ошибке:

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

а именно:

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

Есть ли флаг для psql-команды, который демонстрирует то же поведение, что и --disable-triggers?

Я уже проверил psql "manpage" , ища триггер и похожие ключевые слова, но ничего не нашел.

Или это единственный вариант, когда мне нужно сбросить триггеры на столе перед восстановлением данных?

Sidenote: я использую postgres v. 9.3 в системе Ubuntu 14.10


Было предложено отредактировать сгенерированный sql-файл, включив в него оператор:

ALTER TABLE table DISABLE TRIGGER ALL

Когда я теперь выполнил: psql -d database -f table.sqlя получил сообщение об ошибке о нарушении ограничения «Уникальный» первичного ключа.

Чтобы исправить это, я попытался обернуть копию в:

BEGIN TRANSACTION READ WRITE;
TRUNCATE TABLE table;

-- copy here

COMMIT;

Теперь сообщение об ошибке:

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

Последнее предупреждение повторяется для каждого \N(символизирующего нулевое значение) в дампе.

Vogel612
источник
2
Вы можете перейти и редактировать свой дамп в любом редакторе. Просто соедините COPYс ALTER TABLE table DISABLE TRIGGER ALLи включите их в конце.
Дезсо
Предваряя только отключение, я получаю сообщение о том, что копия нарушает уникальное ограничение первичного ключа. (Вполне понятно) Когда я приступаю к BEGIN TRANSACTION READ WRITE; TRUNCATE TABLE table;обеспечению безопасности своих данных, меня осыпают сообщениями о недопустимых командах :(
Vogel612
@ Vogel612 "неверные команды"? Покажите точные ошибки, пожалуйста.
Крейг Рингер
@CraigRinger Извините за ожидание, я отредактировал вопрос, включив в него то, что я сделал, и сообщения об ошибках, которые я получил
Vogel612
Все это означает, что некоторые данные были обновлены, верно? Попробуйте обновить их обратно, используя временную таблицу, куда вы копируете исходные данные.
Дезсо

Ответы:

4

У @dezso была совершенно правильная идея :

Все это означает, что некоторые данные были обновлены, верно? Попробуйте обновить их обратно, используя временную таблицу, куда вы копируете исходные данные

Теперь осталось только сделать это.

Итак, вот что я сделал. Я взял лист из его книги и вручную отредактировал файл дампа, чтобы использовать таблицу с именем table_backup. Затем я создал упомянутую таблицу, используя определение, приведенное в моем pgAdmin (но это можно сделать и вручную).

Я пропустил триггеры и ограничения, а также внешние ключи, а затем приступил к «обновлению» исходной таблицы данными из резервной таблицы, как показано ниже:

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;

Итак, я наконец вернулся к своим исходным данным, готов к следующему тесту;)

Vogel612
источник
0

Добавьте эту строку к дампу данных .sql:

set session_replication_role = replica;

и PSQL не должен жаловаться на восстановление.

Иван Козик
источник