2010-06-15 31 views
34

Tôi cần chuyển một số dữ liệu từ cơ sở dữ liệu khác. Cơ sở dữ liệu cũ được gọi là paw1.moviesDB và cơ sở dữ liệu mới là paw1. Giản đồ của mỗi bảng là như sau.Chuyển dữ liệu giữa các cơ sở dữ liệu với PostgreSQL

Awards (name of the table)(new DB) 
Id [PK] Serial   Award 

Nominations (name of the table) (old DB) 
Id [PK] Serial   nominations 

Làm cách nào để sao chép dữ liệu từ cơ sở dữ liệu cũ sang cơ sở dữ liệu mới?

Trả lời

30

Cơ sở dữ liệu được phân lập trong PostgreSQL; khi bạn kết nối với một máy chủ PostgreSQL bạn kết nối với một cơ sở dữ liệu, bạn không thể sao chép dữ liệu từ cơ sở dữ liệu này sang cơ sở dữ liệu khác bằng một truy vấn SQL.

Nếu bạn đến từ MySQL: MySQL gì gọi (lỏng lẻo) "cơ sở dữ liệu" là "schemas" trong PostgreSQL - loại không gian tên. Cơ sở dữ liệu PostgreSQL có thể có nhiều lược đồ, mỗi lược đồ có các bảng và khung nhìn của nó, và bạn có thể sao chép từ lược đồ này sang lược đồ khác với cú pháp schema.table.

Nếu bạn thực sự có hai cơ sở dữ liệu PostgreSQL riêng biệt, cách truyền dữ liệu từ nhau sang khác là xuất bảng (với pg_dump -t) sang tệp và nhập chúng vào cơ sở dữ liệu khác (với psql).

Nếu bạn thực sự cần lấy dữ liệu từ cơ sở dữ liệu PostgreSQL riêng biệt, một tùy chọn khác - được đề cập trong câu trả lời của Grant Johnson - là dblink, là mô-đun bổ sung (trong contrib/).

+0

Setting biến search_path sử dụng "SET search_path TO blah" là một cách hay để làm việc với các lược đồ khác nhau mà không làm tổn thương các pinkies của bạn.Bạn có thể thực hiện thay đổi của bạn vĩnh viễn với "ALTER USER user SET search_path TO blah" - thích nó! ;-) –

+1

Thực hiện di chuyển bằng cách sử dụng dblink, xem http://stackoverflow.com/questions/14797327/copy-data-between-two-tables-in-postgresql-using-dblink-sql –

0

Giống như leonbloy được đề xuất, sử dụng hai lược đồ trong cơ sở dữ liệu là cách để thực hiện. Giả sử một nguồn schema (cũ DB) và một mục tiêu schema (DB mới), bạn có thể thử một cái gì đó như thế này (bạn nên xem xét tên cột, các loại, vv):

INSERT INTO target.Awards SELECT * FROM source.Nominations; 
+1

Nếu bạn có phiên bản gần đây của Postgres (> = 8.1), bạn có thể thực hiện các mệnh đề 'ALTER TABLE SET SCHEMA target' – b0fh

+0

Các lược đồ không là gì ngoài các không gian tên và chúng không thực sự cung cấp sự cô lập. Một cơ sở dữ liệu khác có thể chạy trên một máy tính khác hoặc có thể giống nhau nhưng với các thiết lập bộ nhớ/hiệu năng khác nhau và bạn có thể có hai cơ sở dữ liệu có cùng lược đồ (mà chúng ta có). Một cơ sở dữ liệu khác thậm chí có thể là một phiên bản khác của Postgres, giả sử chúng tương thích. – sudo

8

Có ba tùy chọn cho việc sao chép nó nếu điều này là một trong những off:

  1. Sử dụng một db_link (tôi nghĩ rằng nó vẫn còn trong contrib)
  2. có ứng dụng làm việc.
  3. xuất khẩu/nhập khẩu

Nếu đây là một nhu cầu đang diễn ra, câu trả lời là:

  1. Thay đổi để schemas trong cùng DB
  2. db_link
57

Tôi chỉ phải làm điều này chính xác vì vậy tôi figured tôi đăng các công thức ở đây. Điều này giả định rằng cả hai cơ sở dữ liệu trên cùng một máy chủ.

Đầu tiên, sao chép bảng từ db cũ sang db mới (vì dường như bạn không thể di chuyển dữ liệu giữa các cơ sở dữ liệu). Tại dòng lệnh:

pg_dump -U postgres -t <old_table> <old_database> | psql -U postgres -d <new_database> 

Tiếp theo, cấp quyền sao chép cho người dùng cơ sở dữ liệu mới.Đăng nhập vào psql:

psql -U postgres -d <new_database> 

ALTER TABLE <old_table> OWNER TO <new_user>; 

\q 

Cuối cùng, sao chép dữ liệu từ bảng cũ sang bảng mới. Đăng nhập với tư cách là người dùng mới và sau đó:

INSERT INTO <new_table> (field1, field2, field3) 
SELECT field1, field2, field3 from <old_table>; 

Xong!

+3

làm thế nào để làm điều đó cho máy chủ từ xa? –

+1

@DevR, chỉ cần thêm -h rdo

6

