Copia una tabella da un database all'altro in Postgres


273

Sto cercando di copiare un'intera tabella da un database all'altro in Postgres. Eventuali suggerimenti?


1
Se stai bene con l'installazione di DBeaver, ha un modo davvero semplice di trasferire tra due database a cui sei connesso. Basta fare clic con il pulsante destro del mouse sulla tabella di origine e selezionare Esporta dati, scegliere come destinazione una o più tabelle di database e impostare la destinazione come database di destinazione.
Rovyko,

Risposte:


311

Estrarre la tabella e reindirizzarla direttamente al database di destinazione:

pg_dump -t table_to_copy source_db | psql target_db

Nota: se nell'altro database è già impostata la tabella, è necessario utilizzare il -aflag per importare solo i dati, altrimenti potrebbero essere visualizzati strani errori come "Memoria insufficiente":

pg_dump -a -t my_table my_db | psql target_db

5
Come funzionerà per i collegamenti db remoti? Ad esempio, devo scaricare da una posizione diversa.
Curlyreggie,

17
@curlyreggie non ha provato questo, ma non vedo alcun motivo per cui non funzionerebbe. Prova ad aggiungere specifiche dell'utente e del server al comando, in questo modopg_dump -U remote_user -h remote_server -t table_to_copy source_db | psql target_db
Thom

2
Puoi provare questo: "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
si noti che se l'altro database ha già impostato la tabella, è necessario utilizzare il -aflag solo per i dati . vale a dire pg_dump -a -t my_table my_db | psql target_db. Mentre sono qui, se il tuo database si trova su un server, trovo più facile semplicemente scaricare il database in un file e quindi scp quel file al database, quindi inviare il contenuto del file a psql. ad es. pg_dump -a -t my_table my_db > my_file.sqle dopo averlo messo sul tuo server ->psql my_other_db < my_file.sql
Nick Brady il

3
@EamonnKenny di scaricare un tavolo tra maiuscole e minuscole, fare: pg_dump -t '"tableToCopy"' source_db | psql target_db. Nota che le virgolette singole e doppie racchiudono il nome della tabella
gilad mayani

105

È inoltre possibile utilizzare la funzionalità di backup in pgAdmin II. Segui questi passaggi:

  • In pgAdmin, fai clic con il pulsante destro del mouse sulla tabella che desideri spostare, seleziona "Backup"
  • Scegli la directory per il file di output e imposta il formato su "semplice"
  • Fai clic sulla scheda "Opzioni di dumping n. 1", seleziona "Solo dati" o "Solo schema" (a seconda di ciò che stai facendo)
  • Nella sezione Query, fai clic su "Usa inserti di colonna" e "Comandi di inserimento utente".
  • Fai clic sul pulsante "Backup". Questo genera un file .backup
  • Apri questo nuovo file usando il blocco note. Vedrai gli script di inserimento necessari per la tabella / i dati. Copiarli e incollarli nella nuova pagina sql del database in pgAdmin. Esegui come pgScript - Query-> Esegui come pgScript F6

Funziona bene e può fare più tabelle alla volta.


1
Questa è una buona soluzione basata su gui per lo spostamento di dati tra database. Grazie!
kgx

3
È possibile selezionare più tabelle nella Objectssezione. Su OSX, fare clic sul pulsante SQL o ottenere SQL Editortramite il Toolsmenu per incollare l'SQL copiato dal file di backup.
Aleck Landgraf,

funziona grazie. Molto lento anche se su grandi tavoli .. c'è un modo migliore per farlo per accelerarlo? (come ignorare le chiavi straniere o qualcosa del genere?)
TimoSolo

3
@Timothy Ecco la pagina di documentazione di Postgres su come velocizzare il backup e il ripristino
laurie

vecchia risposta ma ancora pertinente, funziona benissimo, non dimenticate di impostare Disabilita i trigger quando si esporta tutto il database
norbertas.gaulia

75

Usare dblink sarebbe più 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
Perché due dbname in due volte ..? qual è la fonte e il bersaglio.
arulraj.net,

1
tableA che stiamo inserendo è la destinazione e tableA nel dbLink è l'origine.
aggietech,

se voglio usare dblink bun non conosco la struttura della tabella dei sorgenti di origine?
Ossarotte,

31

Usando psql, su host linux che hanno connettività ad entrambi i server

