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

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


当前回答

JackDB是web浏览器中的一个数据库客户端,它让这一切变得非常简单。特别是如果你在Heroku。

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

                                                                                                                                                        源 (来源:jackdb.com)


一旦连接了数据库,就可以运行查询并导出到CSV或TXT(见右下角)。


注:我与JackDB没有任何关联。我目前使用他们的免费服务,认为这是一个很棒的产品。

其他回答

JackDB是web浏览器中的一个数据库客户端,它让这一切变得非常简单。特别是如果你在Heroku。

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

                                                                                                                                                        源 (来源:jackdb.com)


一旦连接了数据库,就可以运行查询并导出到CSV或TXT(见右下角)。


注:我与JackDB没有任何关联。我目前使用他们的免费服务,认为这是一个很棒的产品。

有几种解决方案:

1 PSQL命令

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

这有一个很大的优势,您可以通过SSH使用它,如SSH postgres@host命令-使您能够获得

2 postgres copy命令

拷贝(SELECT * from users)到'/tmp/output.csv'

PSQL交互(或不交互)

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

它们都可以在脚本中使用,但我更喜欢第1种。

4 pgadmin,但这是不可编写脚本的。

CSV统一导出

这个信息并没有很好地表示出来。因为这是我第二次需要推导这个,我把它写在这里提醒自己。

实际上,最好的方法(从postgres中获取CSV)是使用COPY…到STDOUT命令。虽然你不想用答案中显示的方式来做。该命令的正确使用方法为:

COPY (select id, name from groups) TO STDOUT WITH CSV HEADER

只记住一个命令!

它非常适合在ssh上使用:

$ ssh psqlserver.example.com 'psql -d mydb "COPY (select id, name from groups) TO STDOUT WITH CSV HEADER"' > groups.csv

它非常适合在docker中使用ssh:

$ ssh pgserver.example.com 'docker exec -tu postgres postgres psql -d mydb -c "COPY groups TO STDOUT WITH CSV HEADER"' > groups.csv

它甚至在本地机器上也很棒:

$ psql -d mydb -c 'COPY groups TO STDOUT WITH CSV HEADER' > groups.csv

或本地机器上的内部docker ?:

docker exec -tu postgres postgres psql -d mydb -c 'COPY groups TO STDOUT WITH CSV HEADER' > groups.csv

或者在kubernetes集群上,在docker中,通过HTTPS??:

kubectl exec -t postgres-2592991581-ws2td 'psql -d mydb -c "COPY groups TO STDOUT WITH CSV HEADER"' > groups.csv

多才多艺,有很多逗号!

你知道吗?

是的,我写了,以下是我的笔记:

的份

使用/copy可以作为执行it1的用户在psql命令运行的任何系统上有效地执行文件操作。如果连接到远程服务器,那么将执行psql的系统上的数据文件复制到远程服务器或从远程服务器复制数据文件是很简单的。

COPY作为后端进程用户帐户(默认为postgres)在服务器上执行文件操作,检查并相应应用文件路径和权限。如果使用TO STDOUT,则绕过文件权限检查。

如果psql没有在您希望生成的CSV最终驻留的系统上执行,这两个选项都需要后续的文件移动。根据我的经验,当您主要使用远程服务器时,这是最可能的情况。

通过ssh配置TCP/IP隧道之类的东西到远程系统以获得简单的CSV输出会更复杂,但对于其他输出格式(二进制),最好通过隧道连接/copy,执行本地psql。同样,对于大型导入,将源文件移动到服务器并使用COPY可能是性能最高的选项。

PSQL参数

使用psql参数,你可以像CSV一样格式化输出,但也有缺点,比如必须记住禁用分页器和不获取头信息:

$ psql -P pager=off -d mydb -t -A -F',' -c 'select * from groups;'
2,Technician,Test 2,,,t,,0,,                                                                                                                                                                   
3,Truck,1,2017-10-02,,t,,0,,                                                                                                                                                                   
4,Truck,2,2017-10-02,,t,,0,,

其他工具

不,我只是想在不编译和/或安装工具的情况下从服务器中获取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数组中复制或从数组中复制,这对于大型数据集可能不太有效。

下载列名为HEADER的CSV文件使用以下命令:

Copy (Select * From tableName) To '/tmp/fileName.csv' With CSV HEADER;