คัดลอกตารางจากฐานข้อมูลหนึ่งไปยังอีกใน Postgres


273

ฉันพยายามที่จะคัดลอกตารางทั้งหมดจากฐานข้อมูลหนึ่งไปยังอีกใน Postgres ข้อเสนอแนะใด ๆ


1
หากคุณโอเคกับการติดตั้ง DBeaver มันมีวิธีการถ่ายโอนระหว่างสองฐานข้อมูลที่คุณเชื่อมต่อ เพียงคลิกขวาที่ตารางต้นฉบับและเลือกส่งออกข้อมูลกำหนดเป้าหมายไปยังตารางฐานข้อมูลแล้วตั้งค่าเป้าหมายเป็นฐานข้อมูลปลายทาง
rovyko

คำตอบ:


311

แยกตารางและไพพ์ไปยังฐานข้อมูลเป้าหมายโดยตรง:

pg_dump -t table_to_copy source_db | psql target_db

หมายเหตุ:หากฐานข้อมูลอื่นมีตารางติดตั้งอยู่แล้วคุณควรใช้-aแฟล็กเพื่อนำเข้าข้อมูลเท่านั้นมิฉะนั้นคุณอาจเห็นข้อผิดพลาดแปลก ๆ เช่น "หน่วยความจำไม่เพียงพอ":

pg_dump -a -t my_table my_db | psql target_db

5
สิ่งนี้จะทำงานกับลิงก์ระยะไกล -BB ได้อย่างไร เช่นฉันต้องการถ่ายโอนข้อมูลจากที่อื่น
curlyreggie

17
@curlyreggie hav ไม่ได้ลองสิ่งนี้ แต่ฉันเห็นเหตุผลว่าทำไมมันไม่ทำงาน ลองเพิ่มผู้ใช้และเซิร์ฟเวอร์เฉพาะให้กับคำสั่งเช่นpg_dump -U remote_user -h remote_server -t table_to_copy source_db | psql target_db
thomax

2
คุณสามารถลองนี้: "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
ทราบว่าถ้าฐานข้อมูลอื่น ๆ แล้วได้ตารางการตั้งค่าที่คุณควรใช้-aธงสำหรับข้อมูลเท่านั้น pg_dump -a -t my_table my_db | psql target_dbกล่าวคือ ขณะที่ฉันอยู่ที่นี่หากฐานข้อมูลของคุณอยู่บนเซิร์ฟเวอร์ฉันพบว่าง่ายกว่าที่จะถ่ายโอนฐานข้อมูลไปยังไฟล์แล้ว scp ไฟล์นั้นไปยังฐานข้อมูลจากนั้นส่งเนื้อหาของไฟล์ไปยัง psql เช่นpg_dump -a -t my_table my_db > my_file.sqlและหลังจากวางลงบนเซิร์ฟเวอร์ของคุณ ->psql my_other_db < my_file.sql
Nick Brady

3
@EamonnKenny การถ่ายโอนข้อมูลตารางเป็นกรณี ๆ pg_dump -t '"tableToCopy"' source_db | psql target_dbไปทำ: โปรดทราบว่าคำพูดเดี่ยวและคู่ล้อมรอบชื่อตาราง
gilad mayani

105

คุณยังสามารถใช้ฟังก์ชันการสำรองข้อมูลใน pgAdmin II เพียงทำตามขั้นตอนเหล่านี้:

  • ใน pgAdmin คลิกขวาที่ตารางที่คุณต้องการย้ายเลือก "สำรองข้อมูล"
  • เลือกไดเร็กทอรีสำหรับไฟล์เอาต์พุตและตั้งค่า Format เป็น "plain"
  • คลิกแท็บ "Dump Options # 1" ตรวจสอบ "Only data" หรือ "only Schema" (ขึ้นอยู่กับสิ่งที่คุณกำลังทำ)
  • ใต้ส่วนแบบสอบถามให้คลิก "ใช้การแทรกคอลัมน์" และ "คำสั่งแทรกผู้ใช้"
  • คลิกปุ่ม "สำรองข้อมูล" เอาต์พุตนี้เป็นไฟล์. backup
  • เปิดไฟล์ใหม่นี้โดยใช้ Notepad คุณจะเห็นสคริปต์แทรกที่จำเป็นสำหรับตาราง / ข้อมูล คัดลอกและวางสิ่งเหล่านี้ลงในหน้า sql ฐานข้อมูลใหม่ใน pgAdmin เรียกใช้เป็น pgScript - Query-> ดำเนินการเป็น pgScript F6