( 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" )

Non è necessario esportare, PGPASSWORD=password1 psql -U ...quindi non hai nemmeno bisogno di sottotitoli espliciti! Normalmente, ti consigliamo di fare un paio di cose da impostare prima, quindi le sottotitoli possono essere comunque necessarie. Inoltre, le password non verranno esportate nei processi successivi. Grazie!
Espiazione limitata il

1
@LimitedAtonement In realtà hai ragione, non è necessario esportare e subshells. Fa solo parte di uno script più complicato, e anche non ho provato senza esportazione e subshells, quindi lo fornisco come è solo per essere onesto e fornisco una soluzione funzionante
Alexey Sviridov,

La tabella deve esistere nel DB di destinazione. Per crearlo, provapg_dump -t '<table_name>' --schema-only
fjsj

24

Prima installa dblink

Quindi, faresti qualcosa del tipo:

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
Questa risposta è ottima perché consente di filtrare le righe copiate (aggiungere la clausola WHERE nel secondo argomento di dblink). Tuttavia, bisogna essere espliciti sui nomi delle colonne (Postgres 9.4) con qualcosa del tipo: 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));(l significa locale, r è remoto. Sfuggire alle virgolette singole. Fornire i tipi col.)
hamx0r

14

Utilizzare pg_dump per scaricare i dati della tabella, quindi ripristinarli con psql.


2
Quindi utilizzare un altro databaserole per connettersi, un ruolo che dispone di autorizzazioni sufficienti. postgresql.org/docs/8.4/static/app-pgdump.html
Frank Heikens

Che cosa sto facendo di sbagliato? pg_dump -t "tablename" dbName --role "postgres"> db.sql "postgres" sarebbe l'utente sul quale sto cercando di impostare il ruolo. Mi dà ancora "Accesso negato".
nix

Hai i permessi per scrivere il file db.sql?
pcent

Come posso verificare quali autorizzazioni ho?
nix

Questo thread è vecchio, ma per chiunque abbia il problema, prova a utilizzare il menu "Strumenti -> Backup" in PgAdminIII, che sembra aggirare i problemi di autorizzazione.
John,

13

Se hai entrambi i server remoti, puoi seguire questo:

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

Copia la tabella menzionata del database di origine nella stessa tabella del database di destinazione, se hai già uno schema esistente.



8

Ecco cosa ha funzionato per me. Primo dump su un file:

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

quindi caricare il file scaricato:

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

per il caricamento del dump è necessario anche "-h localhost"
DTukans

6

Per spostare una tabella dal database A al database B nella configurazione locale, utilizzare il comando seguente:

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

L'ho provato. Questo non funziona perché puoi solo assegnargli la prima password.
max

1
@max puoi fare export PGPASSWORD=<passw>prima di eseguire il comando
lukaszzenko

4

Ho provato alcune delle soluzioni qui e sono state davvero utili. Nella mia esperienza, la migliore soluzione è usare la riga di comando di psql , ma a volte non ho voglia di usare la riga di comando di psql. Quindi ecco un'altra soluzione per 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 
  )
 )

Il problema con questo metodo è che devono essere scritti il ​​nome dei campi e i loro tipi di tabella che si desidera copiare.


4

pg_dump non funziona sempre.

Dato che hai la stessa tabella ddl in entrambi i dbs puoi hackerarla da stdout e stdin come segue:

 # 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

Come le risposte dell'utente5542464 e Piyush S. Wanare, ma suddivise in due passaggi:

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

altrimenti la pipe chiede le due password contemporaneamente.


È possibile menzionare il nome della tabella del database di destinazione?
Piyush S. Wanare,

2

Devi usare DbLink per copiare i dati di una tabella in un'altra tabella in un database diverso. È necessario installare e configurare l'estensione DbLink per eseguire query tra database.

Ho già creato un post dettagliato su questo argomento. Si prega di visitare questo link


2

Controlla questo 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 entrambi i DB (da & a) sono protetti da password, in quello scenario il terminale non chiederà la password per entrambi i DB, la richiesta della password apparirà solo una volta. Quindi, per risolvere questo problema, passare la password insieme ai comandi.

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

1

Stavo usando DataGrip (di Intellij Idea). ed è stato molto semplice copiare i dati da una tabella (in un database diverso a un altro).

Innanzitutto, assicurati di essere connesso con entrambe le origini dati in Data Grip.

Selezionare la tabella di origine e premere F5 o (Fare clic con il pulsante destro del mouse -> Seleziona copia tabella in.)

Questo ti mostrerà un elenco di tutte le tabelle (puoi anche cercare usando il nome di una tabella nella finestra popup). Seleziona il tuo obiettivo e premi OK.

DataGrip gestirà tutto il resto per te.


2
Nota: DataGrip non è gratuito !
Rahmat Ali,

0

Se esegui pgAdmin (Backup:, pg_dumpRestore :) pg_restoreda Windows, proverà a inviare il file per impostazione predefinita a c:\Windows\System32ed è per questo che otterrai l'errore di autorizzazione / accesso negato e non perché l'utente postgres non è abbastanza elevato. Esegui pgAdmin come amministratore o scegli semplicemente un percorso per l'output diverso dalle cartelle di sistema di Windows.


0

In alternativa, è anche possibile esporre le tabelle remote come tabelle locali utilizzando l'estensione del wrapper di dati esterno. È quindi possibile inserire nelle tabelle selezionando dalle tabelle nel database remoto. L'unico aspetto negativo è che non è molto veloce.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.