将表从一个数据库复制到Postgres中的另一个数据库


273

我正在尝试将整个表从一个数据库复制到Postgres中的另一个数据库。有什么建议?


1
如果您可以安装DBeaver,那么它有一种非常简单的方式在您连接的两个数据库之间进行传输。只需右键单击源表,然后选择“导出数据”,将数据库表作为目标并将目标设置为目标数据库。
罗维科

Answers:


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
对于远程数据库链接,这将如何工作?例如,我需要从其他位置转储。
curlreggie 2014年

17
@curlyreggie尚未尝试过此操作,但我认为没有任何理由不起作用。尝试将用户和服务器的详细信息添加到命令中,如下所示pg_dump -U remote_user -h remote_server -t table_to_copy source_db | psql target_db
thomax 2014年

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中,右键单击要移动的表,选择“备份”
  • 选择输出文件的目录并将“格式”设置为“普通”
  • 单击“转储选项#1”选项卡,选中“仅数据”或“仅模式”(取决于您的操作)
  • 在“查询”部分下,单击“使用列插入”和“用户插入命令”。
  • 点击“备份”按钮。这将输出到.backup文件
  • 使用记事本打开此新文件。您将看到表/数据所需的插入脚本。将它们复制并粘贴到pgAdmin中的新数据库sql页面中。以pgScript身份运行-查询->以pgScript F6执行

效果很好,一次可以处理多个表。


1
这是一个很好的基于GUI的解决方案,用于在数据库之间移动数据。谢谢!
kgx

3
您可以在该Objects部分下选择多个表。在OSX上,单击SQL按钮或SQL Editor通过Tools菜单获取通过以粘贴从备份文件复制的SQL。
Aleck Landgraf 2013年

工作,谢谢。虽然在大桌子上非常慢..是否有更好的方法来加快速度?(例如忽略外键之类的东西?)
TimoSolo 2013年

3
@Timothy这里的Postgres的文档页面上如何加快备份和恢复
劳里

旧的答案,但仍然有意义,效果很好,只是在导出所有数据库时别忘了设置“禁用触发器”
norbertas.gaulia 2015年

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 2014年

1
我们要插入的tableA是目标,而dbLink中的tableA是源。
aggietech

如果我想使用dblink bun,我不知道源源表的结构?
奥萨罗特(Ossarotte)

31

在与两个服务器都有连接的Linux主机上使用psql

( 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 ...那么您甚至不需要显式的子外壳!通常,您需要先做几件事,所以无论如何都需要子shell。另外,密码不会导出到后续进程中。谢谢!
限量赎罪

1
@LimitedAtonement实际上,您没错,不需要导出和subshel​​l。它只是更复杂的脚本的一部分,甚至我也没有尝试没有导出和子shell,因此,我提供它只是为了诚实并提供
可行的

该表必须存在于目标数据库中。要创建它,请尝试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
这个答案很好,因为它允许过滤复制的行(在dblink 2nd参数中添加WHERE子句)。但是,需要使用类似以下内容的列名称(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是远程。转义单引号。提供col类型。)
hamx0r

14

使用pg_dump转储表数据,然后使用psql还原它。


2
然后使用另一个具有足够权限的角色连接数据库角色。postgresql.org/docs/8.4/static/app-pgdump.html
Frank Heikens 2010年

我究竟做错了什么?pg_dump -t“表名” dbName-角色“ postgres”> db.sql“ postgres”是我要设置角色的用户。它仍然给我“访问被拒绝”。
nix 2010年

您是否具有写db.sql文件的权限?
2010年

如何检查我拥有哪些权限?
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相同,则可以从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

user5542464Piyush 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 '18

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中的两个DataSource。

选择源表,然后按F5或(右键单击->选择“将表复制到”。)

这将显示所有表的列表(您也可以在弹出窗口中使用表名进行搜索)。只需选择目标,然后按确定即可。

DataGrip将为您处理其他一切。


2
请注意,DataGrip 不是免费的
拉赫玛特·阿里

0

如果您从Windows 运行pgAdmin(备份:pg_dump,还原:),pg_restore它将默认尝试将文件输出到c:\Windows\System32,这就是为什么您会得到“权限/访问被拒绝”错误的原因,而不是因为用户postgres的权限不够高。以管理员身份运行pgAdmin或仅选择输出的位置,而不是Windows的系统文件夹。


0

或者,您也可以使用外部数据包装扩展名将远程表公开为本地表。然后,可以通过从远程数据库中的表中进行选择,将其插入表中。唯一的缺点是速度不是很快。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.