Copie uma tabela de um banco de dados para outro no Postgres


273

Estou tentando copiar uma tabela inteira de um banco de dados para outro no Postgres. Alguma sugestão?


1
Se você está bem com a instalação do DBeaver, ele tem uma maneira muito simples de transferir entre dois bancos de dados aos quais você está conectado. Basta clicar com o botão direito do mouse na tabela de origem e selecionar Exportar Dados, segmentar uma tabela de Banco de Dados e definir o destino como o banco de dados de destino.
rovyko 22/03

Respostas:


311

Extraia a tabela e direcione-a diretamente para o banco de dados de destino:

pg_dump -t table_to_copy source_db | psql target_db

Nota: Se o outro banco de dados já tiver a tabela configurada, use o -asinalizador para importar apenas dados; caso contrário, poderá ocorrer erros estranhos como "Memória insuficiente":

pg_dump -a -t my_table my_db | psql target_db

5
Como isso funcionará para links db remotos? Por exemplo, eu preciso despejar de um local diferente.
curlyreggie

17
@ Curlyreggie não tentei isso, mas não vejo razão para que não funcione. Tente adicionar especificidades usuário e servidor para o comando, como assimpg_dump -U remote_user -h remote_server -t table_to_copy source_db | psql target_db
thomax

2
Você pode tentar o seguinte: "pg_dump -U remote_user -h remote_server -t table_to_copy source_db | psql target_db -U remote_user -h remote_server"
Hua Zhang

18
observe que se o outro banco de dados já tiver a tabela configurada, você deve usar o -asinalizador apenas para dados . ie pg_dump -a -t my_table my_db | psql target_db. Enquanto estou aqui, se seu banco de dados estiver em um servidor, acho mais fácil simplesmente despejar o banco de dados em um arquivo e, em seguida, scp esse arquivo no banco de dados e enviar o conteúdo do arquivo para o psql. por exemplo, pg_dump -a -t my_table my_db > my_file.sqle depois de colocar isso no seu servidor ->psql my_other_db < my_file.sql
Nick Brady

3
@EamonnKenny para despejar uma tabela de maiúsculas e minúsculas, fazer: pg_dump -t '"tableToCopy"' source_db | psql target_db. Note que aspas simples e duplas cercar o nome da tabela
gilad Mayani

105

Você também pode usar a funcionalidade de backup no pgAdmin II. Basta seguir estes passos:

  • No pgAdmin, clique com o botão direito do mouse na tabela que deseja mover e selecione "Backup"
  • Escolha o diretório para o arquivo de saída e defina Format como "plain"
  • Clique na guia "Dump Options # 1", marque "Only data" ou "only Schema" (dependendo do que você está fazendo)
  • Na seção Consultas, clique em "Usar inserções de coluna" e "Comandos de inserção do usuário".
  • Clique no botão "Backup". Isso gera um arquivo .backup
  • Abra esse novo arquivo usando o bloco de notas. Você verá os scripts de inserção necessários para a tabela / dados. Copie e cole-os na nova página sql do banco de dados no pgAdmin. Executar como pgScript - Consulta-> Executar como pgScript F6

Funciona bem e pode fazer várias tabelas ao mesmo tempo.


1
Essa é uma boa solução baseada em GUI para mover dados entre bancos de dados. Obrigado!
KGX

3
Você pode selecionar várias tabelas na Objectsseção. No OSX, clique no botão SQL ou SQL Editoracesse o Toolsmenu para colar o SQL copiado do arquivo de backup.
Aleck Landgraf

funciona, obrigado. Muito lento, porém em grandes mesas .. existe uma maneira melhor de fazê-lo para acelerar? (como ignorar chaves estrangeiras ou algo assim?)
TimoSolo

3
@Timothy Aqui está a página de documentação postgres sobre como acelerar o backup e restauração
Laurie

velha resposta, mas ainda relevante, funciona muito bem, só não se esqueça de definir gatilhos Desativar ao exportar todos os banco de dados
norbertas.gaulia

75

Usar o dblink seria mais conveniente!

truncate table tableA;

insert into tableA
select *
from dblink('dbname=postgres hostaddr=xxx.xxx.xxx.xxx dbname=mydb user=postgres',
            'select a,b from tableA')
       as t1(a text,b text);

12
Por que dois dbname em duas vezes ..? qual é a origem e o destino?
Arulraj.net

1
tableA que estamos inserindo é o destino, e tableA no dbLink é a fonte.
22915 Aggietech

