将压缩的CSV文件导入到PostgreSQL

19

我有一个大型压缩的csv文件(25gb),我想将其导入到PostgreSQL 9.5版本中。有没有一种快速的方法可以在不解压缩文件的情况下将zip或qzip文件导入到postgres中?


3
没有内置的方法,但是 copy 命令可以从程序获取输入,因此您可以运行解压并将输出导入 copy (或 \copy)命令。一些 SQL 客户端也提供了这个功能。 - user330315
我正在使用没有zip文件选项的pgAdmin III客户端。使用您提到的copy命令会更快,还是先提取文件然后导入到postgresql? - Arezoo
COPY是用于从/到CSV导入和导出数据的命令,它没有提取zip文件的功能。如果您想使用pgAdmin导入,您需要先提取zip文件,然后使用COPY导入提取的CSV文件。 - Vivek S.
3个回答

24

有一个老的技巧可以使用命名管道(在Unix上有效,不知道Windows怎么样)

  • 创建一个命名管道:mkfifo /tmp/omyfifo
  • 将文件内容写入其中:zcat mycsv.csv.z > /tmp/omyfifo &
  • [从psql中] copy mytable(col1,...) from '/tmp/omyfifo'
  • [完成后]:rm /tmp/omyfifo

zcat在后台会阻塞,直到读者(这里是COPY命令)开始读取,它才会在EOF时完成。(或者如果读者关闭了管道)

你甚至可以启动多个管道+zcat对,这些对将被你sql脚本中的多个COPY语句捡起来。


这在pgadmin中可行,但是fifo(+zcat进程)应该存在于运行DBMS服务器的机器上。


顺便说一下:使用netcat的类似技巧可以用于从远程机器读取文件(当然,远程机器应该将文件写入网络套接字)


18

以下是使用zcatpipe的示例:

-bash-4.2$ psql -p 5555 t -c "copy tp to '/tmp/tp.csv';"
COPY 1
-bash-4.2$ gzip /tmp/tp.csv
-bash-4.2$ zcat /tmp/tp.csv.gz | psql -p 5555 t -c "copy tp from stdin;"
COPY 1
-bash-4.2$ psql -p 5555 t -c "select count(*) from tp"
 count
-------
     2
(1 row)

另外,从9.3版本开始您可以:

psql -p 5555 t -c "copy tp from program 'zcat /tmp/tp.csv.gz';"

完全不使用管道


2
通过使用 program 属性,您可以将 zcat 命令嵌入到复制命令中。psql -p 5555 t -c "copy tp from program 'zcat /tmp/tp.csv.gz';"独立运行生成输出的程序的能力也是非常有用的。(https://www.postgresql.org/docs/9.5/static/sql-copy.html) - Canonical Chris
1
true - “从标准输入复制”无论如何都需要SU权限,因此可以是“从程序复制”。 - Vao Tsun

3
如果你有一个ZIP (.zip) 而不是GZIP (.gz) 归档文件,你可以使用 unzip -p 命令来将压缩文件传输。
psql -p 5555 -t -c "copy tp from program 'unzip -p /tmp/tp.csv.zip';"

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