Kopieren Sie eine Tabelle in Postgres von einer Datenbank in eine andere


273

Ich versuche, eine ganze Tabelle in Postgres von einer Datenbank in eine andere zu kopieren. Irgendwelche Vorschläge?


1
Wenn Sie mit der Installation von DBeaver einverstanden sind, können Sie ganz einfach zwischen zwei Datenbanken übertragen, mit denen Sie verbunden sind. Klicken Sie einfach mit der rechten Maustaste auf die Quelltabelle und wählen Sie Daten exportieren, zielen Sie auf eine oder mehrere Datenbanktabellen und legen Sie das Ziel als Zieldatenbank fest.
Rovyko

Antworten:


310

Extrahieren Sie die Tabelle und leiten Sie sie direkt an die Zieldatenbank weiter:

pg_dump -t table_to_copy source_db | psql target_db

Hinweis: Wenn in der anderen Datenbank die Tabelle bereits eingerichtet ist, sollten Sie das -aFlag nur zum Importieren von Daten verwenden. Andernfalls werden möglicherweise seltsame Fehler wie "Nicht genügend Speicher" angezeigt:

pg_dump -a -t my_table my_db | psql target_db

5
Wie funktioniert dies für Remote-DB-Verbindungen? ZB muss ich von einem anderen Ort aus entsorgen.
Curlyreggie

17
@ Curlyreggie hat das nicht versucht, aber ich sehe keinen Grund, warum es nicht funktionieren würde. Versuchen Sie , Benutzer- und Server Besonderheiten auf den Befehl, wie sopg_dump -U remote_user -h remote_server -t table_to_copy source_db | psql target_db
Thomax

2
Sie können dies versuchen: "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
Beachten Sie, dass Sie das -aFlag nur für Daten verwenden sollten, wenn in der anderen Datenbank die Tabelle bereits eingerichtet ist . dh pg_dump -a -t my_table my_db | psql target_db. Während ich hier bin: Wenn sich Ihre Datenbank auf einem Server befindet, fällt es mir leichter, die Datenbank einfach in eine Datei zu kopieren und diese Datei dann in die Datenbank zu scp und dann den Inhalt der Datei an psql zu senden. zB pg_dump -a -t my_table my_db > my_file.sqlund nachdem Sie das auf Ihren Server gestellt haben ->psql my_other_db < my_file.sql
Nick Brady

3
@EamonnKenny, um eine Tabelle mit Groß- und Kleinschreibung zu löschen, gehen Sie wie folgt vor : pg_dump -t '"tableToCopy"' source_db | psql target_db. Beachten Sie, dass einfache und doppelte Anführungszeichen den Tabellennamen umgeben
Gilad Mayani

105

Sie können die Sicherungsfunktion auch in pgAdmin II verwenden. Befolgen Sie einfach diese Schritte:

  • Klicken Sie in pgAdmin mit der rechten Maustaste auf die Tabelle, die Sie verschieben möchten, und wählen Sie "Backup".
  • Wählen Sie das Verzeichnis für die Ausgabedatei und setzen Sie Format auf "normal".
  • Klicken Sie auf die Registerkarte "Dump-Optionen Nr. 1" und aktivieren Sie "Nur Daten" oder "Nur Schema" (je nachdem, was Sie tun).
  • Klicken Sie im Abschnitt "Abfragen" auf "Spalteneinfügungen verwenden" und "Befehle zum Einfügen von Benutzern".
  • Klicken Sie auf die Schaltfläche "Backup". Dies wird in eine Backup-Datei ausgegeben
  • Öffnen Sie diese neue Datei mit dem Editor. Sie sehen die Einfügeskripte, die für die Tabelle / Daten benötigt werden. Kopieren Sie diese und fügen Sie sie in die neue Datenbank-SQL-Seite in pgAdmin ein. Als pgScript ausführen - Abfrage-> Als pgScript ausführen F6

Funktioniert gut und kann mehrere Tabellen gleichzeitig erstellen.


1
Dies ist eine gute GUI-basierte Lösung zum Verschieben von Daten zwischen Datenbanken. Vielen Dank!
kgx