se eu quiser usar o dblink bun, não conheço a estrutura da tabela de origem de origem?
Ossarotte

31

Usando psql, no host linux que possui conectividade para os dois servidores

( export PGPASSWORD=password1 
  psql -U user1 -h host1 database1 \
  -c "copy (select field1,field2 from table1) to stdout with csv" ) \
| 
( export PGPASSWORD=password2 
  psql -U user2 -h host2 database2 \ 
   -c "copy table2 (field1, field2) from stdin csv" )

Não há necessidade de exportar, PGPASSWORD=password1 psql -U ...então você nem precisa de subshells explícitos! Normalmente, você deve fazer algumas coisas para configurar primeiro, para que subconjuntos possam ser necessários de qualquer maneira. Além disso, as senhas não serão exportadas para processos subsequentes. Obrigado!
Expiação limitada

1
@LimitedAtonement Na verdade, você não precisa exportar e subshells. É apenas uma parte do roteiro mais complicado, e mesmo que eu não tentar, sem exportação e subshells, por isso, eu fornecê-la como é apenas para ser honesto e fornecer solução funcionou
Alexey Sviridov

A tabela deve existir no banco de dados de destino. Para criá-lo, tentepg_dump -t '<table_name>' --schema-only
fjsj

24

Primeira instalação do dblink

Então, você faria algo como:

INSERT INTO t2 select * from 
dblink('host=1.2.3.4
 user=*****
 password=******
 dbname=D1', 'select * t1') tt(
       id int,
  col_1 character varying,
  col_2 character varying,
  col_3 int,
  col_4 varchar 
);

1
Essa resposta é ótima porque permite filtrar linhas copiadas (adicione a cláusula WHERE no segundo argumento dblink). No entanto, é preciso ser explícito sobre os nomes das colunas (Postgres 9.4) com algo como: INSERT INTO l_tbl (l_col1, l_col2, l_col3) SELECT * FROM dblink('dbname=r_db hostaddr=r_ip password=r_pass user=r_usr', 'select r_col1, r_col2, r_col3 from r_tbl where r_col1 between ''2015-10-29'' AND ''2015-10-30'' ') AS t1(col1 MACADDR, col2 TIMESTAMP, col3 NUMERIC(7,1));(meio l local, r é remota Fuga aspas simples Fornecer tipos col...)
hamx0r

14

Use pg_dump para despejar dados da tabela e, em seguida, restaure-os com o psql.


2
Em seguida, use outra base de dados para se conectar, uma função que tenha permissões suficientes. postgresql.org/docs/8.4/static/app-pgdump.html
Frank Heikens

O que estou fazendo de errado? pg_dump -t "tablename" dbName --role "postgres"> db.sql "postgres" seria o usuário para o qual estou tentando definir a função. Ainda me dá "Acesso negado".
Nix

Você tem permissões para gravar o arquivo db.sql?
pcent 07/07

Como verifico quais permissões tenho?
Nix

Este tópico é antigo, mas para qualquer outra pessoa com o problema, tente usar o menu 'Ferramentas -> Backup' no PgAdminIII, que parece contornar os problemas de permissão.
John

13

Se você tiver o servidor remoto, poderá seguir o seguinte:

pg_dump -U Username -h DatabaseEndPoint -a -t TableToCopy SourceDatabase | psql -h DatabaseEndPoint -p portNumber -U Username -W TargetDatabase

Ele copiará a tabela mencionada do banco de dados de origem na mesma tabela nomeada do banco de dados de destino, se você já tiver um esquema existente.


9

Você pode fazer o seguinte:

pg_dump -h <host ip address> -U <host db user name> -t <host table> > <host database> | psql -h localhost -d <local database> -U <local db user>


2
gostaria de dizer algo sobre ele
Muhammad Omer Aslam

isso é legítimo 😂 você possui me
Muhammad Omer Aslam

8

Aqui está o que funcionou para mim. Primeiro despejo para um arquivo:

pg_dump -h localhost -U myuser -C -t my_table -d first_db>/tmp/table_dump

em seguida, carregue o arquivo despejado:

psql -U myuser -d second_db</tmp/table_dump

para carga de despejo também precisa "-h localhost"
DTukans

6

Para mover uma tabela do banco de dados A para o banco de dados B na sua configuração local, use o seguinte comando:

pg_dump -h localhost -U owner-name -p 5432 -C -t table-name database1 | psql -U owner-name -h localhost -p 5432 database2

Eu tentei. Isso não funciona porque você só pode fornecer a primeira senha.
máximo