ทำงานได้ดีและสามารถทำหลาย ๆ ตารางในเวลาเดียวกัน


1
นี่เป็นโซลูชั่น gui ที่ดีสำหรับการย้ายข้อมูลระหว่างฐานข้อมูล ขอบคุณ!
kgx

3
คุณสามารถเลือกหลายตารางภายใต้Objectsส่วน บน OSX คลิกปุ่ม SQL หรือรับSQL Editorผ่านทางToolsเมนูเพื่อวางลงใน SQL ที่คัดลอกมาจากไฟล์สำรอง
Aleck Landgraf

ได้ผลขอบคุณ ช้ามากแม้ว่าบนโต๊ะขนาดใหญ่ .. มีวิธีที่ดีกว่าในการเพิ่มความเร็วหรือไม่ (เช่นเพิกเฉยต่อกุญแจต่างประเทศหรืออะไร?)
TimoSolo

3
@Timothy นี่คือหน้าเอกสารประกอบ postgresเกี่ยวกับวิธีการเพิ่มความเร็วในการสำรองและกู้คืน
ลอรี

คำตอบเก่า แต่ยังมีความเกี่ยวข้องใช้งานได้ดีอย่าลืมตั้งค่าปิดการใช้งานทริกเกอร์เมื่อส่งออกฐานข้อมูลทั้งหมด
norbertas.gaulia

75

การใช้dblinkจะสะดวกกว่า!

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
ทำไมสอง dbname ในสองครั้ง .. อันไหนคือแหล่งที่มาและเป้าหมาย?
arulraj.net

1
tableA ที่เรากำลังแทรกเข้าไปคือปลายทางและ tableA ใน dbLink คือแหล่งที่มา
aggietech

ถ้าฉันต้องการใช้ dblink bun ฉันไม่ทราบโครงสร้างของตารางที่มา?
Ossarotte

31

ใช้ psql บนโฮสต์ linux ที่มีการเชื่อมต่อกับเซิร์ฟเวอร์ทั้งสอง

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

ไม่จำเป็นต้องส่งออก PGPASSWORD=password1 psql -U ...จากนั้นคุณไม่จำเป็นต้องมี subshells ชัดเจนอีกด้วย! โดยปกติคุณจะต้องทำสองสิ่งเพื่อตั้งค่าก่อนดังนั้นจึงจำเป็นต้องมี subshells นอกจากนี้รหัสผ่านจะไม่ถูกส่งออกไปยังกระบวนการที่ตามมา ขอบคุณ!
การชดเชย จำกัด

1
@LimitedAtonement จริงๆแล้วคุณไม่จำเป็นต้องส่งออกและ subshells มันเป็นเพียงส่วนหนึ่งของสคริปต์ที่ซับซ้อนยิ่งขึ้นและแม้ว่าฉันจะไม่ได้ลองโดยไม่มีการส่งออกและ subshells ดังนั้นฉันจึงให้มันเป็นเพียงความซื่อสัตย์และให้วิธีแก้ปัญหาการทำงาน
Alexey Sviridov

ตารางจะต้องมีอยู่ในฐานข้อมูลปลายทาง เพื่อสร้างมันลองpg_dump -t '<table_name>' --schema-only
fjsj

24

ขั้นแรกให้ติดตั้ง dblink

