我正在尝试使用COPY将CSV文件导入PostgreSQL。当它遇到有空值的行时,它会窒息,例如:第二行:
JAN-01-2001,1,2,3,4,5
JAN-02-2001,6,7 ,,,
我已经尝试过这个COPY语句,以及使用NULL和QUOTE的变体,并且没有找到任何有效的方法。
来自'data.dat'的COPY数据 使用DELIMITERS','CSV;
有什么建议吗?数据文件是一个庞大的22GB平面文件,所以我想避免直接编辑它。
答案 0 :(得分:1)
我建议您将数字列转换为文本列,以便导入。原因是空字符串不是有效的数值。将数字列更改为文本列,导入CSV文件,将空值更新为null或0,然后将列更改回整数。
答案 1 :(得分:1)
你的陈述是可疑的:
COPY data FROM 'data.dat' USING DELIMITERS ',' CSV;
DELIMITERS
用于7.3之前的版本 。它仍然受支持,以免破坏旧代码,但不再使用它。正确的关键字是DELIMITER
。而且您根本不需要指定,
,因为它是FORMAT CSV
的默认值
另外,我引用manual here:
<强> 文件名 强>
输入或输出文件的绝对路径名。 Windows用户可能需要使用
E''
字符串并将路径名中使用的任何反斜杠加倍。
大胆强调我的。将'data.dat'
替换为UNIX上的'/path/to/data.dat'
或Windows上的E'C:\\path\\to\\data.dat'
。
对于7.3+版本,请使用:
COPY data FROM '/path/to/data.dat' CSV
对于9.0+版本,请使用:
COPY data FROM '/path/to/data.dat' (FORMAT CSV)
如果您仍然收到此错误:
ERROR: invalid input syntax for type numeric: CONTEXT: COPY data, line 13, column interval_2400:
然后,显然,源文件与表data
的结构不匹配。查看您的源文件,转到第13行并查看列interval_2400
的值。机会是,它不是数字。特别是,数字类型的列中不允许empty string
(''
)。
您可以修复源文件或调整表格定义:
ALTER TABLE data ALTER COLUMN interval_2400 TYPE text;
或者任何类型更合适。从名称来看,可能是interval
。 (但text
几乎接受任何输入值。)
或者,更好的是,创建一个修改过的临时文件COPY
,修复违规值,然后插入目标表,从文本转换。参见:
答案 2 :(得分:0)
这是PostgreSQL错误 - csv解析器忽略最后一个空项并抛出错误 - &#34; PG :: BadCopyFileFormat:错误:列#34缺少数据。
我使用了一个愚蠢的黑客:
如果最后一项为空,则简单地在字符串末尾添加一个分隔符:
1,2,3
1,2,,
此添加错过了行中的最后一项以导入数据。
答案 3 :(得分:0)
另一个警告 - 检查错误的行号并确保它不是CSV文件中的空行。这将导致postgres抛出有关缺失值的相同错误。
答案 4 :(得分:-1)
任何人来到这里都有较小的文件:这是我发现的最简单的解决方案,并且csv中的分隔符数量不一致。
这将遍历整个CSV并强制它在分隔符(,)中具有正确的列数,即使该列中没有数据也是如此。
如果您对Excel没有问题,您也可以将其转换为宏,这样我的宏(Ctrl + g)就可以一次完成。 Creating a Macro