\pset format csv
\pset tuples_only on
begin;
declare c cursor for your-query-here;
fetch 1000000 from c \g file1.csv
fetch 1000000 from c \g file2.csv
... as many times as necessary...
close c;
end;
因为 psql 中没有循环结构,并且假设您事先不知道需要多少个 fetch 步骤,所以您必须在上一步中生成该脚本,该脚本计算count(*)结果集并向编号文件发出(count(*)+NR-1)/NR时间fetch NR from...命令,例如上面,NR每个文件的记录数在哪里。
如果记录在文本字段中没有嵌入换行符,因此存在严格的 [one line = one record] 映射,您可以将
\copy csv
in psql 的输出传递给 Unix 命令split。例如:请参阅
split
更改输出文件或目标目录名称格式的选项。如果您是超级用户,它也可以在服务器端使用,COPY
而不是。\copy
如果记录可能嵌入了换行符,那就更复杂了,因为使用上述方法,一条记录可能跨越两个连续的文件,使每个文件单独成为无效的 CSV 文件。例如:
会产生两个文件
和
如果目标是将文件连接回单个文件以进行处理,那么没关系,但如果必须单独处理它们,则应考虑使用不同的方法。
在 psql中是可能的,但有点涉及(而不是用编程语言编写它)。从 PostgreSQL 12 开始,csv 是 psql 中的本机输出格式,因此查询上的游标可能与
FETCH 1000000
执行实际剪切和检索的语句一起使用。一段应该工作的脚本的骨架如下所示:因为 psql 中没有循环结构,并且假设您事先不知道需要多少个 fetch 步骤,所以您必须在上一步中生成该脚本,该脚本计算
count(*)
结果集并向编号文件发出(count(*)+NR-1)/NR
时间fetch NR from...
命令,例如上面,NR
每个文件的记录数在哪里。