3
Sie können mehrere Tabellen unter dem ObjectsAbschnitt auswählen . Klicken Sie unter OSX auf die Schaltfläche SQL oder rufen Sie SQL Editorüber das ToolsMenü das aus der Sicherungsdatei kopierte SQL ein.
Aleck Landgraf

funktioniert, danke. Auf großen Tischen allerdings sehr langsam. Gibt es eine bessere Möglichkeit, dies zu beschleunigen? (wie Fremdschlüssel ignorieren oder so?)
TimoSolo

3
@ Timothy Hier ist die Postgres-Dokumentationsseite, wie man das Sichern und Wiederherstellen
beschleunigt

alte Antwort, aber immer noch relevant, funktioniert hervorragend, vergessen Sie jedoch nicht, die Auslöser für das
Deaktivieren

75

Die Verwendung von dblink wäre bequemer!

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
Warum zwei Datenbanknamen in zwei Mal ..? Welches ist Quelle und Ziel?
Arulraj.net

1
tableA, in die wir einfügen, ist das Ziel, und tableA im dbLink ist die Quelle.
Aggietech

Wenn ich dblink bun verwenden möchte, kenne ich die Struktur der Quellquellentabelle nicht?
Ossarotte

31

Verwenden von psql auf einem Linux-Host, der mit beiden Servern verbunden ist

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

Kein Export erforderlich, PGPASSWORD=password1 psql -U ...dann brauchen Sie nicht einmal explizite Subshells! Normalerweise sollten Sie zuerst ein paar Dinge tun, um sie einzurichten, sodass möglicherweise ohnehin Unterschalen erforderlich sind. Außerdem werden die Passwörter nicht in nachfolgende Prozesse exportiert. Vielen Dank!
Begrenzte Versöhnung

1
@LimitedAtonement Eigentlich haben Sie Recht, Export und Subshells sind nicht erforderlich. Es ist nur ein Teil eines komplizierteren Skripts, und selbst ich habe es nicht ohne Export und Subshells versucht, also biete ich es so an, wie es nur ist, um ehrlich zu sein und eine funktionierende Lösung bereitzustellen
Alexey Sviridov

Die Tabelle muss in der Ziel-DB vorhanden sein. Um es zu erstellen, versuchen Siepg_dump -t '<table_name>' --schema-only
fjsj

24

Zuerst installieren dblink

Dann würden Sie so etwas tun wie:

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
Diese Antwort ist großartig, da man kopierte Zeilen filtern kann (füge die WHERE-Klausel im zweiten Argument von dblink hinzu). Es muss jedoch explizit über Spaltennamen (Postgres 9.4) gesprochen werden mit: 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 bedeutet lokal, r ist remote. Escape einfache Anführungszeichen. Geben Sie Col-Typen an.)
hamx0r

14

Verwenden Sie pg_dump, um Tabellendaten zu sichern und sie dann mit psql wiederherzustellen.


2
Verwenden Sie dann eine andere Datenbankeinheit, um eine Verbindung herzustellen, eine Rolle, die über genügend Berechtigungen verfügt. postgresql.org/docs/8.4/static/app-pgdump.html
Frank Heikens

Was mache ich falsch? pg_dump -t "Tabellenname" dbName - Rolle "postgres"> db.sql "postgres" ist der Benutzer, auf den ich die Rolle festlegen möchte. Es gibt mir immer noch "Zugriff verweigert".
Nix

Haben Sie die Berechtigung, die Datei db.sql zu schreiben?
Cent

Wie überprüfe ich, welche Berechtigungen ich habe?
nix

Dieser Thread ist alt, aber für alle anderen, die das Problem haben, versuchen Sie, das Menü 'Extras -> Sichern' in PgAdminIII zu verwenden, um die Berechtigungsprobleme zu umgehen.
John

13

Wenn Sie beide Remote-Server haben, können Sie folgende Schritte ausführen:

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

Die erwähnte Tabelle der Quelldatenbank wird in die gleichnamige Tabelle der Zieldatenbank kopiert, sofern bereits ein Schema vorhanden ist.



8

Hier ist, was für mich funktioniert hat. Erster Speicherauszug in eine Datei:

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

