我使用带有pgAdmin III和PSQL插件的PostgreSQL 8.4运行查询。
你想要将生成的文件放在服务器上还是客户端上?
如果您想要易于重用或自动化的内容,可以使用Postgresql内置的COPY命令。例如:
Copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',' HEADER;
SECURITY DEFINER
选项创建函数,使函数以超级用户一样运行。GRANT
定义,但是函数现在正在作为超级用户运行,因此通常“禁止”的表将完全可访问。您可能不希望让某个人调用您的函数并在您的“用户”表末尾添加行……
我已经写了一篇博客文章扩展这种方法,包括一些函数导出(或导入)符合严格条件的文件和表格的示例。
另一种方法是在应用程序或脚本中在客户端处理文件操作。Postgres服务器不需要知道您要复制到哪个文件,它只会输出数据,客户端将其放在某个位置。
此操作的底层语法是COPY TO STDOUT
命令,图形化工具如pgAdmin会为您包装成一个漂亮的对话框。
psql
命令行客户端有一个特殊的“元命令”叫做\copy
,它接受与“真正”的COPY
相同的所有选项,但在客户端中运行:
\copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',' HEADER
;
,因为元命令由换行符终止,而不是SQL命令。您的应用程序编程语言可能还支持推送或获取数据,但通常无法在标准SQL语句中使用不要将COPY与psql指令\copy混淆。 \copy调用COPY FROM STDIN或COPY TO STDOUT,然后将数据提取/存储在对psql客户端可访问的文件中。因此,在使用\copy时,文件可访问性和访问权限取决于客户机而不是服务器。
COPY FROM STDIN
/TO STDOUT
,因为没有连接输入/输出流的方法。 PHP的PostgreSQL处理程序(不是 PDO)包括非常基本的pg_copy_from
和pg_copy_to
函数,可复制到/从PHP数组,这对于大型数据集可能不是有效的。\copy
也可以使用,路径相对于客户端,并且不需要/不允许使用分号。请参考我的编辑。 - krlmlr\copy
需要写成一行代码。这样你就无法美化 SQL 代码的格式,也不能只简单地把 copy
或函数放在周围。 - isaaclwpsql
命令psql -d 数据库名 -t -A -F"," -c "select * from users" > 输出.csv
这个方法的优点是可以通过 SSH 使用,例如 ssh postgres@主机名 命令
- 让您轻松获取。
copy
命令COPY (SELECT * from users) To '/tmp/output.csv' With CSV;
>psql dbname
psql>\f ','
psql>\a
psql>\o '/tmp/output.csv'
psql>SELECT * from users;
psql>\q
所有这些都可以在脚本中使用,但我更喜欢#1。
select * from users
使用每个varchar列的引用函数:quote_literal():select id, quote_literal(name), quote_literal(email), ... from users
- Dek4nice ','
:\f ','
2) 将输出格式设置为不对齐:
\a
3) 仅显示元组:
\t
4) 设置输出:
\o '/tmp/yourOutputFile.csv'
5) 执行您的查询:
:select * from YOUR_TABLE
6) 输出:
\o
然后您就可以在这个位置找到您的csv文件:
cd /tmp
scp
命令进行拷贝,或使用 nano 进行编辑:nano /tmp/yourOutputFile.csv
COPY
或\copy
方法可以正确处理(转换为标准CSV格式);这个方法呢? - Wildcard这些信息并没有很好地呈现出来。由于这是我第二次需要推导出它,所以我将把它放在这里,以便提醒自己。
实际上,获取Postgres中的CSV最佳方法是使用COPY ... TO 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
它非常适用于通过ssh在docker内部使用:
$ 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 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
可以在执行psql
命令的系统上有效地执行文件操作,作为执行它的用户1。如果连接到远程服务器,则可以简单地将数据文件从执行psql
的系统复制到/从远程服务器。
COPY
以后端进程用户帐户(默认为postgres
)在服务器上执行文件操作,检查并相应地应用文件路径和权限。如果使用TO STDOUT
,则绕过文件权限检查。
这两个选项都需要随后移动文件,如果psql
未在您希望结果CSV最终驻留的系统上执行,则最有可能出现这种情况。根据我的经验,当您主要与远程服务器一起工作时,情况就是这样。
配置类似于通过ssh建立到远程系统的TCP/IP隧道以进行简单的CSV输出更加复杂,但对于其他输出格式(二进制),可能更好地通过隧道连接上的/copy
,执行本地psql
。同样,在进行大量导入时,将源文件移动到服务器并使用COPY
可能是最高性能的选项。
使用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文件,而无需编译或安装任何工具。
新版本 - psql 12 - 将支持 --csv
。
--csv
切换到 CSV(逗号分隔值)输出模式,等同于\pset format 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
如果您对特定表的所有列及其标题感兴趣,可以使用以下方法:
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;
并且它正在运作
/tmp
文件夹来解决它。例如:\copy (SELECT * FROM messages) TO '/tmp/messages.csv' With CSV HEADER;
- Somto我正在使用AWS Redshift,它不支持COPY TO
功能。
我的BI工具支持制表符分隔的CSV文件,因此我使用了以下方法:
psql -h dblocation -p port -U user -d dbname -F $'\t' --no-align -c "SELECT * FROM TABLE" > outfile.csv
psql -h dblocation -p port -U user -d dbname -F $',' --no-align -c "SELECT * FROM TABLE" > outfile.csv
来获取CSV文件。虽然没有对字段进行引用,但对于我的目的来说已经足够了。 - Lightheaded.pg_service.conf
文件来将连接参数别名化,例如 psql service=default -F $'\t' ...
。 - combinatoristUNLOAD
命令。 - Himanshupsql
可以为您完成此操作:
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中,可以从查询窗口导出到文件。在主菜单中选择Query -> Execute to file或者使用相同功能的按钮(一个绿色三角形和一个蓝色软盘,而不是普通的绿色三角形只运行查询)。如果您不是从查询窗口运行查询,则建议按照IMSoP的建议使用复制命令。