Sao chép bảng từ cơ sở dữ liệu này sang cơ sở dữ liệu khác trong Postgres


273

Tôi đang cố gắng sao chép toàn bộ bảng từ cơ sở dữ liệu này sang cơ sở dữ liệu khác trong Postgres. Bất kỳ đề xuất?


1
Nếu bạn ổn với việc cài đặt DBeaver, nó có một cách chuyển giao thực sự đơn giản giữa hai cơ sở dữ liệu mà bạn kết nối. Chỉ cần nhấp chuột phải vào bảng nguồn và chọn Xuất dữ liệu, nhắm mục tiêu (các) bảng Cơ sở dữ liệu và đặt mục tiêu làm cơ sở dữ liệu đích.
rovyko

Câu trả lời:


310

Trích xuất bảng và dẫn nó trực tiếp đến cơ sở dữ liệu đích:

pg_dump -t table_to_copy source_db | psql target_db

Lưu ý: Nếu cơ sở dữ liệu khác đã có bảng được thiết lập, bạn chỉ nên sử dụng -acờ để nhập dữ liệu, nếu không bạn có thể thấy các lỗi lạ như "Hết bộ nhớ":

pg_dump -a -t my_table my_db | psql target_db

5
Làm thế nào điều này sẽ làm việc cho các liên kết db từ xa? Ví dụ, tôi cần phải đổ từ một vị trí khác.
curreggie

17
@curlyreggie chưa thử cái này, nhưng tôi không hiểu lý do tại sao nó không hoạt động. Hãy thử thêm thông tin cụ thể của người dùng và máy chủ vào lệnh, như vậypg_dump -U remote_user -h remote_server -t table_to_copy source_db | psql target_db
thomax

2
Bạn có thể thử điều này: "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
lưu ý rằng nếu cơ sở dữ liệu khác đã có bảng được thiết lập, bạn chỉ nên sử dụng -acờ cho dữ liệu . tức pg_dump -a -t my_table my_db | psql target_db. Khi tôi ở đây, Nếu cơ sở dữ liệu của bạn ở trên một máy chủ, tôi thấy việc chuyển cơ sở dữ liệu vào một tệp và sau đó quét tệp đó vào cơ sở dữ liệu, sau đó gửi nội dung của tệp tới psql. ví dụ pg_dump -a -t my_table my_db > my_file.sqlvà sau khi đưa nó lên máy chủ của bạn ->psql my_other_db < my_file.sql
Nick Brady

3
@EamonnKenny để đổ một bảng phân biệt chữ hoa chữ thường, làm : pg_dump -t '"tableToCopy"' source_db | psql target_db. Lưu ý rằng dấu ngoặc đơn VÀ kép bao quanh tên bảng
gilad mayani

105

Bạn cũng có thể sử dụng chức năng sao lưu trong pgAdmin II. Chỉ cần làm theo các bước sau:

  • Trong pgAdmin, nhấp chuột phải vào bảng bạn muốn di chuyển, chọn "Sao lưu"
  • Chọn thư mục cho tệp đầu ra và đặt Định dạng thành "đơn giản"
  • Nhấp vào tab "Tùy chọn kết xuất số 1", chọn "Chỉ dữ liệu" hoặc "Chỉ lược đồ" (tùy thuộc vào những gì bạn đang làm)
  • Trong phần Truy vấn, nhấp vào "Sử dụng Chèn cột" và "Lệnh chèn người dùng".
  • Nhấp vào nút "Sao lưu". Điều này xuất ra tệp .backup
  • Mở tập tin mới này bằng notepad. Bạn sẽ thấy các tập lệnh chèn cần thiết cho bảng / dữ liệu. Sao chép và dán chúng vào trang sql cơ sở dữ liệu mới trong pgAdmin. Chạy dưới dạng pgScript - Truy vấn-> Thực thi dưới dạng pgScript F6

Hoạt động tốt và có thể làm nhiều bảng cùng một lúc.


1
Đây là một giải pháp dựa trên gui tốt để di chuyển dữ liệu giữa các cơ sở dữ liệu. Cảm ơn!
kgx

3
Bạn có thể chọn nhiều bảng dưới Objectsphần. Trên OSX, nhấp vào nút SQL hoặc lấy SQL Editorthông qua Toolsmenu để dán vào SQL được sao chép từ tệp sao lưu.
Aleck Landgraf

