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?

nix
fonte
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
thomax
fonte
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.

a2ron44
fonte
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);
tinychen
fonte
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" )
Alexey Sviridov
fonte
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 
);
Felipe Augusto
fonte
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.

Pablo Santa Cruz
fonte
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.

Piyush S. Wanare
fonte
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>

Gowtham Balusamy
fonte
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
max
fonte
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
user5542464
fonte
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.

Eloy A
fonte
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"
Yordan Georgiev
fonte
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.

Adobe
fonte
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

Anvesh
fonte
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);
themadmax
fonte
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>
Dante
fonte
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ê.

Developine
fonte
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.

Imre
fonte
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.

ThatDataGuy
fonte