Skopiuj tabelę z jednej bazy danych do drugiej w Postgres


273

Próbuję skopiować całą tabelę z jednej bazy danych do innej w Postgres. Jakieś sugestie?


1
Jeśli nie masz nic przeciwko instalacji DBeavera, ma on naprawdę prosty sposób przesyłania między dwiema bazami danych, z którymi jesteś podłączony. Po prostu kliknij prawym przyciskiem myszy tabelę źródłową i wybierz Eksportuj dane, celuj w tabele bazy danych i ustaw cel jako docelową bazę danych.
rovyko

Odpowiedzi:


311

Wyodrębnij tabelę i potokuj ją bezpośrednio do docelowej bazy danych:

pg_dump -t table_to_copy source_db | psql target_db

Uwaga: jeśli inna baza danych ma już skonfigurowaną tabelę, powinieneś użyć -aflagi do importowania tylko danych, w przeciwnym razie możesz zobaczyć dziwne błędy, takie jak „Brak pamięci”:

pg_dump -a -t my_table my_db | psql target_db

5
Jak to będzie działać w przypadku łączy zdalnej bazy danych? Na przykład muszę zrzucić z innej lokalizacji.
curlyreggie

17
@ curlyreggie nie próbowałem tego, ale nie widzę powodu, dla którego to by nie działało. Spróbuj dodać użytkownika i serwera specyfiki do polecenia, tak jakpg_dump -U remote_user -h remote_server -t table_to_copy source_db | psql target_db
thomax

2
Możesz spróbować: „pg_dump -U użytkownik_zdalny -h serwer_zdalny -t tabela_do_kopii źródło_db | psql cel_db -U użytkownik_zdalny -h użytkownik_zdalny”
Hua Zhang

18
zwróć uwagę, że jeśli inna baza danych ma już skonfigurowaną tabelę, powinieneś używać -aflagi tylko do danych . tj pg_dump -a -t my_table my_db | psql target_db. Skoro już tu jestem, jeśli twoja baza danych znajduje się na serwerze, łatwiej mi po prostu zrzucić bazę danych do pliku, a następnie przesłać ten plik do bazy danych, a następnie wysłać zawartość pliku do psql. np. pg_dump -a -t my_table my_db > my_file.sqli po umieszczeniu tego na serwerze ->psql my_other_db < my_file.sql
Nick Brady

3
@EamonnKenny zrzucić tabeli wielkość liter, należy: pg_dump -t '"tableToCopy"' source_db | psql target_db. Zauważ, że pojedyncze i podwójne cudzysłowy otaczają nazwę tabeli
gilad mayani

105

Możesz także użyć funkcji tworzenia kopii zapasowych w pgAdmin II. Wystarczy wykonać następujące kroki:

  • W pgAdmin kliknij prawym przyciskiem myszy tabelę, którą chcesz przenieść, wybierz „Kopia zapasowa”
  • Wybierz katalog dla pliku wyjściowego i ustaw Format na „zwykły”
  • Kliknij kartę „Opcje zrzutu 1”, zaznacz „Tylko dane” lub „tylko schemat” (w zależności od tego, co robisz)
  • W sekcji Zapytania kliknij „Użyj wstawek kolumn” i „Polecenia wstawiania użytkownika”.
  • Kliknij przycisk „Kopia zapasowa”. Dane wyjściowe do pliku .backup
  • Otwórz ten nowy plik za pomocą notatnika. Zobaczysz skrypty wstawiania potrzebne dla tabeli / danych. Skopiuj i wklej je na nowej stronie bazy danych SQL w pgAdmin. Uruchom jako pgScript - Zapytanie-> Wykonaj jako pgScript F6

Działa dobrze i może wykonywać wiele tabel jednocześnie.


1
To dobre rozwiązanie oparte na GUI do przenoszenia danych między bazami danych. Dzięki!
kgx

3
W Objectssekcji możesz wybrać wiele tabel . W systemie OSX kliknij przycisk SQL lub skorzystaj SQL Editorz Toolsmenu, aby wkleić SQL skopiowany z pliku kopii zapasowej.
Aleck Landgraf

działa, dzięki. Ale bardzo wolno na dużych stołach .. czy jest lepszy sposób, aby to przyspieszyć? (np. zignorować klucze obce czy coś takiego?)
TimoSolo,

3
@Timothy Oto strona dokumentacja postgres na jak przyspieszyć tworzenie kopii zapasowych i przywracanie
Laurie

stara odpowiedź, ale nadal aktualna, działa świetnie, po prostu nie zapomnij ustawić Wyłącz wyzwalacze podczas eksportowania całej bazy danych
norbertas.gaulia

75

Korzystanie z dblink byłoby wygodniejsze!

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
Dlaczego dwa razy dbname dwa razy ..? który jest źródłem i celem.
arulraj.net

1
tableA, do którego wstawiamy, jest miejscem docelowym, a tableA w dbLink jest źródłem.
aggietech,

jeśli chcę użyć bunka dblink Nie znam struktury źródłowej tabeli źródłowej?
Ossarotte,

31

Za pomocą psql na hoście Linux, który ma łączność z obydwoma serwerami

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

Nie ma potrzeby eksportowania, PGPASSWORD=password1 psql -U ...więc nie potrzebujesz nawet jawnych podpowłok! Zwykle najpierw musisz zrobić kilka rzeczy, aby skonfigurować, więc podpowłoki mogą być konieczne. Ponadto hasła nie będą eksportowane do kolejnych procesów. Dzięki!
Ograniczone Zadośćuczynienie

