我有一个带有多 Gb 表(其中包含某些事件的日志)的 PostgreSQL 数据库。我需要将最新事件传递给分析师 - 假设他只需要上个月的事件。
我怎样才能产生只有那些行的转储,比如说,created_at > '2012-05-01'
?
Mil*_*dev 16
另一种方法是使用COPY
或\copy
(psql
命令),例如:
COPY (SELECT * FROM big_table WHERE created_at > '2012-05-01') TO '/path/to/a/dump/file';
Run Code Online (Sandbox Code Playgroud)
gil*_*905 11
psql -c "COPY (SELECT * FROM my_table WHERE created_at > '2012-05-01') TO STDOUT;" source_db | psql -c "COPY my_table FROM STDIN;" target_db
小智 7
免责声明:逐字来自/sf/ask/106234481/
您想要在服务器上还是在客户端上的结果文件?
如果你想要一些易于重用或自动化的东西,你可以使用 Postgresql 的内置COPY命令。例如
Copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',';
Run Code Online (Sandbox Code Playgroud)
这种方法完全在远程服务器上运行——它不能写入您的本地 PC。它还需要以 Postgres“超级用户”(通常称为“root”)的身份运行,因为 Postgres 无法阻止它使用该机器的本地文件系统做令人讨厌的事情。
这实际上并不意味着您必须以超级用户身份进行连接(自动化会带来不同类型的安全风险),因为您可以使用该SECURITY DEFINER
选项CREATE FUNCTION
来创建一个像超级用户一样运行的功能。
关键部分是您的函数在那里执行额外的检查,而不仅仅是绕过安全性 - 因此您可以编写一个函数来导出您需要的确切数据,或者您可以编写一些可以接受各种选项的函数,只要它们满足严格的白名单。你需要检查两件事:
GRANT
数据库中的s定义,但该函数现在以超级用户身份运行,因此通常“越界”的表将完全可以访问。您可能不想让某人调用您的函数并在“用户”表的末尾添加行……我写了一篇扩展这种方法的博客文章,包括一些导出(或导入)满足严格条件的文件和表的函数示例。
另一种方法是在客户端进行文件处理,即在您的应用程序或脚本中。Postgres 服务器不需要知道您要复制到哪个文件,它只是吐出数据,然后客户端将其放在某处。
它的底层语法是COPY TO STDOUT
命令,像 pgAdmin 这样的图形工具会在一个漂亮的对话框中为你包装它。
在psql
命令行客户端有一个特殊的“元命令”之称\copy
,这需要所有相同的选项,“真正的” COPY
,但在运行客户端中:
\copy (Select * From foo) To '/tmp/test.csv' With CSV
Run Code Online (Sandbox Code Playgroud)
请注意,没有终止;
,因为元命令以换行符终止,与 SQL 命令不同。
从文档:
不要将 COPY 与 psql 指令 \copy 混淆。\copy 调用 COPY FROM STDIN 或 COPY TO STDOUT,然后在 psql 客户端可访问的文件中获取/存储数据。因此,当使用 \copy 时,文件可访问性和访问权限取决于客户端而不是服务器。
您的应用程序编程语言可能也支持推送或获取数据,但您通常不能在标准 SQL 语句中使用COPY FROM STDIN
/ TO STDOUT
,因为无法连接输入/输出流。PHP的PostgreSQL的处理程序(未PDO)包括非常基本的pg_copy_from
和pg_copy_to
其复制到/从一个PHP数组,这可能不是高效的大数据集的功能。
归档时间: |
|
查看次数: |
40742 次 |
最近记录: |