我需要从远程 PostgreSQL 服务器复制到本地服务器。我不能使用任何 ETL 工具,必须使用 Perl 和 DBI 来完成。这个数据会很大,所以我不想使用“从源中选择”和“插入到本地”。我希望使用 COPY 创建一个文件,但是这个文件将在远程服务器上创建。我也做不到。我想改用 \COPY 。
如何使用 DBI 执行“\从远程表复制”命令并在 Perl 中使用 DBI 创建本地文件?
您可以使用 DBD::Pg 在 perl 中执行此操作,可以在此处找到详细信息:
您肯定希望使用“复制自”和“复制到”命令有效地将数据进出数据库。它们比迭代数据行快几个数量级。许多人还希望在将数据复制到目标表时关闭索引,然后在复制完成时启用它们(并让它们构建)。
假设您只是连接到两个数据库的侦听器端口,只需打开到源数据库的连接,将表复制到文件,打开到目标数据库的连接并将文件复制回目标表。
您可以使用 ~/.pgpass 并为自己保存导出 PGUSER 的东西,并将密码保留在环境之外......(从安全角度来看总是一个好主意)
唔。 \copy to ...
是一个psql
指令,而不是 SQL,因此 DBI 或另一端的 PostgreSQL 服务器不会理解它。
我看到 PostgreSQL 的 SQLCOPY
命令有FROM STDIN
和TO STDOUT
选项——但我怀疑 DBI 是否有办法执行访问结果数据所需的“原始读取”。(我确定内部TO STDOUT
是如何psql
实现\copy to ...
的。)
所以:在你的情况下,我会使用例如 samba 或 nfs 将源盒上的文件夹安装回目标盒,并使用普通的 old COPY TO '/full/path/to/mounted/folder/data.txt' ...
。
我使用 \copy (select * from remote_table) to '/local/file.txt' ... 然后 \copy local_table from '/local/file.txt' 将文件加载到本地数据库中。我从 psql 脚本执行了 \copy 命令。
这是我的脚本
导出 PGUSER=remoteuser 导出 PGPASSWORD=remotepwd
/opt/PostgreSQL/8.3/bin/psql -h xx.xx.xx -p 5432 -d remotedb -c "\COPY (select * from remote_table where date(reccreationtime e) = date((current_date - interval '4 day' ))) TO '/local/copied_from_remote.txt' D ELIMITER '|'"
导出 PGUSER=localuser 导出 PGPASSWORD=localpwd
/opt/PostgreSQL/8.3/bin/psql -h xx.xx.xx.xx -p 5432 -d localdb -c "\COPY local_table FROM '/local/copied_from_remote.txt' DELIMITER '|'"