Restaurando texto simples pg_dump com psql e --disable-triggers


8

Eu tive que executar alguns testes com um script curto para atualizar alguns dados "legados" em uma das minhas tabelas.

Por mais cauteloso que seja, usando um script não testado, decidi fazer backup da tabela relevante antes de fazê-lo. A maneira mais simples de fazer isso era:

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

Agora eu fiz o que tinha que fazer, verifiquei os resultados e os achei bastante insatisfatórios. Pensei comigo: como sou sortuda por ter um backup dessa mesa.

Eu já tinha sido avisado quando fiz backup da tabela de 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.

Não pensei muito nisso, mas agora temos um problema. De fato, a tabela em questão possui vários gatilhos anexados, mas não consigo restaurar a table.sqlopção with --disable-triggers do comando pg_restore.

Se eu tentar o seguinte comando, recebo uma mensagem de erro:

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

nomeadamente:

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

Existe um sinalizador para o psqlcomando que exibe o mesmo comportamento que --disable-triggers?

Eu já verifiquei o "manpage" do psql , procurando por palavras-chave de gatilho e similares, mas não encontrei nada.

Ou é a única opção que tenho para soltar os gatilhos na tabela antes de restaurar os dados?

Sidenote: Estou usando o postgres v. 9.3 em um sistema Ubuntu 14.10


Foi sugerido editar o arquivo sql gerado, para incluir a instrução:

ALTER TABLE table DISABLE TRIGGER ALL

Quando agora executei: psql -d database -f table.sqlrecebi uma mensagem de erro sobre a violação da restrição "Exclusivo" da chave primária.

Para corrigir isso, tentei colocar a cópia em:

BEGIN TRANSACTION READ WRITE;
TRUNCATE TABLE table;

-- copy here

COMMIT;

Agora a mensagem de erro é:

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

O último aviso se repete para cada um \N(simbolizando o valor nulo) no despejo.


2
Você pode editar seu dump em qualquer editor. Basta colocar o COPYcom ALTER TABLE table DISABLE TRIGGER ALLe reativar no final.
Dezso

Anexando apenas a desativação, recebo um erro informando que a cópia viola a restrição exclusiva da chave primária. (Muito compreensivelmente) Quando eu proceder para BEGIN TRANSACTION READ WRITE; TRUNCATE TABLE table;que os meus dados garantir I começa regado com mensagens sobre comandos inválidos :(
Vogel612

@ Vogel612 "comandos inválidos"? Mostre os erros exatos, por favor.
Craig campainha

@CraigRinger Desculpem a espera, eu editei a pergunta para incluir o que eu fiz e as mensagens de erro que recebi
Vogel612

Tudo isso significa que alguns dados foram atualizados, certo? Tente atualizá-los novamente, usando uma tabela temporária na qual você copia os dados originais.
Dez15

Respostas:


4

@dezso teve a ideia completamente certa :

Tudo isso significa que alguns dados foram atualizados, certo? Tente atualizá-los novamente, usando uma tabela temporária na qual você copia os dados originais

A única coisa que restava agora era fazer isso acontecer.

Então aqui está o que eu fiz. Peguei uma folha de seu livro e editei manualmente o arquivo de despejo para usar uma tabela chamada table_backup. Então eu criei a referida tabela usando a definição fornecida no meu pgAdmin (mas também pode ser feita manualmente).

Deixei de fora gatilhos e restrições, bem como Chaves estrangeiras, e depois continuei "atualizando" a tabela original com os dados da tabela de backup da seguinte maneira:

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;

Finalmente, estou de volta com meus dados originais, pronto para a próxima execução de teste;)


0

Anexe esta linha ao despejo de dados .sql:

set session_replication_role = replica;

e o psql não deve reclamar da restauração.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.