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

Posted

技术标签:

【中文标题】在 Postgres 中将表从一个数据库复制到另一个数据库【英文标题】:Copy a table from one database to another in Postgres 【发布时间】:2011-03-12 19:52:25 【问题描述】:

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

【问题讨论】:

如果您可以安装 DBeaver,它有一种非常简单的方法可以在您连接的两个数据库之间进行传输。只需右键单击源表并选择导出数据,定位数据库表并将目标设置为目标数据库。 【参考方案1】:

您可以通过两个简单的步骤

# dump the database in custom-format archive
pg_dump -Fc mydb > db.dump

# restore the database
pg_restore -d newdb db.dump

如果是远程数据库

# dump the database in custom-format archive
pg_dump -U mydb_user -h mydb_host -t table_name -Fc mydb > db.dump

# restore the database
pg_restore -U newdb_user -h newdb_host -d newdb db.dump

【讨论】:

【参考方案2】:

提取表并将其直接通过管道传输到目标数据库:

pg_dump -t table_to_copy source_db | psql target_db

注意:如果其他数据库已经建立了表,你应该使用-a标志只导入数据,否则你可能会看到像“内存不足”这样的奇怪错误:

pg_dump -a -t table_to_copy source_db | psql target_db

【讨论】:

这将如何用于远程数据库链接?例如,我需要从不同的位置转储。 @curlyreggie 没有尝试过这个,但我看不出它为什么不起作用。尝试将用户和服务器细节添加到命令中,例如 pg_dump -U remote_user -h remote_server -t table_to_copy source_db | psql target_db 你可以试试这个:“pg_dump -U remote_user -h remote_server -t table_to_copy source_db | psql target_db -U remote_user -h remote_server” 请注意,如果其他数据库已经设置了表,您应该为 data only 使用-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 @EamonnKenny 转储一个区分大小写的表,执行:pg_dump -t '"tableToCopy"' source_db | psql target_db。请注意,单引号和双引号将表名括起来【参考方案3】:

对于DBeaver tool 用户,您可以“导出数据”到另一个数据库中的表。

我一直面临的唯一错误是因为wrong postgres driver。

SQL Error [34000]: ERROR: portal "c_2" does not exist
    ERROR: Invalid protocol sequence 'P' while in PortalSuspended state.

这是一个关于如何导出数据的官方 wiki:https://github.com/dbeaver/dbeaver/wiki/Data-transfer

【讨论】:

【参考方案4】:

使用dblink会更方便!

truncate table tableA;

insert into tableA
select *
from dblink('hostaddr=xxx.xxx.xxx.xxx dbname=mydb user=postgres',
            'select a,b from tableA')
       as t1(a text,b text);

【讨论】:

为什么两个 dbname 在两次..?哪一个是源和目标? 我们插入的tableA是目标,dbLink中的tableA是源。 如果我要使用dblink bun我不知道源源表的结构? @Ossarotte 嘿,你找到问题的答案了吗?【参考方案5】:

我使用的是 DataGrip(由 Intellij Idea 提供)。并且很容易将数据从一个表(在不同的数据库中复制到另一个)。

首先,确保您已连接到 Data Grip 中的两个数据源。

选择源表并按 F5 或(右键单击 -> 选择将表复制到。)

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

DataGrip 将为您处理所有其他事情。

【讨论】:

请注意,DataGrip 不是免费的! 此功能也是 IntelliJ Ultimate 的一部分(也不是免费的),但很多人可能已经拥有。【参考方案6】:

在连接到两台服务器的 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!通常,您首先需要做几件事来设置,因此无论如何可能需要子shell。此外,密码不会导出到后续进程中。谢谢! @LimitedAtonement 实际上你是对的,export 和 subshel​​ls 不是必需的。它只是更复杂脚本的一部分,即使我没有尝试没有导出和子shell,所以,我提供它只是为了诚实并提供有效的解决方案 该表必须存在于目标数据库中。要创建它,请尝试pg_dump -t '<table_name>' --schema-only 将密码输入~/.pgpass【参考方案7】:

作为替代方案,您还可以使用外部数据包装器扩展将远程表公开为本地表。然后,您可以通过从远程数据库中的表中进行选择来插入表中。唯一的缺点是速度不是很快。

