Скопіюйте таблицю з однієї бази даних в іншу в 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
Як це буде працювати для віддалених db-посилань? Наприклад, мені потрібно скинути з іншого місця.
curlyreggie

17
@curlyreggie цього не пробував, але я не бачу причини, щоб це не вийшло. Спробуйте додати до команди специфіку користувача та сервера, як-от так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"
Хуа Чжан

18
зауважте, що якщо в іншій базі даних вже встановлена ​​таблиця, слід використовувати -aпрапор лише для даних . тобто pg_dump -a -t my_table my_db | psql target_db. Поки я тут, Якщо ваша база даних знаходиться на сервері, мені простіше просто скинути базу даних у файл, а потім прокрутити цей файл у базу даних, а потім надіслати вміст файлу до psql. наприклад, pg_dump -a -t my_table my_db > my_file.sqlі після того, як поставити це на своєму сервері ->psql my_other_db < my_file.sql
Нік Брейді,

3
@EamonnKenny скинути таблицю з урахуванням регістра, зробіть наступне : pg_dump -t '"tableToCopy"' source_db | psql target_db. Зауважте, що одиночні І подвійні лапки оточують назву таблиці
gilad mayani

105

Ви також можете використовувати функцію резервного копіювання в pgAdmin II. Просто виконайте наступні дії:

  • У pgAdmin клацніть правою кнопкою миші таблицю, яку потрібно перемістити, виберіть "Резервне копіювання"
  • Виберіть каталог для вихідного файлу та встановіть для Формат "звичайний"
  • Перейдіть на вкладку "Параметри скидання №1", поставте прапорець "Тільки дані" або "Тільки схема" (залежно від того, що ви робите)
  • У розділі "Запити" натисніть "Використовувати вставки стовпців" та "Команди вставки користувача".
  • Натисніть кнопку "Резервне копіювання". Це виводить у файл .backup
  • Відкрийте цей новий файл за допомогою блокнота. Ви побачите скрипти вставки, необхідні для таблиці / даних. Скопіюйте та вставте їх на нову сторінку sql бази даних у pgAdmin. Запустити як pgScript - Query-> Execute as pgScript F6

Працює добре і може робити кілька таблиць одночасно.


1
Це гарне рішення на основі gui для переміщення даних між базами даних. Дякую!
кгх

3
Ви можете вибрати кілька таблиць під Objectsрозділом. В OSX натисніть кнопку SQL або перейдіть SQL Editorчерез Toolsменю для вставки в SQL, скопійований з файла резервної копії.
Aleck Landgraf

працює, дякую. Дуже повільно, хоча на великих столах .. Чи є кращий спосіб зробити це, щоб пришвидшити його? (як ігнорувати іноземні ключі чи щось?)
TimoSolo

3
@Timothy Ось сторінка документації про postgres про те, як пришвидшити резервне копіювання та відновлення
laurie

стара відповідь, але все ще актуальна, працює чудово, просто не забудьте встановити відключення тригерів при експорті всієї бази даних
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, я не знаю структуру вихідної таблиці джерела?
Осаротте

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 ...тоді вам навіть не потрібні явні передплати! Зазвичай, ви хочете зробити пару речей, щоб налаштувати спочатку, тому передплатники можуть бути потрібні в будь-якому випадку. Також паролі не будуть експортовані в наступні процеси. Дякую!
Обмежене спокутування

1
@LimitedAtonement Насправді ви праві, експорт та передплати не потрібні. Це лише частина складнішого сценарію, і навіть я не пробував без експорту та
Олексій Свиридов

Таблиця повинна існувати в цільовій БД. Щоб створити його, спробуйте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). Однак потрібно чітко вказати назви стовпців (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 віддалений.
Уникнути

14

Використовуйте pg_dump для скидання даних таблиці, а потім відновіть їх за допомогою psql.


2
Потім для підключення використовуйте іншу базу даних, роль, яка має достатньо дозволів. postgresql.org/docs/8.4/static/app-pgdump.html
Френк Хейкенс

Що я роблю неправильно? pg_dump -t "ім'я таблиці" dbName --role "postgres"> db.sql "postgres" буде користувачем, якому я намагаюся встановити роль. Це все ще дає мені "Доступ заборонено".
nix

Чи є у вас дозволи на запис файлу db.sql?
пент

Як перевірити, які у мене є дозволи?
nix

Цей потік старий, але для всіх, хто має проблеми, спробуйте скористатися меню "Інструменти -> Резервне копіювання" на PgAdminIII, яке, схоже, усуне проблеми з дозволом.
Іван

13

Якщо у вас є обидва віддаленого сервера, ви можете слідувати цьому:

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

Він скопіює згадану таблицю вихідної бази даних у таку ж іменовану таблицю цільової бази даних, якщо у вас вже є існуюча схема.



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


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 С. Wanare , але розкол в два етапи:

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

інакше труба запитує два паролі одночасно.


Чи є можливість я згадати ім'я таблиці цільової бази даних?
Піюш С. Ванаре

2

Ви повинні використовувати DbLink для копіювання даних однієї таблиці в іншу таблицю в іншій базі даних. Вам потрібно встановити та налаштувати розширення DbLink для виконання запиту міжбазової бази даних.

Я вже створив детальну публікацію на цю тему. Перейдіть за цим посиланням


2

Перевірте цей сценарій python

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). і дуже просто було скопіювати дані з однієї таблиці (в іншу базу даних в іншу).

Спочатку переконайтеся, що ви пов’язані з обома джерелами даних у Data Grip.

Виберіть джерельну таблицю і натисніть F5 або (Клацніть правою кнопкою миші -> Вибрати копіювати таблицю.)

Це покаже вам список усіх таблиць (ви також можете шукати, використовуючи ім'я таблиці у спливаючому вікні). Просто виберіть ціль і натисніть OK.

DataGrip обробляє все інше за вас.


2
Зверніть увагу, DataGrip - це не безкоштовно !
Рахмат Алі

0

Якщо ви запустили pgAdmin (резервне копіювання:, pg_dumpвідновлення :) pg_restoreз Windows, він спробує вивести файл за замовчуванням до, c:\Windows\System32і саме тому ви отримаєте помилку дозволу / доступу відхилено, а не тому, що користувацькі поштові подробиці недостатньо підвищені. Запустіть pgAdmin як адміністратор або просто виберіть місце для виводу, окрім системних папок Windows.


0

Як альтернативу, ви також можете виставити віддалені таблиці як локальні таблиці, використовуючи розширення для обговорення іноземних даних. Потім можна вставити у свої таблиці, вибравши з таблиць у віддаленій базі даних. Єдиний мінус - це не дуже швидко.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.