将远程的Postgres表导出为CSV文件到本地机器上

我只能以只读权限访问远程服务器上的数据库。因此,我可以执行以下操作:
COPY products TO '/tmp/products.csv' DELIMITER ',';
但是在那个服务器上,我没有权限创建/保存文件,所以我需要在我的本地机器上完成这个操作。 当我连接到远程数据库时,如何执行一个命令将文件保存在我的本地机器上,而不是远程服务器上? 或者,如何执行一个Linux命令来连接到远程数据库,执行查询,并将输出保存为文件到我的本地机器上?
2个回答

两种已经提出的方法似乎都过于复杂。

只需使用 psql 内置的 \copy 命令,它的工作方式就像服务器端的 COPY 命令一样,但它会通过线协议复制到客户端并使用客户端路径。

因为它是一个 psql 反斜杠命令,所以您可以省略分号,例如:

\copy products TO '/tmp/products.csv' CSV DELIMITER ','
请参阅psql命令手册中的\copy条目COPY命令文档以获取更多详细信息。 与COPY一样,当复制数据时(但不是在复制数据时),您可以使用(SELECT ...)查询而不是表名来使用\copy
一个通常较差的选择,只在一些有限的情况下可能会有用的是使用:
psql -t -P format=unaligned -P fieldsep_zero=on -c 'SELECT * FROM tablename'
使用-o标志或shell输出重定向将输出写入文件。几乎总是应优先使用\copy

但这样做无法进行交易 :( - Reza S
2嗯,当然可以。使用here-document来向psql提供一个脚本,以BEGIN开头,然后执行你的\copy命令,最后是COMMIT。或者使用psql -f来运行一个脚本,而不是使用here-document。 - Craig Ringer
谢谢你回复……我最终就是这样做的,而且它有效了 =) - Reza S
你可以使用-A代替-P format=unaligned,而且我认为你还需要一个-P fieldsep=, - Evan Carroll

Linux命令是:
psql -h 127.0.0.1 -U username -o file.csv -c 'select id, name from clients;'

2这不会生成CSV,而是生成格式化的文本输出。如果你在命令中添加-t -P format=unaligned,你会得到更接近的结果,类似有问题的以管道分隔的CSV,但是文本中的管道符号不会被转义,所以它将是无效的。 - Craig Ringer
1哦,你还想要-P fieldsep=',',但是这样更容易出现错误,因为缺少转义。如果你不介意解析以空字节分隔的文本,那么-P fieldsep_zero=on就可以了,因为空字节在psql输出中不会自然出现。 - Craig Ringer