Từ: hxxp: //dbaspot.c om/postgresql/348.627-pg_dump-t-cho-nơi-condition.html (Chú ý: liên kết với doanh nghiệp được chia)

# create tmp db with the data 
psql mydb 
CREATE TABLE temp1 (LIKE mytable); 
INSERT INTO temp1 SELECT * FROM mytable WHERE myconditions; 
\q 

# export the data 
pg_dump --data-only --column-inserts -t temp1 mtdb > out.sql 
psql mydb 
DROP TABLE temp1; 
\q 

# import temp1 somewhere 
cat out.sql | psql -d [other_db] 
psql other_db 
INSERT INTO mytable (SELECT * FROM temp1); 
DROP TABLE temp1; 

Phương pháp khác hữu ích trong việc điều khiển từ xa

psql-remote> COPY elements TO '/tmp/elements.csv' DELIMITER ',' CSV HEADER; 
    $ scp host.com:/tmp/elements.csv /tmp/elements.csv 
    psql-local> COPY elements FROM '/tmp/elements.csv' DELIMITER ',' CSV; 
+1

Cảm ơn. Đây là giải pháp đơn giản nhất không liên quan đến bất kỳ tiện ích mở rộng nào. Lưu ý rằng '--column-inserts' đáng kể làm chậm nó xuống, vì vậy bạn có thể loại bỏ điều đó nếu bảng của cơ sở dữ liệu đích được biết là không có bất kỳ xung đột nào. – sudo

+1

Trong trường hợp điều này là không rõ ràng cho bất cứ ai, nửa thứ hai là: Tạo bảng trên DB khác: 'psql -d [other_db] -c" TẠO TABLE temp1 (LIKE mytable); "', sau đó chèn vào DB khác của bạn : 'cat out.sql | psql -d [other_db] ', sau đó chèn vào bảng chính:' psql -d [other_db] -c "INSERT INTO mytable (SELECT * FROM temp1);" '. – sudo

17

này đã làm việc cho tôi để sao chép một bảng điều khiển từ xa từ localhost của tôi để postgresql Heroku của:

pg_dump -C -t source_table -h localhost source_db | psql -h destination_host -U destination_user -p destination_port destination_db

Điều này tạo bảng cho bạn.

Đối với một hướng khác (từ Heroku đến địa phương) pg_dump -C -t source_table -h source_host -U source_user -p source_port source_db | psql -h localhost destination_db

+0

Trong trường hợp bạn có cổng và tên người dùng khác nhau trong localhost, lệnh này là: pg_dump -C -t source_table -h localhost -p local_port -U local_user source_db | psql -h destination_host -U destination_user -p destination_port destination_db – Fil

0

Bạn không thể thực hiện một truy vấn chéo cơ sở dữ liệu như SQL Server; PostgreSQL không hỗ trợ điều này.

Phần mở rộng DbLink của PostgreSQL được sử dụng để kết nối cơ sở dữ liệu với cơ sở dữ liệu khác. Bạn đã cài đặt và cấu hình DbLink để thực hiện truy vấn chéo cơ sở dữ liệu.

Tôi đã tạo một kịch bản từng bước và ví dụ để thực hiện truy vấn cơ sở dữ liệu chéo trong PostgreSQL. Vui lòng truy cập vào bài đăng này : PostgreSQL [Video]: Cross Database Queries using the DbLink Extension

0

Thực tế, có khả năng gửi dữ liệu bảng từ cơ sở dữ liệu PostgreSQL này sang cơ sở dữ liệu khác. Tôi sử dụng ngôn ngữ thủ tục plperlu (ngôn ngữ thủ tục Perl không an toàn) cho nó.

Mô tả (tất cả đã được thực hiện trên máy chủ Linux):

  1. Tạo ngôn ngữ plperlu trong cơ sở dữ liệu của bạn Một

  2. Sau đó, PostgreSQL có thể tham gia một số module Perl qua hàng loạt các lệnh sau ở cuối của postgresql.conf cho cơ sở dữ liệu A:

    plperl.on_init='use DBI;' 
    plperl.on_init='use DBD::Pg;' 
    
  3. Bạn xây dựng một hàm trong một như thế này:

    CREATE OR REPLACE FUNCTION send_data(VARCHAR) 
    RETURNS character varying AS 
    $BODY$ 
    my $command = $_[0] || die 'No SQL command!'; 
    my $connection_string = 
    "dbi:Pg:dbname=your_dbase;host=192.168.1.2;port=5432;"; 
    $dbh = DBI->connect($connection_string,'user','pass', 
    {AutoCommit=>0,RaiseError=>1,PrintError=>1,pg_enable_utf8=>1,} 
    ); 
    my $sql = $dbh-> prepare($command); 
    eval { $sql-> execute() }; 
    my $error = $dbh-> state; 
    $sql-> finish; 
    if ($error) { $dbh-> rollback() } else { $dbh-> commit() } 
    $dbh-> disconnect(); 
    $BODY$ 
    LANGUAGE plperlu VOLATILE; 
    

Và sau đó bạn có thể gọi hàm bên trong cơ sở dữ liệu A:

SELECT send_data('INSERT INTO jm (jm) VALUES (''zzzzzz'')'); 

Và giá trị "zzzzzz" sẽ được bổ sung vào bảng "jm" trong cơ sở dữ liệu B.

Các vấn đề liên quan