将PostgreSQL的PL / pgSQL输出保存为CSV文件

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

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

你想在服务器上,还是在客户端上产生的文件?

服务器端

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

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

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

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

关键的一点是,你的函数是在那里执行额外的检查,而不仅仅是绕过安全 – 所以你可以写一个函数,导出你需要的确切数据,或者你可以写一些东西,可以接受各种选项,只要他们遇到一个严格的白名单。 你需要检查两件事情:

  1. 应该允许用户在磁盘上读写哪些文件 ? 例如,这可能是一个特定的目录,文件名可能必须有一个合适的前缀或扩展名。
  2. 用户能够在数据库中读/写哪些 ? 这通常由数据库中的GRANT定义,但是该函数现在以超级用户的身份运行,所以通常是“越界”的表将被完全访问。 你可能不想让别人调用你的函数,并在你的“用户”表的最后添加行…

我写了一篇博客文章,介绍了这种方法 ,包括一些导出(或导入)符合严格条件的文件和表格的函数示例。


客户端

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

底层的语法是COPY TO STDOUT命令,象pgAdmin这样的graphics工具会把它包装好,并放在一个很好的对话框中。

psql命令行客户端有一个叫做\copy的特殊“元命令”,它和“真正的” COPY有相同的选项,但是在客户端运行:

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

请注意,没有终止; ,因为与SQL命令不同,元命令由换行符终止。

从文档 :

不要将COPY与psql指令\副本混淆。 \ copy会调用COPY FROM STDIN或COPY TO STDOUT,然后将数据提取/存储到psql客户端可访问的文件中。 因此,使用\ copy时,文件的可访问性和访问权限取决于客户端而不是服务器。

您的应用程序编程语言也可能支持推送或读取数据,但通常不能在标准SQL语句中使用COPY FROM STDIN / TO STDOUT ,因为没有办法连接input/输出stream。 PHP的PostgreSQL处理程序( 不是 PDO)包含非常基本的pg_copy_frompg_copy_to函数,这些函数可以复制到PHP数组中,或者从PHP数组中复制,这对于大数据集可能不是有效的。

有几个解决scheme:

1个psql命令

psql -d dbname -t -A -F"," -c "select * from users" > output.csv

这有很大的好处,你可以通过SSH使用它,比如ssh postgres@host command – 使你能够得到

2 postgres copy命令

COPY (SELECT * from users) To '/tmp/output.csv' With CSV;

3 psql交互式(或不)

 >psql dbname psql>\f ',' psql>\a psql>\o '/tmp/output.csv' psql>SELECT * from users; psql>\q 

所有这些都可以在脚本中使用,但我更喜欢#1。

4 pgadmin但这不是脚本。

在terminal(当连接到数据库)设置输出到CVS文件

1)将字段分隔符设置为','

 \f ',' 

2)设置输出格式未alignment:

 \a 

3)只显示元组:

 \t 

4)设置输出:

 \o '/tmp/yourOutputFile.csv' 

5)执行你的查询:

 :select * from YOUR_TABLE 

6)输出:

 \o 

您将能够在这个位置find您的csv文件:

 cd /tmp 

使用scp命令复制它或使用nano编辑:

 nano /tmp/yourOutputFile.csv 

如果您对特定表格的所有列以及标题感兴趣,则可以使用

 COPY table TO '/some_destdir/mycsv.csv' WITH CSV HEADER; 

这比一点点简单

 COPY (SELECT * FROM table) TO '/some_destdir/mycsv.csv' WITH CSV HEADER; 

据我所知,这是等同的。

我不得不使用\ COPY,因为我收到了错误信息:

 ERROR: could not open file "/filepath/places.csv" for writing: Permission denied 

所以我用:

 \Copy (Select address, zip From manjadata) To '/filepath/places.csv' With CSV; 

它正在运作

psql可以为你做这个:

 edd@ron:~$ psql -d beancounter -t -A -F"," \ -c "select date, symbol, day_close " \ "from stockprices where symbol like 'I%' " \ "and date >= '2009-10-02'" 2009-10-02,IBM,119.02 2009-10-02,IEF,92.77 2009-10-02,IEV,37.05 2009-10-02,IJH,66.18 2009-10-02,IJR,50.33 2009-10-02,ILF,42.24 2009-10-02,INTC,18.97 2009-10-02,IP,21.39 edd@ron:~$ 

请参阅man psql获取这里使用的选项的帮助。

在pgAdmin III中,有一个选项可以从查询窗口导出到文件。 在主菜单中,查询 – >执行到文件,或者有一个button,执行相同的事情(这是一个蓝色的软盘,而不是简单的绿色三angular形,只是运行查询)的绿色三angular形。 如果你没有从查询窗口运行查询,那么我会做什么IMSoPbuild议,并使用复制命令。

我正在使用AWS Redshift,它不支持COPY TOfunction。

我的商业智能工具支持制表符分隔的CSV,所以我使用了以下内容:

  psql -h dblocation -p port -U user -d dbname -F $'\t' --no-align -c " SELECT * FROM TABLE" > outfile.csv 

我写了一个名为psql2csv的小工具,将COPY query TO STDOUT封装COPY query 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 

如果你有更长的查询,你想使用psql,那么把你的查询到一个文件,并使用下面的命令:

 psql -d my_db_name -t -A -F";" -f input-file.sql -o output-file.csv 

JackDB ,Web浏览器中的数据库客户端,使得这非常简单。 特别是如果你在Heroku上。

它允许您连接到远程数据库并在其上运行SQL查询。

来源 jackdb-heroku http://static.jackdb.com/assets/img/blog/jackdb-heroku-oauth-connect.gif


连接数据库后,您可以运行查询并导出为CSV或TXT(请参阅右下angular)。


jackdb出口

注意:我与JackDB没有任何关系。 我目前使用他们的免费服务,并认为这是一个伟大的产品。