làm việc, cảm ơn. Rất chậm mặc dù trên các bàn lớn .. có cách nào tốt hơn để tăng tốc không? (như bỏ qua khóa ngoại hoặc cái gì đó?)
TimoSolo

3
@Timothy Đây là trang tài liệu postgres về cách tăng tốc sao lưu và khôi phục
laurie

câu trả lời cũ nhưng vẫn có liên quan, hoạt động rất tốt, chỉ cần đừng quên thiết lập Tắt kích hoạt khi xuất tất cả cơ sở dữ liệu
norbertas.gaulia

75

Sử dụng dblink sẽ thuận tiện hơn!

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
Tại sao hai dbname trong hai lần ..? cái nào là nguồn và đích.?
arulraj.net

1
bảngA mà chúng ta đang chèn là đích và bảngA trong dbLink là nguồn.
aggietech

Nếu tôi muốn sử dụng dblink bun, tôi không biết cấu trúc của bảng nguồn?
Ossarotte

31

Sử dụng psql, trên máy chủ linux có kết nối với cả hai máy chủ

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

Không cần xuất, PGPASSWORD=password1 psql -U ...sau đó bạn thậm chí không cần subshells rõ ràng! Thông thường, bạn sẽ muốn thực hiện một vài điều cần thiết lập trước tiên, vì vậy dù sao đi nữa, có thể cần phải có các lớp con. Ngoài ra, mật khẩu sẽ không được xuất sang các quy trình tiếp theo. Cảm ơn!
Chuộc tội có giới hạn

1
@LrictAtonement Thật ra bạn đúng, xuất và subshells là không cần thiết. Nó chỉ là một phần của kịch bản phức tạp hơn, và thậm chí tôi đã không thử mà không xuất và chia nhỏ, vì vậy, tôi cung cấp nó như là chỉ thành thật và cung cấp giải pháp hiệu quả
Alexey Sviridov

Bảng phải tồn tại trong DB đích. Để tạo nó, hãy thửpg_dump -t '<table_name>' --schema-only
fjsj

24

Đầu tiên cài đặt dblink

Sau đó, bạn sẽ làm một cái gì đó như:

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
Câu trả lời này rất hay vì nó cho phép một người lọc các hàng đã sao chép (thêm mệnh đề WHERE trong đối số thứ 2 của dblink). Tuy nhiên, người ta cần phải rõ ràng về tên cột (Postgres 9.4) với một cái gì đó như: 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 có nghĩa là địa phương, r là từ xa. Thoát dấu ngoặc đơn. Cung cấp các loại col.)
hamx0r

14

Sử dụng pg_dump để kết xuất dữ liệu bảng, sau đó khôi phục nó bằng psql.


2
Sau đó sử dụng một databaserole khác để kết nối, một vai trò có đủ quyền. postgresql.org/docs/8.4/static/app-pgdump.html
Frank Heikens

Tôi đang làm gì sai? pg_dump -t "tablename" dbName --role "postgres"> db.sql "postgres" sẽ là người dùng tôi đang cố gắng đặt vai trò. Nó vẫn cho tôi "Truy cập bị từ chối".
nix

Bạn có quyền ghi tệp db.sql không?
pent

Làm cách nào để kiểm tra những quyền tôi có?
nix

Chủ đề này đã cũ, nhưng đối với bất kỳ ai khác gặp sự cố, hãy thử sử dụng menu 'Công cụ -> Sao lưu' trong PGAdminIII, có vẻ như giải quyết được các vấn đề về quyền.
Giăng

13

Nếu bạn có cả máy chủ từ xa thì bạn có thể làm theo điều này:

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

Nó sẽ sao chép bảng Cơ sở dữ liệu nguồn được đề cập vào cùng bảng được đặt tên của cơ sở dữ liệu đích, nếu bạn đã có lược đồ hiện có.


9

Bạn có thể làm như sau:

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
bạn có muốn nói điều gì về nó không
Muhammad Omer Aslam

đó là hợp pháp bạn sở hữu tôi
Muhammad Omer Aslam

8

Đây là những gì làm việc cho tôi. Đầu tiên đổ vào một tập tin:

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

