我正在处理一些SEC 数据,这些数据在非常规则格式的制表符分隔文件中可用。
在 MySQL 上,我可以这样导入这些文件:
CREATE TABLE import ( adsh text, tag text, version text, ddate text, qtrs text, uom text, dimh text, iprx text, value text, footnote text, footlen text, dimn text, coreg text, durp text, datp text, dcml text);
LOAD DATA INFILE '/pg/import/2011/Q2/num.tsv' INTO TABLE import FIELDS ESCAPED BY '' IGNORE 1 ROWS;
这适用于每个文件。但是,在 Pg 服务器上运行的类似命令不起作用。在这种情况下,我使用该页面上 .zip 中的 2011 年第二季度“num”数据。此文件是一个 40 列的制表符分隔文件。我在 Pg 服务器上运行这个命令。
COPY import._2011_q2_num from '/pg/import/2011/Q2/num.tsv' DELIMITER E'\t' CSV HEADER;
ERROR: unterminated CSV quoted field
CONTEXT: COPY _2011_q2_num, line 830954: "0001193125-11-104388 DerivativeInstrumentsGainLossReclassifiedFromAccumulatedOCIIntoIncomeEffectiveP..."
根据 wc -l,该文件中有 830953 行。如果我删除最后一行,错误仍然存在 - 它只是说它像 830953 一样打开,等等。
我认为问题在于文件中出现了多个空字段:
\t\t\t\t
(来自 od -c)。我认为 Pg 正在将那些连续的标签视为转义。文档说:
ESCAPE...默认值与 QUOTE 值相同(这样如果引用字符出现在数据中,则加倍)。这必须是一个单字节字符。
好的,所以我必须为 ESCAPE 赋予一些价值,即使在这些文件中什么都不会被转义。文件中没有 \b ,所以我尝试了:
COPY import._2011_q2_num from '/pg/import/2011/Q2/num.tsv' DELIMITER E'\t' ESCAPE E'\b' CSV HEADER;
但是,我得到了同样的错误。
\b 也许有些时髦?我还尝试了波浪号(它出现在某些文件中,但我尝试了一个没有它的文件)和同样的错误。
-- with E for ESCAPE byte
copy import._2011_q2_num from '/pg/import/2011/Q2/num.tsv' ESCAPE E'~' DELIMITER E'\t' CSV HEADER
-- without E
copy import._2011_q2_num from '/pg/import/2011/Q2/num.tsv' ESCAPE '~' DELIMITER E'\t' CSV HEADER
根据我的测试,大约四分之一的文件失败,其余的成功。每个文件中有数百万行,因此手动检查它们是不切实际的,而且我不认为这些文件的构造很糟糕,因为 MySQL 没有问题。我想我只是没有给出正确的 Pg 语法 - ?
这是 Debian 11.3 上的 PostgreSQL 13.5