Скопировать таблицу из одной базы данных в другую в Postgres


273

Я пытаюсь скопировать всю таблицу из одной базы данных в другую в Postgres. Какие-либо предложения?


1
Если вы согласны с установкой DBeaver, у него есть действительно простой способ переноса между двумя базами данных, к которым вы подключены. Просто щелкните правой кнопкой мыши исходную таблицу и выберите «Экспортировать данные», выберите целевую таблицу (таблицы) и установите целевой объект в качестве целевой базы данных.
Ровико

Ответы:


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
Как это будет работать для удаленных ссылок в БД? Например, мне нужно сбросить из другого места.
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-> Выполнить как pgScript F6

Хорошо работает и может делать несколько таблиц одновременно.


1
Это хорошее решение на основе графического интерфейса для перемещения данных между базами данных. Спасибо!
kgx

3
Вы можете выбрать несколько таблиц в Objectsразделе. На OSX, нажмите кнопку SQL или получить с SQL Editorпомощью Toolsвставить в SQL скопированный из файла резервной копии меню.
Алек Ландграф

работает, спасибо. Очень медленно, хотя на больших столах ... есть ли лучший способ сделать это, чтобы ускорить это? (как игнорировать внешние ключи или что-то?)
TimoSolo

3
@Timothy Вот страница документации postgres о том, как ускорить резервное копирование и восстановление
Лори

старый ответ, но все еще актуален, отлично работает, только не забудьте установить триггеры Disable при экспорте всей базы данных
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
Почему два имени в два раза ..? какой из них является источником и целью.
arulraj.net

1
Таблица A, в которую мы вставляем, является пунктом назначения, а таблица A в 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 ...тогда вам даже не нужны явные субоболочки! Обычно вам нужно сначала выполнить несколько действий для настройки, поэтому в любом случае могут потребоваться вспомогательные оболочки. Кроме того, пароли не будут экспортированы в последующие процессы. Спасибо!
Ограниченное искупление

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 означает local, r удаленно. Избегайте одинарных кавычек. Предоставляйте типы
столбцов

14

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


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

Что я делаю не так? pg_dump -t "tablename" 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

для загрузки дампа также нужен "-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

в противном случае канал запрашивает два пароля одновременно.


Есть ли возможность, что я могу упомянуть имя таблицы целевой базы данных?
Пиюш С. Ванаре

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 Idea). и было очень легко копировать данные из одной таблицы (из другой базы данных в другую).

Во-первых, убедитесь, что вы подключены к обоим источникам данных в Data Grip.

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

Это покажет вам список всех таблиц (вы также можете искать, используя имя таблицы во всплывающем окне). Просто выберите цель и нажмите ОК.

DataGrip позаботится обо всем остальном за вас.


2
Обратите внимание, что DataGrip не является бесплатным !
Рахмат Али

0

Если вы запустите pgAdmin (Backup:, pg_dumpRestore :) pg_restoreиз Windows, он попытается вывести файл по умолчанию, c:\Windows\System32и именно поэтому вы получите ошибку «Разрешение / доступ запрещен», а не потому, что пользователь postgres недостаточно повышен. Запустите pgAdmin от имени администратора или просто выберите место для вывода, отличное от системных папок Windows.


0

В качестве альтернативы вы также можете представить свои удаленные таблицы в качестве локальных таблиц, используя расширение для сторонних данных. Затем вы можете вставить в свои таблицы, выбрав из таблиц в удаленной базе данных. Единственным недостатком является то, что это не очень быстро.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.