从PostgreSQL数据库保存PL/pgSQL输出到CSV文件的最简单的方法是什么?

我使用PostgreSQL 8.4 pgAdmin III和PSQL插件,我从那里运行查询。


当前回答

从Postgres 12开始,你可以改变输出格式:

\pset format csv

允许使用以下格式:

aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped

如果要导出请求的结果,可以使用\o文件名特性。

例子:

\pset format csv

\o file.csv
SELECT * FROM table LIMIT 10;
\o

\pset format aligned

其他回答

我写了一个叫做psql2csv的小工具,它封装COPY查询TO STDOUT模式,生成合适的CSV。它的接口类似于psql。

psql2csv [OPTIONS] < QUERY
psql2csv [OPTIONS] QUERY

查询被假定为STDIN的内容(如果存在)或最后一个参数。所有其他参数都被转发到psql,除了以下参数:

-h, --help           show help, then exit
--encoding=ENCODING  use a different encoding than UTF8 (Excel likes LATIN1)
--no-header          do not output a header

从Postgres 12开始,你可以改变输出格式:

\pset format csv

允许使用以下格式:

aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped

如果要导出请求的结果,可以使用\o文件名特性。

例子:

\pset format csv

\o file.csv
SELECT * FROM table LIMIT 10;
\o

\pset format aligned

我尝试了几件事,但很少有人能够给我所需的CSV与头细节。

以下是对我有效的方法。

psql -d dbame -U username \
  -c "COPY ( SELECT * FROM TABLE ) TO STDOUT WITH CSV HEADER " > \
  OUTPUT_CSV_FILE.csv

应@skeller88的要求,我将我的评论作为一个答案重新发布,这样就不会被那些没有阅读每个回复的人所遗漏……

DataGrip的问题在于它控制了你的钱包。它不是免费的。在DBeaver .io上试试社区版的DBeaver。它是一个面向SQL程序员、dba和分析师的自由/开源多平台数据库工具,支持所有流行的数据库:MySQL、PostgreSQL、SQLite、Oracle、DB2、SQL Server、Sybase、MS Access、Teradata、Firebird、Hive、Presto等。

DBeaver Community Edition使得连接到数据库、发出查询以检索数据、然后下载结果集以将其保存为CSV、JSON、SQL或其他常见数据格式变得非常简单。对于Postgres的TOAD, SQL Server的TOAD,或者Oracle的TOAD,它是一个可行的自由/开源软件竞争对手。

I have no affiliation with DBeaver. I love the price and functionality, but I wish they would open up the DBeaver/Eclipse application more and made it easy to add analytics widgets to DBeaver / Eclipse, rather than requiring users to pay for the annual subscription to create graphs and charts directly within the application. My Java coding skills are rusty and I don't feel like taking weeks to relearn how to build Eclipse widgets, only to find that DBeaver has disabled the ability to add third-party widgets to the DBeaver Community Edition.

DBeaver用户是否了解如何创建要添加到社区版的分析小部件?

您希望生成的文件在服务器上还是客户机上?

服务器端

如果你想要一些易于重用或自动化的东西,你可以使用Postgresql内置的COPY命令。如。

Copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',' HEADER;

这种方法完全运行在远程服务器上-它不能写入您的本地PC。它还需要作为Postgres的“超级用户”(通常称为“root”)运行,因为Postgres无法阻止它对机器的本地文件系统做一些讨厌的事情。

这实际上并不意味着您必须以超级用户的身份连接(自动化这将是另一种安全风险),因为您可以使用CREATE FUNCTION的security DEFINER选项来创建一个像超级用户一样运行的函数。

关键的部分是你的函数要执行额外的检查,而不仅仅是绕过安全性——所以你可以编写一个函数来导出你需要的确切数据,或者你可以编写一些东西,只要它们符合严格的白名单,就可以接受各种选项。你需要检查两件事:

Which files should the user be allowed to read/write on disk? This might be a particular directory, for instance, and the filename might have to have a suitable prefix or extension. Which tables should the user be able to read/write in the database? This would normally be defined by GRANTs in the database, but the function is now running as a superuser, so tables which would normally be "out of bounds" will be fully accessible. You probably don’t want to let someone invoke your function and add rows on the end of your “users” table…

我已经写了一篇关于这种方法的博客文章,包括一些函数的例子,导出(或导入)满足严格条件的文件和表。


客户端

另一种方法是在客户端进行文件处理,即在应用程序或脚本中。Postgres服务器不需要知道你要复制到哪个文件,它只是吐出数据,然后客户端把它放在某个地方。

它的底层语法是COPY TO STDOUT命令,像pgAdmin这样的图形化工具将为您在一个漂亮的对话框中包装它。

psql命令行客户端有一个特殊的“元命令”,称为\copy,它与“真正的”copy具有相同的选项,但在客户端内部运行:

\copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',' HEADER

注意,没有终止符;,因为元命令由换行符终止,这与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数组中复制或从数组中复制,这对于大型数据集可能不太有效。