sau đó tải tập tin kết xuất:

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

đối với tải bãi cũng cần "-h localhost"
DTukans

6

Để di chuyển bảng từ cơ sở dữ liệu A sang cơ sở dữ liệu B tại thiết lập cục bộ của bạn, hãy sử dụng lệnh sau:

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

Tôi đã thử nó. Điều này không hoạt động vì bạn chỉ có thể cung cấp cho nó mật khẩu đầu tiên.
tối đa

1
@max bạn có thể làm export PGPASSWORD=<passw>trước khi chạy lệnh
lukaszzenko

4

Tôi đã thử một số giải pháp ở đây và chúng thực sự hữu ích. Theo kinh nghiệm của tôi, giải pháp tốt nhất là sử dụng dòng lệnh psql , nhưng đôi khi tôi không cảm thấy thích sử dụng dòng lệnh psql. Vì vậy, đây là một giải pháp khác cho 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 
  )
 )

Vấn đề với phương pháp này là tên của các trường và loại bảng mà bạn muốn sao chép phải được viết.


4

pg_dump không hoạt động luôn.

Cho rằng bạn có cùng một bảng ddl trong cả hai dbs, bạn có thể hack nó từ thiết bị xuất chuẩn và stdin như sau:

 # 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

Giống như câu trả lời của người dùng5542464Piyush S. Wanare nhưng được chia thành hai bước:

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

nếu không thì đường ống hỏi hai mật khẩu cùng một lúc.


Có khả năng tôi có thể đề cập đến tên bảng của cơ sở dữ liệu đích không?
Piyush S. Wanare

2

Bạn phải sử dụng DbLink để sao chép một dữ liệu bảng vào một bảng khác tại cơ sở dữ liệu khác nhau. Bạn phải cài đặt và định cấu hình tiện ích mở rộng DbLink để thực hiện truy vấn cơ sở dữ liệu chéo.

Tôi đã tạo ra bài viết chi tiết về chủ đề này. Vui lòng truy cập liên kết này


2

Kiểm tra kịch bản python này

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

Nếu cả hai DB (từ & đến) được bảo vệ bằng mật khẩu, trong thiết bị đầu cuối kịch bản đó sẽ không yêu cầu mật khẩu cho cả hai DB, lời nhắc mật khẩu sẽ chỉ xuất hiện một lần. Vì vậy, để khắc phục điều này, hãy chuyển mật khẩu cùng với các lệnh.

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

1

Tôi đã sử dụng DataGrip (Theo Intellij Idea). và nó rất dễ dàng sao chép dữ liệu từ một bảng (trong cơ sở dữ liệu khác nhau sang bảng khác).

Trước tiên, hãy đảm bảo bạn được kết nối với cả DataSource trong Data Grip.

Chọn Bảng nguồn và nhấn F5 hoặc (Nhấp chuột phải -> Chọn Sao chép bảng vào.)

Điều này sẽ hiển thị cho bạn một danh sách tất cả các bảng (bạn cũng có thể tìm kiếm bằng tên bảng trong cửa sổ bật lên). Chỉ cần chọn mục tiêu của bạn và nhấn OK.

DataGrip sẽ xử lý mọi thứ khác cho bạn.


2
Xin lưu ý, DataGrip không miễn phí !
Rahmat Ali

0

Nếu bạn chạy pgAdmin (Sao lưu:, pg_dumpKhôi phục pg_restore:) từ Windows, nó sẽ cố gắng xuất tệp theo mặc định c:\Windows\System32và đó là lý do tại sao bạn sẽ gặp phải lỗi từ chối Quyền truy cập / Quyền truy cập và không phải vì độ trễ của người dùng không đủ cao. Chạy pgAdmin với tư cách Quản trị viên hoặc chỉ chọn một vị trí cho đầu ra không phải là thư mục hệ thống của Windows.


0

Thay vào đó, bạn cũng có thể hiển thị các bảng từ xa của mình dưới dạng các bảng cục bộ bằng cách sử dụng tiện ích mở rộng trình bao bọc dữ liệu nước ngoài. Sau đó, bạn có thể chèn vào các bảng của mình bằng cách chọn từ các bảng trong cơ sở dữ liệu từ xa. Nhược điểm duy nhất là nó không quá nhanh.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.