在 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 和 subshells 不是必需的。它只是更复杂脚本的一部分,即使我没有尝试没有导出和子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 中将表从一个数据库复制到另一个数据库