从PostgreSQL数据库保存PL/pgSQL输出到CSV文件的最简单的方法是什么?
我使用PostgreSQL 8.4 pgAdmin III和PSQL插件,我从那里运行查询。
从PostgreSQL数据库保存PL/pgSQL输出到CSV文件的最简单的方法是什么?
我使用PostgreSQL 8.4 pgAdmin III和PSQL插件,我从那里运行查询。
当前回答
新版本- psql 12 -将支持——csv。
PSQL - devel ——csv 切换到CSV(逗号分隔值)输出模式。这相当于\pset格式的csv。 csv_fieldsep 指定在CSV输出格式中使用的字段分隔符。如果分隔符出现在字段的值中,该字段将以双引号输出,遵循标准CSV规则。默认值是逗号。
用法:
psql -c "SELECT * FROM pg_catalog.pg_tables" --csv postgres
psql -c "SELECT * FROM pg_catalog.pg_tables" --csv -P csv_fieldsep='^' postgres
psql -c "SELECT * FROM pg_catalog.pg_tables" --csv postgres > output.csv
其他回答
您希望生成的文件在服务器上还是客户机上?
服务器端
如果你想要一些易于重用或自动化的东西,你可以使用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数组中复制或从数组中复制,这对于大型数据集可能不太有效。
如果您对特定表的所有列以及标题感兴趣,则可以使用
COPY table TO '/some_destdir/mycsv.csv' WITH CSV HEADER;
这稍微简单一点
COPY (SELECT * FROM table) TO '/some_destdir/mycsv.csv' WITH CSV HEADER;
据我所知,两者是等价的。
新版本- psql 12 -将支持——csv。
PSQL - devel ——csv 切换到CSV(逗号分隔值)输出模式。这相当于\pset格式的csv。 csv_fieldsep 指定在CSV输出格式中使用的字段分隔符。如果分隔符出现在字段的值中,该字段将以双引号输出,遵循标准CSV规则。默认值是逗号。
用法:
psql -c "SELECT * FROM pg_catalog.pg_tables" --csv postgres
psql -c "SELECT * FROM pg_catalog.pg_tables" --csv -P csv_fieldsep='^' postgres
psql -c "SELECT * FROM pg_catalog.pg_tables" --csv postgres > output.csv
我写了一个叫做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