จากนั้นคุณจะทำสิ่งที่ชอบ:

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
คำตอบนี้ยอดเยี่ยมเพราะอนุญาตให้หนึ่งตัวกรองแถวที่คัดลอก (เพิ่มส่วนคำสั่ง WHERE ในอาร์กิวเมนต์ dblink 2nd) แต่หนึ่งในความต้องการที่จะมีความชัดเจนเกี่ยวกับชื่อคอลัมน์ (Postgres 9.4) กับสิ่งที่ต้องการ: 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 หมายถึงท้องถิ่น r คือระยะไกลหนีราคาเดียวให้บริการประเภทพ...)
hamx0r

14

ใช้ pg_dump เพื่อดัมพ์ข้อมูลตารางจากนั้นกู้คืนด้วย psql


2
จากนั้นใช้ databaserole อื่นเพื่อเชื่อมต่อซึ่งเป็นบทบาทที่มีสิทธิ์เพียงพอ postgresql.org/docs/8.4/static/app-pgdump.html
Frank Heikens

ผมทำอะไรผิดหรือเปล่า? pg_dump -t "tablename" dbName --role "postgres"> db.sql "postgres" จะเป็นผู้ใช้ที่ฉันพยายามกำหนดบทบาทให้ มันยังให้ฉัน "การเข้าถึงถูกปฏิเสธ"
ห้าม

คุณมีสิทธิ์เขียนไฟล์ db.sql หรือไม่
ร้อยละ

ฉันจะตรวจสอบสิทธิ์ที่ฉันมีได้อย่างไร
ห้าม

เธรดนี้เก่า แต่สำหรับใครที่มีปัญหาลองใช้เมนู 'เครื่องมือ -> สำรองข้อมูล' ใน PgAdminIII ซึ่งดูเหมือนว่าจะมีปัญหาเกี่ยวกับการอนุญาต
จอห์น

13

หากคุณมีเซิร์ฟเวอร์ระยะไกลทั้งคู่คุณสามารถทำตามสิ่งนี้:

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

มันจะคัดลอกตารางดังกล่าวของฐานข้อมูลต้นทางลงในตารางชื่อเดียวกันของฐานข้อมูลเป้าหมายหากคุณมีสคีมาอยู่แล้ว


9

คุณสามารถทำสิ่งต่อไปนี้:

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
คุณต้องการที่จะพูดอะไรเกี่ยวกับมัน
Muhammad Omer Aslam

ถูกต้องแล้วคุณเป็นเจ้าของฉัน
Muhammad Omer Aslam

8

นี่คือสิ่งที่ใช้ได้ผลสำหรับฉัน ดัมพ์แรกไปยังไฟล์:

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

จากนั้นโหลดไฟล์ที่ดัมพ์:

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

สำหรับการถ่ายโอนข้อมูลต้องมี "-h localhost" ด้วยเช่นกัน
DTukans

6

หากต้องการย้ายตารางจากฐานข้อมูล A ไปยังฐานข้อมูล B ที่การตั้งค่าท้องถิ่นของคุณให้ใช้คำสั่งต่อไปนี้:

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

ฉันลองแล้ว สิ่งนี้ไม่ทำงานเนื่องจากคุณสามารถให้รหัสผ่านแรกได้เท่านั้น
สูงสุด

1
@ max คุณสามารถทำได้export PGPASSWORD=<passw>ก่อนรันคำสั่ง
lukaszzenko

4

ฉันลองวิธีแก้ปัญหาบางอย่างที่นี่และพวกเขามีประโยชน์จริง ๆ ในประสบการณ์ของฉันทางออกที่ดีที่สุดคือการใช้บรรทัดคำสั่งpsqlแต่บางครั้งฉันไม่รู้สึกอยากใช้คำสั่ง psql ดังนั้นนี่คือทางออกอื่นสำหรับ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 
  )
 )

ปัญหาของวิธีนี้คือต้องเขียนชื่อของเขตข้อมูลและประเภทของตารางที่คุณต้องการคัดลอก