1
@Max você pode fazer export PGPASSWORD=<passw>antes de executar o comando
lukaszzenko

4

Tentei algumas das soluções aqui e elas foram realmente úteis. Na minha experiência, a melhor solução é usar a linha de comando psql , mas às vezes não sinto vontade de usar a linha de comando psql. Então, aqui está outra solução para o pgAdminIII

create table table1 as(
 select t1.* 
 from dblink(
   'dbname=dbSource user=user1 password=passwordUser1',
   'select * from table1'  
  ) as t1(
    fieldName1 as bigserial,
    fieldName2 as text,
    fieldName3 as double precision 
  )
 )

O problema com esse método é que o nome dos campos e seus tipos da tabela que você deseja copiar devem ser gravados.


4

pg_dump nem sempre funciona.

Dado que você tem a mesma tabela ddl nos dois dbs, pode cortá-la do stdout e stdin da seguinte maneira:

 # grab the list of cols straight from bash

 psql -d "$src_db" -t -c \
 "SELECT column_name 
 FROM information_schema.columns 
 WHERE 1=1 
 AND table_name='"$table_to_copy"'"
 # ^^^ filter autogenerated cols if needed     

 psql -d "$src_db" -c  \
 "copy ( SELECT col_1 , col2 FROM table_to_copy) TO STDOUT" |\
 psql -d "$tgt_db" -c "\copy table_to_copy (col_1 , col2) FROM STDIN"

3

O mesmo que as respostas do usuário5542464 e Piyush S. Wanare, mas divididas em duas etapas:

pg_dump -U Username -h DatabaseEndPoint -a -t TableToCopy SourceDatabase > dump
cat dump | psql -h DatabaseEndPoint -p portNumber -U Username -W TargetDatabase

caso contrário, o canal solicita as duas senhas ao mesmo tempo.


Existe a possibilidade de eu mencionar o nome da tabela do banco de dados de destino?
Piyush S. Wanare

2

Você precisa usar o DbLink para copiar os dados de uma tabela para outra tabela no banco de dados diferente. Você precisa instalar e configurar a extensão DbLink para executar a consulta entre bancos de dados.

Eu já criei post detalhado sobre este tópico. Por favor, visite este link


2

Verifique este script python

python db_copy_table.py "host=192.168.1.1 port=5432 user=admin password=admin dbname=mydb" "host=localhost port=5432 user=admin password=admin dbname=mydb" alarmrules -w "WHERE id=19" -v
Source number of rows = 2
INSERT INTO alarmrules (id,login,notifybyemail,notifybysms) VALUES (19,'mister1',true,false);
INSERT INTO alarmrules (id,login,notifybyemail,notifybysms) VALUES (19,'mister2',true,false);

1

Se os dois DBs (de e para) estiverem protegidos por senha, nesse cenário o terminal não solicitará a senha para os dois, o prompt de senha aparecerá apenas uma vez. Portanto, para corrigir isso, passe a senha junto com os comandos.

PGPASSWORD=<password> pg_dump -h <hostIpAddress> -U <hostDbUserName> -t <hostTable> > <hostDatabase> | PGPASSWORD=<pwd> psql -h <toHostIpAddress> -d <toDatabase> -U <toDbUser>

1

Eu estava usando o DataGrip (por Intellij Idea). e foi muito fácil copiar dados de uma tabela (em um banco de dados diferente para outro).

Primeiro, verifique se você está conectado aos dois DataSources no Data Grip.

Selecione Tabela de origem e pressione F5 ou (Clique com o botão direito do mouse -> Selecionar Copiar tabela para.)

Isso mostrará uma lista de todas as tabelas (você também pode pesquisar usando um nome de tabela na janela pop-up). Basta selecionar seu alvo e pressionar OK.

O DataGrip tratará de tudo o mais para você.


2
Observe que o DataGrip não é gratuito !
Rahmat Ali 15/03

0

Se você executar o pgAdmin (Backup:, pg_dumpRestore :) pg_restoreno Windows, ele tentará gerar o arquivo por padrão para c:\Windows\System32e é por isso que você receberá o erro de Permissão / Acesso negado, e não porque o usuário postgres não está suficientemente elevado. Execute o pgAdmin como administrador ou apenas escolha um local para a saída que não seja as pastas do sistema do Windows.


0

Como alternativa, você também pode expor suas tabelas remotas como tabelas locais usando a extensão de invólucro de dados externos. Em seguida, você pode inserir suas tabelas selecionando uma das tabelas no banco de dados remoto. A única desvantagem é que não é muito rápido.

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.