【问题标题】:Is it possible to turn off quote processing in the Postgres COPY command with CSV format?是否可以在 CSV 格式的 Postgres COPY 命令中关闭报价处理?
【发布时间】:2013-12-05 14:33:01
【问题描述】:

我有 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 开头的双引号解释为字段换行符。

我如何指定我的数据完全引用?

【问题讨论】:

标签: postgresql csv import


【解决方案1】:

解决方法(感谢this comment!)

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

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

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

【讨论】:

  • @Kyle Barron 的添加对于一些编码错误的文本至关重要。我有一个非常大的 (~50GB) CSV,我需要复制它,在结束前大约 3GB,出现了 '\b'。该文件的源代码在清理值方面做得不好,但这并不意味着我希望我的COPY 失败。 tr 救援。
【解决方案2】:

(作为新答案添加,因为我还没有评论的声誉。)

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

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

(使用 \010octal representation\b)。

由于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 '';

【讨论】:

    【解决方案3】:

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

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

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

    那么处理后的文件应该可以在没有任何附加选项的情况下导入:

    \copy sometable from processed.txt
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多