Exportar e importar um banco de dados PostgreSQL com um nome diferente?

39

Existe uma maneira de exportar um banco de dados PostgreSQL e depois importá-lo com outro nome?

Estou usando o PostgreSQL com o Rails e geralmente exporto os dados da produção, onde o banco de dados é chamado blah_production e os importo no desenvolvimento ou na preparação com os nomes blah_development e blah_staging. No MySQL, isso é trivial, pois a exportação não possui o banco de dados em nenhum lugar (exceto um comentário, talvez), mas no PostgreSQL parece impossível. Isso é impossível?

Atualmente, estou descartando o banco de dados desta maneira:

pg_dump blah > blah.dump

Não estou usando as opções -c ou -C. Esse despejo contém instruções como:

COMMENT ON DATABASE blah IS 'blah';

ALTER TABLE public.checks OWNER TO blah;

ALTER TABLE public.users OWNER TO blah;

Quando tento importar com

psql blah_devel < blah.dump

eu recebo

WARNING:  database "blah" does not exist

ERROR:  role "blah" does not exist

Talvez o problema não seja realmente o banco de dados, mas o papel?

Se eu despejo desta maneira:

pg_dump --format=c blah > blah.dump

e tente importá-lo desta maneira:

pg_restore -d blah_devel < tmp/blah.psql

Eu recebo estes erros:

pg_restore: WARNING:  database "blah" does not exist
pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 1513; 1259 16435 TABLE checks blah
pg_restore: [archiver (db)] could not execute query: ERROR:  role "blah" does not exist
    Command was: ALTER TABLE public.checks OWNER TO blah;
pg_restore: [archiver (db)] Error from TOC entry 1509; 1259 16409 TABLE users blah
pg_restore: [archiver (db)] could not execute query: ERROR:  role "blah" does not exist
    Command was: ALTER TABLE public.users OWNER TO blah;
pg_restore: [archiver (db)] Error from TOC entry 1508; 1259 16407 SEQUENCE users_id_seq blah
pg_restore: [archiver (db)] could not execute query: ERROR:  role "blah" does not exist
    Command was: ALTER TABLE public.users_id_seq OWNER TO blah;
pg_restore: [archiver (db)] Error from TOC entry 1824; 0 0 ACL public postgres
pg_restore: [archiver (db)] could not execute query: ERROR:  role "postgres" does not exist
    Command was: REVOKE ALL ON SCHEMA public FROM postgres;
pg_restore: [archiver (db)] could not execute query: ERROR:  role "postgres" does not exist
    Command was: GRANT ALL ON SCHEMA public TO postgres;
WARNING: errors ignored on restore: 11

Alguma ideia?

Eu já vi pessoas usando scripts sed para modificar o dump. Eu gostaria de evitar essa solução, mas se não houver alternativa, eu a adotarei. Alguém escreveu um script para alterar o nome do banco de dados do dump para garantir que nenhum dado seja alterado?

pupeno
fonte

Respostas:

42

A solução foi descartada da seguinte forma:

pg_dump --no-owner --no-acl blah > blah.psql

e importando-o assim:

psql blah_devel < blah.psql > /dev/null

Eu ainda recebo este aviso:

WARNING:  database "blah" does not exist

mas o resto parece funcionar.

pupeno
fonte
2
Você é um salva-vidas :)
Sri Harsha Kappala
salva-vidas mano :)
Você sabe quem
11

Se você estiver criando um dump de texto, poderá exportar o banco de dados sem os CREATE DATABASEbits (ou seja, não especifique -ce - Copções para pg_dump); Isso impedirá que o Postgres tente soltar, criar e conectar-se ao banco de dados.

Se você estiver usando um dos formatos de arquivo morto, poderá especificar a -dopção pg_restorepara nomear o banco de dados para o qual deseja restaurar.

Verifique as páginas do homem para pg_dumpe pg_restorepara mais informações, e não se esqueça de montar um macaco zero antes de tentar isso em sistemas de produção em caso eu deixei de fora alguns detalhes importantes.

voretaq7
fonte
Obrigado. Vou tentar -da com pg_restore, mas, no momento, estou despejando-o como texto e em pg_dump não estou especificando nem -c nem -C. Estou apenas chamando pg_dump databasename. Estou esquecendo de algo?
pupeno
sem opções pg_dumpdeve criar um dump que você restaure em qualquer banco de dados ao qual está conectado (já faz um tempo desde que eu fiz um dump de texto e restaurei em um banco de dados diferente, mas se não houver CREATE& \connectbits, o SQL no dump de texto será executado onde quer que você é quando você \imPort o arquivo de despejo.
voretaq7
O pg_dump no modo texto ou binário, por padrão, possui várias menções ao nome do banco de dados.
pupeno
6

Agora, o pg_restore possui a opção -d e você pode definir o nome do banco de dados para importar dados.

na fonte :

pg_dump -v -Fc mydb.dmp mydb

no dest :

createdb -T template1 mydb2

pg_restore -v -e -d mydb2 mydb.dmp

Dmitry Kremer
fonte
3
Essa sintaxe funcionou para mim: pg_dump -v -Fc mydb > mydb.dmp(pg_dump v9.4.5).
Paolo