4

pg_dump ไม่ทำงานเสมอ

ระบุว่าคุณมีตาราง ddl เดียวกันใน dbs ทั้งสองคุณสามารถแฮ็กมันจาก stdout และ stdin ดังนี้:

 # 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

เหมือนกับคำตอบโดยuser5542464และPiyush S. Wanareแต่แยกออกเป็นสองขั้นตอน:

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

มิฉะนั้นไพพ์จะถามรหัสผ่านสองตัวในเวลาเดียวกัน


มีความเป็นไปได้ไหมที่ฉันสามารถพูดถึงชื่อตารางของฐานข้อมูลเป้าหมายได้
Piyush S. Wanare

2

คุณต้องใช้ DbLink เพื่อคัดลอกข้อมูลหนึ่งตารางไปยังตารางอื่นที่ฐานข้อมูลที่แตกต่างกัน คุณต้องติดตั้งและกำหนดค่าส่วนขยาย DbLink เพื่อดำเนินการค้นหาข้ามฐานข้อมูล

ฉันได้สร้างโพสต์โดยละเอียดในหัวข้อนี้แล้ว กรุณาเยี่ยมชมลิงค์นี้


2

ตรวจสอบสคริปต์หลามนี้

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

หากฐานข้อมูลทั้งสอง (จาก & ถึง) ได้รับการป้องกันด้วยรหัสผ่านในเทอร์มินัลสถานการณ์จำลองจะไม่ถามรหัสผ่านสำหรับทั้งสองฐานข้อมูลการแจ้งเตือนรหัสผ่านจะปรากฏเพียงครั้งเดียว ดังนั้นเพื่อแก้ไขปัญหานี้ให้ส่งรหัสผ่านพร้อมกับคำสั่ง

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

1

ฉันใช้DataGrip (โดย Intellij Idea) และมันเป็นเรื่องง่ายมากที่จะคัดลอกข้อมูลจากตารางหนึ่ง (ในฐานข้อมูลที่แตกต่างไปยังอีก)

ก่อนอื่นตรวจสอบให้แน่ใจว่าคุณเชื่อมต่อกับแหล่งข้อมูลทั้งสองใน Data Grip แล้ว

เลือก Source Table แล้วกด F5 หรือ (คลิกขวา -> เลือก Copy Table to)

นี่จะแสดงรายการของตารางทั้งหมด (คุณสามารถค้นหาโดยใช้ชื่อตารางในหน้าต่างป๊อปอัป) เพียงเลือกเป้าหมายของคุณแล้วกดตกลง

DataGrip จะจัดการทุกอย่างให้คุณ


2
โปรดทราบว่า DataGrip นั้นไม่ฟรี !
Rahmat Ali

0

หากคุณเรียกใช้ pgAdmin (Backup:, pg_dumpRestore:) pg_restoreจาก Windows ระบบจะพยายามส่งออกไฟล์เป็นค่าเริ่มต้นc:\Windows\System32และนั่นคือสาเหตุที่คุณจะได้รับการอนุญาต / ปฏิเสธการเข้าถึงข้อผิดพลาดและไม่ใช่เพราะผู้ใช้ postgres ยกระดับไม่เพียงพอ รันpgAdminในฐานะผู้ดูแลระบบหรือเพียงแค่เลือกตำแหน่งสำหรับเอาต์พุตอื่นที่ไม่ใช่โฟลเดอร์ระบบของ Windows


0

นอกจากนี้คุณยังสามารถแสดงตารางระยะไกลของคุณเป็นตารางท้องถิ่นโดยใช้ส่วนขยายของ wrapper ข้อมูลต่างประเทศ จากนั้นคุณสามารถแทรกลงในตารางของคุณโดยเลือกจากตารางในฐานข้อมูลระยะไกล ข้อเสียเพียงอย่างเดียวคือมันไม่เร็วมาก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.