如何在Postgresql中将表导出为CSV并包含标题?

492
我正在尝试通过命令行将一个带有表头的PostgreSQL表格导出到CSV文件,但是它只能导出CSV文件而没有表头。
我的代码如下:
COPY products_273 to '/tmp/products_199.csv' delimiters',';

你是否使用的是 PostgreSQL 版本大于等于 8.1? - Dana the Sane
1
我想我会制定一个升级计划,这将使生活变得更加轻松。 - Elitmiar
1
请参见https://dev59.com/q3I_5IYBdhLWcg3wHvQ5 - Peter Krauss
14个回答

685
COPY products_273 TO '/tmp/products_199.csv' WITH (FORMAT CSV, HEADER);

手册所述。


9
请注意,"HEADER" 参数是在 8.1 版本中引入的。 - Dana the Sane
7
可以说有点生锈。 - Milen A. Radev
77
注意:COPY 命令需要管理员权限。如果遇到问题,请使用 \COPY 命令代替。 - fny
5
最好使用"FORMAT csv"而不是"DELIMITER ','",否则可能会产生不符合规范的输出。不确定这个功能是从哪个版本开始提供的。 - grahamrhay
39
在v9.5中,该命令现在是 COPY products_273 TO '/tmp/products_199.csv' WITH (FORMAT CSV, HEADER); - Shubham Goyal
显示剩余11条评论

266

使用 psql 命令行:

\COPY my_table TO 'filename' CSV HEADER

末尾没有分号。


25
这个版本是目前最好的,因为“COPY”命令需要管理员权限。 - Matthew O'Riordan
2
同时使用 psql 方法,可以将输出保存在任何有访问权限的地方。我刚刚使用了 psql 方法,将远程服务器上的数据获取到本地文件中。非常流畅。 - Ian Gow
非常好,特别是当你保存到一个你有访问权限但 postgres 用户没有的目录时。 - Steve Bennett
2
@arilwan 使用 pg_dump -h remote | pg_restore -h localhost - Ian Gow
4
将"mytable"表中的所有数据导出为CSV格式文件"mytable.csv": psql -c "\COPY (SELECT * FROM mytable) TO STDOUT" > mytable.csv - Juha Palomäki
显示剩余6条评论

139

除了表名,您还可以编写查询以仅获取所选列的数据。

COPY (select id,name from tablename) TO 'filepath/aa.csv' DELIMITER ',' CSV HEADER;

具有管理员特权

\COPY (select id,name from tablename) TO 'filepath/aa.csv' DELIMITER ',' CSV HEADER;

我认为在psql版本的命令(\COPY ...)中不需要终止分号。至少在我的psql版本(9.5.2)中,我不需要指定'DELIMITER';默认值是逗号。 - user1071847
如果我将选定的字段从CSV复制到表格中,语法会如何改变? - user269867

134

当我没有从Postgres中写入文件的权限时,我发现可以从命令行运行查询。

psql -U user -d db_name -c "Copy (Select * From foo_table LIMIT 10) To STDOUT With CSV HEADER DELIMITER ',';" > foo_data.csv

10
最适合“任何环境”。最适合于以下三点:1. 不需要在Postgresql或客户端中获得特殊权限;2. 可以使用相对路径;以及3. 对于真实的CSV格式(安全引用),具有安全性。 - Peter Krauss
我喜欢这个,因为它可以在单独的环境中工作。 - Vasantha Ganesh

36

这个有效。

psql dbname -F , --no-align -c "SELECT * FROM TABLE"

12
好的。请注意,这似乎不能转义包含逗号的字段内部的逗号。 - Lucas Wiman
我喜欢这个,不要使用“-F ,”,并使用“|”作为分隔符。谢谢! - dsummersl
2
这不是通常被认为的导出功能,只是受控数据显示。差别很小,但很重要:这更适合供人阅读,而COPY语句则创建一个可重复使用的文件。 - Romain G
11
危险警告:它不适用于CSV格式,不能正常处理包含“,”的数组或文本。它无法正确地进行CSV引用。请使用@Brian的答案。 - Peter Krauss
我喜欢这种形式,因为它适用于从命令文件重定向输入的情况。我使用制表符分隔符,这样例如gnumeric out.tsv就可以工作了。 - hoffmanc

17

最简单的方法(使用psql)似乎是通过使用--csv标志:

psql --csv -c "SELECT * FROM products_273" > '/tmp/products_199.csv'

我在我的电脑上哪里可以找到那个目录? - user12510360
结果将保存在 > 后的任何路径下。 - Yan Foto
3
我的版本 psql (PostgreSQL) 11.7 (Ubuntu 11.7-0ubuntu0.19.10.1) 没有 --csv 选项。 - hoffmanc
我在等待命令行输入结束时遇到了分页器问题,所以不得不添加“-P pager=off”选项。 - thayne

10
这个方法对我来说很有效,使用 \copy 命令。
psql -h <host> -U <user> -d <dbname> -c "\copy <table_name> FROM '<path to csvfile/file.csv>' with (format csv,header true, delimiter ',');"

10

对于我使用的版本9.5,应该是这样的:

COPY products_273 TO '/tmp/products_199.csv' WITH (FORMAT CSV, HEADER);

4
这是我使用 PowerShell 和 pgsl 连接到 Heroku PG 数据库的方法:
首先,我需要将客户端编码更改为 utf8,像这样:\encoding UTF8 然后,我将数据转储到 CSV 文件中,如下所示:
\copy (SELECT * FROM my_table) TO  C://wamp64/www/spider/chebi2/dump.csv CSV DELIMITER '~'

我使用~作为分隔符,因为我不喜欢CSV文件,通常我使用TSV文件,但是它不允许我将'\t'作为分隔符,因此我使用了~,因为它是一个很少使用的字符。


2

COPY命令并没有受到限制,受到限制的是将TO的输出指向除STDOUT之外的任何地方。但是,可以通过\o命令指定输出文件而没有限制。

\o '/tmp/products_199.csv';
COPY products_273 TO STDOUT WITH (FORMAT CSV, HEADER);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接