1
@LimitedAtonement W rzeczywistości masz prawo, eksport i podpowłoki nie są konieczne. To tylko część bardziej skomplikowanego skryptu, a nawet nie próbowałem bez eksportu i podpowłoki, więc zapewniam go tak, jak powinienem być szczery i zapewniam działające rozwiązanie
Alexey Sviridov

Tabela musi istnieć w docelowej bazie danych. Aby go utworzyć, spróbujpg_dump -t '<table_name>' --schema-only
fjsj

24

Najpierw zainstaluj dblink

Następnie zrobiłbyś coś takiego:

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
Ta odpowiedź jest świetna, ponieważ pozwala filtrować skopiowane wiersze (dodaj klauzulę WHERE w drugim argumencie dblink). Jednak trzeba wyraźnie powiedzieć o nazwach kolumn (Postgres 9.4) za pomocą czegoś takiego: 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 oznacza lokalny, r jest zdalny.
Unikaj

14

Użyj pg_dump, aby zrzucić dane tabeli, a następnie przywróć je za pomocą psql.


2
Następnie użyj innej konsoli danych do połączenia, roli, która ma wystarczającą liczbę uprawnień. postgresql.org/docs/8.4/static/app-pgdump.html
Frank Heikens

Co ja robię źle? pg_dump -t "tablename" dbName --role "postgres"> db.sql "postgres" to użytkownik, dla którego próbuję ustawić rolę. Nadal daje mi komunikat „Odmowa dostępu”.
nix

Czy masz uprawnienia do zapisu pliku db.sql?
pens

Jak sprawdzić, jakie mam uprawnienia?
nix

Wątek jest stary, ale dla każdego, kto ma problem, spróbuj użyć menu „Narzędzia -> Kopia zapasowa” w PgAdminIII, który wydaje się omijać problemy z uprawnieniami.
John

13

Jeśli masz oba serwery zdalne, możesz wykonać następujące czynności:

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

Skopiuje wspomnianą tabelę źródłowej bazy danych do tej samej nazwanej tabeli docelowej bazy danych, jeśli masz już istniejący schemat.



8

Oto, co zadziałało dla mnie. Pierwszy zrzut do pliku:

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

następnie załaduj zrzut pliku:

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

do zrzutu zrzutu potrzebujemy również „-h localhost”
DTukans

6

Aby przenieść tabelę z bazy danych A do bazy danych B w konfiguracji lokalnej, użyj następującego polecenia:

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

Próbowałem tego. To nie działa, ponieważ możesz podać tylko pierwsze hasło.
maks.

1
@maks. możesz to zrobić export PGPASSWORD=<passw>przed uruchomieniem polecenia
lukaszzenko

4

Wypróbowałem tutaj niektóre rozwiązania, które były bardzo pomocne. Z mojego doświadczenia wynika, że ​​najlepszym rozwiązaniem jest użycie wiersza polecenia psql , ale czasami nie mam ochoty używać wiersza polecenia psql. Oto kolejne rozwiązanie dla 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 
  )
 )

Problem z tą metodą polega na tym, że należy wpisać nazwę pól i ich typy tabeli, którą chcesz skopiować.


4

pg_dump nie zawsze działa.

Biorąc pod uwagę, że masz ten sam ddl tabeli w obu dbs, możesz zhakować go ze stdout i stdin w następujący sposób:

 # 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

Takie same jak odpowiedzi użytkownika 5542464 i Piyush S. Wanare, ale podzielone na dwa etapy:

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

w przeciwnym razie potok poprosi o dwa hasła w tym samym czasie.


Czy istnieje możliwość, że mogę wymienić nazwę tabeli docelowej bazy danych?
Piyush S. Wanare

2

Musisz użyć DbLink, aby skopiować dane jednej tabeli do innej tabeli w innej bazie danych. Musisz zainstalować i skonfigurować rozszerzenie DbLink, aby wykonać kwerendę między bazami danych.

Stworzyłem już szczegółowy post na ten temat. Proszę odwiedzić ten link


2

Sprawdź ten skrypt Pythona

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

Jeśli obie bazy danych (od & do) są chronione hasłem, w takim scenariuszu terminal nie poprosi o hasło dla obu baz danych, monit o podanie hasła pojawi się tylko raz. Aby to naprawić, podaj hasło wraz z poleceniami.

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

1

Korzystałem z DataGrip (autor: Intellij Idea). i bardzo łatwo było skopiować dane z jednej tabeli (z innej bazy danych do innej).

Najpierw upewnij się, że masz połączenie z obydwoma źródłami danych w Data Grip.

Wybierz opcję Tabela źródłowa i naciśnij klawisz F5 lub (kliknij prawym przyciskiem myszy -> Wybierz opcję Kopiuj tabelę do.)

Spowoduje to wyświetlenie listy wszystkich tabel (możesz także wyszukiwać, używając nazwy tabeli w wyskakującym oknie). Po prostu wybierz cel i naciśnij OK.

DataGrip zajmie się wszystkim za Ciebie.


2
Uwaga: DataGrip nie jest darmowy !
Rahmat Ali

0

Jeśli uruchomisz pgAdmin (Backup:, pg_dumpRestore :) w pg_restoresystemie Windows, spróbuje on domyślnie wypisać plik c:\Windows\System32i dlatego pojawi się błąd odmowy uprawnień / dostępu, a nie dlatego, że postgres użytkownika nie jest wystarczająco podniesiony. Uruchom pgAdmin jako Administrator lub po prostu wybierz lokalizację wyjściową inną niż foldery systemowe Windows.


0

Alternatywnie możesz również udostępnić zdalne tabele jako tabele lokalne za pomocą rozszerzenia opakowania danych obcych. Następnie możesz wstawić do swoich tabel, wybierając z tabel w zdalnej bazie danych. Jedynym minusem jest to, że nie jest bardzo szybki.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.