【问题标题】:Quoted NULL values makes PostgreSQL COPY command fail引用的 NULL 值使 PostgreSQL COPY 命令失败
【发布时间】:2019-10-23 18:16:26
【问题描述】:

我有一个很大的 CSV 文件,其中所有列都用 " 引用。 空值表示为"",列分隔符为|。 我想使用 postgresql(版本 10.7)中的 COPYcommand 来摄取这些文件。 我尝试了很多组合,但对我来说更自然的是:

COPY test.large
FROM '/path/to/big.file'
WITH (
    FORMAT CSV,
    HEADER,
    DELIMITER '|',
    QUOTE '"',
    NULL ''
);

我的基础表需要一个整数列,并且有些行将 NULL 值设置为 ...|""|... 而不是某个数字 ...|"123456"|...。不幸的是,这让COPY 崩溃了,说:

ERREUR:  syntaxe en entrée invalide pour l'entier : «  »
CONTEXT:  COPY regpat_pct_app_reg, ligne 2743, colonne appid : «  »

对不起,这个终端是法语的。无论如何,它说:Invalid syntax for integer : « » 在第 2743 行,我们发现:

...000205"|""|"XY...

这是一个 NULL 值,但我找不到如何正确设置 COPY 命令开关以使 postgresql 摄取这些文件。

文档说:

NULL

指定表示空值的字符串。默认为文本格式的 \N(反斜杠-N),以及一个不带引号的空字符串 CSV 格式。即使是文本格式,您也可能更喜欢空字符串 您不想将空值与空字符串区分开来的情况。 使用二进制格式时不允许使用此选项。

我知道我可以通过使用sed 或一些正则表达式/替换操作将...|""|... 更改为...||... 来清理文件。这将解决我的问题,我已经检查过了。

我想知道的是:postgresql 是否可以忍受,毕竟这是完全有效的 CSV 格式。

更新

按照建议阅读following post,我写道:

COPY test.large
FROM '/path/to/big.file'
WITH (
        FORMAT CSV,
        HEADER,
        DELIMITER '|',
        QUOTE '"',
        NULL '',
        FORCE_NULL appid
    );

我明白了:

ERREUR:  l'argument de l'option « force_null » doit être une liste de noms de colonnes

转换为force_null must be a list of column names。有什么想法吗?

【问题讨论】:

    标签: postgresql csv null postgresql-copy


    【解决方案1】:

    这不是 NULL,它是一个空字符串,这是另一回事。我不知道有一种方法可以让 PG 将空字符串视为空数。我建议您在此处使用文本列而不是整数导入临时表,然后将数据移动到主表,并根据需要转换为数字

    看看这个Q:Postgresql COPY empty string as NULL not work

    与您的场景非常相似,那里接受的答案描述了类似的技术

    【讨论】:

    • 我同意,你可能会认为,通过告诉 OG 引用是 '"' 而 null 是 '',它将首先从 ,"",... 中删除引号并在其中找不到任何内容然后理解它与您的 null 规范 ''.. 相同,但它没有;它找到空字符串。如果您说 quote '"' null 'nul' 并且您的 csv 就像 ...,"nul",nul,... 您可能会认为它们都是空的,但是一个是按照规范的 SQL NULL,一个是 nul 的字符串文字。这有意义吗?可以把它想象成“它在删除引号之前查找 null,而不是在删除引号之后”
    • 我已经尝试过您参考中的建议。我已经更新了我的帖子以反映错误。有趣的是,它需要一个列名列表。
    • @jlandercy:你需要使用FORCE_NULL (appid)(即一个1元素列表)。
    • 不幸的是它不起作用,但我找到了解决方案:erreur de syntaxe sur ou près de « NULL » LINE 9: FORCE NULL (appid) ^
    • 好的,我找到了为什么我们有这个_ 或没有讨论,请参阅我的答案。感谢您花时间解决我的问题。
    【解决方案2】:

    似乎是COPY命令切换略有不一致,因为以下调用:

    COPY test.large
    FROM '/path/to/big.file'
    WITH CSV HEADER DELIMITER '|' QUOTE '"' FORCE NULL appid;
    

    按预期工作,或者如果您使用键值对表示法,则必须添加 _

    COPY test.large
    FROM '/path/to/big.file'
    WITH (
        FORMAT CSV,
        HEADER,
        DELIMITER '|',
        QUOTE '"',
        FORCE_NULL (appln_id)
    );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-10
      • 2020-05-03
      • 2011-08-15
      相关资源
      最近更新 更多