Laden Sie dann die abgelegte Datei:

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

Für die Dump-Ladung benötigen Sie auch "-h localhost"
DTukans

6

Verwenden Sie den folgenden Befehl, um eine Tabelle in Ihrem lokalen Setup von Datenbank A in Datenbank B zu verschieben:

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

Ich versuchte es. Dies funktioniert nicht, da Sie ihm nur das erste Passwort geben können.
Max

1
@max können Sie tun, export PGPASSWORD=<passw>bevor Sie den Befehl
ausführen

4

Ich habe einige der Lösungen hier ausprobiert und sie waren wirklich hilfreich. Nach meiner Erfahrung ist die beste Lösung die Verwendung der psql- Befehlszeile, aber manchmal habe ich keine Lust, die psql-Befehlszeile zu verwenden. Hier ist eine andere Lösung für 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 
  )
 )

Das Problem bei dieser Methode ist, dass der Name der Felder und ihre Typen der Tabelle, die Sie kopieren möchten, geschrieben werden müssen.


4

pg_dump funktioniert nicht immer.

Vorausgesetzt, Sie haben dieselbe Tabelle ddl in beiden dbs, können Sie sie wie folgt von stdout und stdin hacken:

 # 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

Entspricht den Antworten von user5542464 und Piyush S. Wanare, ist jedoch in zwei Schritte unterteilt:

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

Andernfalls werden die beiden Passwörter gleichzeitig von der Pipe abgefragt.


Gibt es die Möglichkeit, dass ich den Tabellennamen der Zieldatenbank erwähnen kann?
Piyush S. Wanare

2

Sie müssen DbLink verwenden, um Tabellendaten in eine andere Tabelle in einer anderen Datenbank zu kopieren. Sie müssen die DbLink-Erweiterung installieren und konfigurieren, um eine datenbankübergreifende Abfrage auszuführen.

Ich habe bereits einen ausführlichen Beitrag zu diesem Thema erstellt. Bitte besuchen Sie diesen Link


2

Überprüfen Sie dieses Python-Skript

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

Wenn beide DBs (von & bis) kennwortgeschützt sind, fragt das Terminal in diesem Szenario nicht nach dem Kennwort für beide DBs. Die Kennwortabfrage wird nur einmal angezeigt. Um dies zu beheben, übergeben Sie das Kennwort zusammen mit den Befehlen.

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

1

Ich habe DataGrip (von Intellij Idea) verwendet. und es war sehr einfach, Daten von einer Tabelle (in einer anderen Datenbank in eine andere) zu kopieren.

Stellen Sie zunächst sicher, dass Sie mit beiden DataSources in Data Grip verbunden sind.

Wählen Sie Quelltabelle und drücken Sie F5 oder (Klicken Sie mit der rechten Maustaste -> Wählen Sie Tabelle kopieren nach.)

Dies zeigt Ihnen eine Liste aller Tabellen (Sie können auch mit einem Tabellennamen im Popup-Fenster suchen). Wählen Sie einfach Ihr Ziel aus und drücken Sie OK.

DataGrip erledigt alles andere für Sie.


2
Bitte beachten Sie, dass DataGrip nicht kostenlos ist !
Rahmat Ali

0

Wenn Sie pgAdmin (Backup : pg_dump, Restore :) pg_restoreunter Windows ausführen , wird versucht, die Datei standardmäßig an auszugeben. Aus c:\Windows\System32diesem Grund wird der Fehler "Berechtigung / Zugriff verweigert" angezeigt, und nicht, weil der Benutzer postgres nicht ausreichend erhöht ist. Führen Sie pgAdmin als Administrator aus oder wählen Sie einen anderen Speicherort für die Ausgabe als die Systemordner von Windows.


0

Alternativ können Sie Ihre Remote-Tabellen auch als lokale Tabellen mit der Erweiterung für fremde Daten-Wrapper verfügbar machen. Sie können dann in Ihre Tabellen einfügen, indem Sie aus den Tabellen in der entfernten Datenbank auswählen. Der einzige Nachteil ist, dass es nicht sehr schnell ist.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.