带引号的NULL值使PostgreSQL复制命令失败

带引号的NULL值使PostgreSQL复制命令失败,postgresql,csv,null,postgresql-copy,Postgresql,Csv,Null,Postgresql Copy,我有一个很大的CSV文件,所有列都用“引用。 空值表示为”,列分隔符表示为|。 我想使用来自postgresql(10.7版)的命令来接收这些文件。 我尝试了很多组合,但更自然的是: COPY test.large FROM '/path/to/big.file' WITH ( FORMAT CSV, HEADER, DELIMITER '|', QUOTE '"', NULL '' ); 我的基础表需要一列整数,有些行的NULL值被设置为。|“|…”,

我有一个很大的CSV文件,所有列都用
引用。 空值表示为
,列分隔符表示为
|
。 我想使用来自postgresql(10.7版)的命令来接收这些文件。 我尝试了很多组合,但更自然的是:

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 : «  »
对不起,这个终端是法语的。无论如何,它说:
整数的语法无效:«»
在第2743行,我们发现:

...000205"|""|"XY...
这是一个
NULL
值,但我找不到如何正确设置
COPY
命令开关以使postgresql接收这些文件

文件说:

NULL

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

我知道我可以通过使用
sed
或一些regexp/replace操作将
.|“|…”
更改为
.| |
来清理文件。这将解决我的问题,我已经检查过了

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

更新

按照建议,我读了这篇文章,写道:

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\u null的必须是列名称的列表。
知道吗?

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

看看这个问题:


与您的场景非常相似,那里的公认答案描述了一种类似的技术

这不是空的,它是一个空字符串,这是另一回事。我不知道有什么方法可以让PG将空字符串视为空数字。我建议您使用文本列而不是整数来导入临时表,然后移动t将主表中的数据转换为数字(视情况而定)

看看这个问题:


与您的场景非常相似,其中的公认答案描述了一种类似的技术

似乎在
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)
);

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)
);

我同意,您可能会认为,通过告诉OG quote是“”,null是“”,它将首先从
、“”、…
中删除quote,并且在它们内部找不到任何内容,然后理解它与您的null规范是相同的。。但事实并非如此;它会找到空字符串。如果你说的是
quote''null'nul'
,你的csv就像
,“nul”,nul,,
,你可能会认为它们都是null,但根据规范,一个是SQL null,另一个是
nul
的字符串文本。这有意义吗?想象一下“它在删除引号之前查找null,而不是在删除引号之后”“我试过你推荐信中的一些建议。我已经更新了我的帖子以反映错误。有趣的是,它需要列名称列表。@jlandercy:您需要使用
FORCEèu NULL(appid)
(即一个1元素列表)。不幸的是,它不起作用,但我找到了一个解决方案:
erreur de syntax sur ou près de«NULL»第9行:FORCE NULL(appid)^
好的,我已经找到了我们为什么要讨论这个
或者不讨论,请看我的答案。感谢您花时间来解决我的问题。我同意,您可能会认为,通过告诉OG quote是“”,null是“”,它将首先从
,“,…
中删除引号,并在其中找不到任何内容,然后理解它与您的null规范“”相同……但它不一样;它会找到空字符串。如果您说
quote“'null'nul'
并且您的csv类似于
,“nul”,nul,…
您可能认为它们都是null,但根据规范,一个是SQL null,另一个是字符串文本
nul
。这有意义吗?可以这样想:“它在删除引号之前查找null,而不是在删除引号之后。”我尝试了您的参考中建议的一些方法。我已经更新了我的帖子以反映错误。有趣的是,它需要列名称列表。@jlandercy:您需要使用
FORCEèu NULL(appid)
(即一个1元素列表)。不幸的是,它不起作用,但我找到了一个解决方案:
erreur de syntax sur ou près de«NULL»第9行:FORCE NULL(appid)^
好的,我已经找到了我们为什么要讨论这个
或者不讨论,请看我的答案。谢谢你抽出时间来解决我的问题。