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