是否可以使用CSV格式关闭Postgres COPY命令中的报价处理?

时间:2013-12-05 14:33:02

标签: postgresql csv import

我有CSV文件,以制表符分隔,字段用引号括起来,其中字段数据可以包含单引号,双引号,管道和反斜杠等字符。

示例数据可能如下所示:

1       2       "ba$aR\eR\       18

我想使用COPY语句将此数据导入Postgres。

当我尝试使用

导入时
COPY <tablename> FROM  <filename> NULL AS '';

我收到错误psql:-:1: ERROR: missing data for column,因为Postgres将反斜杠+标签视为“转义标签”,而不是字段分隔符后面的反斜杠。

所以我转而使用COPY运算符的“CSV格式”,如下所示:

COPY <tablename> FROM <filename> WITH CSV DELIMITER E'\t' NULL AS '';

现在出现了新的错误psql:-:1: ERROR: value too long for type character varying(254)

显然是因为它将字段3开头的双引号解释为字段包装字符。

如何指定我的数据 NOT 引用?

3 个答案:

答案 0 :(得分:27)

解决方法(感谢this comment!)

COPY <tablename> FROM <filename> WITH CSV DELIMITER E'\t' QUOTE E'\b' NULL AS '';

所以基本上指定一个永远不应该出现在文本中的引号字符,但那很难看。

如果实际上有办法完全关闭报价处理,我会更喜欢它。

答案 1 :(得分:1)

(由于我没有声誉尚未发表评论,因此作为新答案添加。)

为了记录,由于我一直在努力解决同一问题,您可以使用tr删除\b,而不只是希望它不在您的文字中任何地方。

tr -d '\010' < filename.csv > newfile.csv

(使用\010\b的{​​{3}}。

由于COPY支持从STDIN读取,因此您可以通过管道tr的输出来减轻I / O影响:

cat filename.csv | tr -d '\010' | COPY <tablename> FROM STDIN WITH CSV DELIMITER E'\t' QUOTE E'\b' NULL AS '';

答案 2 :(得分:1)

您要用于所描述的数据格式的模式是默认文本模式。它会将大多数字符无阻碍地传递到数据库中。它没有报价处理,它使用制表符作为分隔符。使用CSV模式只会给您带来麻烦,因为您需要引入必须解决的引用。

文本模式会传递美元字符,单引号和双引号,管道,甚至返回空格(即使问题中没有提到)。正如示例中的那一点&# 39;没有通过的是反斜杠。但这就像逃避它们一样简单,例如通过这个sed命令:

sed -e 's/\\/\\\\/g' < source.txt > processed.txt

然后处理后的文件应该是可导入的,无需任何其他选项:

\copy sometable from processed.txt