【讨论】:

【参考方案8】:

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

【讨论】:

【参考方案9】:

第一install 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 
);

【讨论】:

这个答案很棒,因为它允许过滤复制的行(在 dblink 第二个参数中添加 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 类型。)【参考方案10】:

pg_dump 并不总是有效。

鉴于您在两个数据库中都有相同的表 ddl 您可以按如下方式从标准输出和标准输入破解它:

 # 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"

【讨论】:

【参考方案11】:

要在本地设置中将表从数据库 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

【讨论】:

我试过了。这不起作用,因为您只能给它第一个密码。 @max 你可以在运行命令之前执行export PGPASSWORD=<passw>【参考方案12】:

如果两个 DB(from & to) 都受密码保护,在这种情况下终端不会询问两个 DB 的密码,密码提示只会出现一次。 因此,要解决此问题,请将密码与命令一起传递。

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

【讨论】:

【参考方案13】:

您可以执行以下操作:

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>

【讨论】:

你能不能说点什么 那是合法的?你拥有我【参考方案14】:

查看python script

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);

【讨论】:

【参考方案15】:

这对我有用。 首先转储到文件:

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”【参考方案16】:

与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

否则管道会同时询问两个密码。

【讨论】:

我可以提及目标数据库的表名吗?【参考方案17】:

如果你有两个远程服务器,那么你可以按照这个:

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

如果您已经有现有的模式,它将把提到的源数据库表复制到目标数据库的同名表中。

【讨论】:

【参考方案18】:

我在这里尝试了一些解决方案,它们真的很有帮助。根据我的经验,最好的解决方案是使用 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 
  )
 )

这种方法的问题是,你要复制的表的字段名和类型必须要写。

【讨论】:

【参考方案19】:

您必须使用 DbLink 将一个表数据复制到不同数据库的另一个表中。 您必须安装和配置 DbLink 扩展才能执行跨数据库查询。

我已经创建了关于这个主题的详细帖子。 Please visit this link

【讨论】:

【参考方案20】:

您还可以使用 pgAdmin II 中的备份功能。只需按照以下步骤操作:

在 pgAdmin 中,右键单击要移动的表,选择“备份” 选择输出文件的目录并将格式设置为“普通” 点击“Dump Options #1”选项卡,选中“Only data”或“only Schema”(取决于您在做什么) 在“查询”部分下,单击“使用列插入”和“用户插入命令”。 单击“备份”按钮。这将输出到 .backup 文件 使用记事本打开这个新文件。您将看到表/数据所需的插入脚本。将这些复制并粘贴到 pgAdmin 中的新数据库 sql 页面中。作为 pgScript 运行 - 查询->作为 pgScript F6 执行

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

【讨论】:

这是一个很好的基于 gui 的解决方案,用于在数据库之间移动数据。谢谢! 您可以在Objects 部分下选择多个表。在 OSX 上,单击 SQL 按钮或通过Tools 菜单获取SQL Editor 以粘贴从备份文件复制的 SQL。 有效,谢谢。虽然在大桌子上非常慢..有没有更好的方法来加快速度? (比如忽略外键什么的?) @Timothy 这是the postgres documentation page,了解如何加快备份和恢复速度 旧答案但仍然相关,效果很好,只是不要忘记在导出所有数据库时设置禁用触发器【参考方案21】:

使用 pg_dump 转储表数据,然后使用 psql 恢复。

【讨论】:

然后使用另外一个databaserole连接,这个角色有足够的权限。 postgresql.org/docs/8.4/static/app-pgdump.html 我做错了什么? pg_dump -t "tablename" dbName --role "postgres" > db.sql "postgres" 将是我试图将角色设置为的用户。它仍然给我“访问被拒绝”。 你有权限写db.sql文件吗? 如何查看我有哪些权限? 不是一个真正有用的答案,因为其他答案向您展示了如何使用 pg_dump

以上是关于在 Postgres 中将表从一个数据库复制到另一个数据库的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL Server 中将表从一个数据库复制到另一个数据库

如何在同一个表中将数据从一列复制到另一列?

将表从 Postgres RDS 迁移到另一个 RDS

Postgres 创建触发器函数以在允许插入之前将值从一列复制到另一列

在同一个表中将值从一列复制到另一列

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