CSV 中引用的雪花空值中断 PostgreSQL 卸载
Snowflake null values quoted in CSV breaks PostgreSQL unload
我正在尝试将数据从 Snowflake 转移到 Postgresql,为此我首先将其以 CSV 格式加载到 s3 中。在table中,文本中可能出现逗号,因此我使用FIELD_OPTIONALLY_ENCLOSED_BY
雪花卸载选项来引用有问题的单元格的内容。但是,当发生这种情况+空值时,我无法为 PostgreSQL 获取有效的 CSV。
我创建了一个简单的 table 来帮助您理解这个问题。在这里:
CREATE OR REPLACE TABLE PUBLIC.TEST(
TEXT_FIELD VARCHAR(),
NUMERIC_FIELD INT
);
INSERT INTO PUBLIC.TEST VALUES
('A', 1),
(NULL, 2),
('B', NULL),
(NULL, NULL),
('Hello, world', NULL)
;
COPY INTO @STAGE/test
FROM PUBLIC.TEST
FILE_FORMAT = (
COMPRESSION = NONE,
TYPE = CSV,
FIELD_OPTIONALLY_ENCLOSED_BY = '"'
NULL_IF = ''
)
OVERWRITE = TRUE;
Snowflake 将从中创建以下 CSV
"A",1
"",2
"B",""
"",""
"Hello, world",""
但在那之后,我无法将此 CSV 原样复制到 PostgreSQL Table 中。
甚至从 PostgreSQL 文档中想到我们在 NULL 选项旁边有:
Specifies the string that represents a null value. The default is \N (backslash-N) in text format, and an unquoted empty string in CSV format.
未在 PostgreSQL 中设置 COPY 选项 COPY INTO 将导致卸载失败。实际上它不会工作,因为我们还必须使用 QUOTE 指定使用的引号。这里是 QUOTE '"'
因此在卸载 POSTGRESQL 期间,使用:
FORMAT csv, HEADER false, QUOTE '"'
将给出:
DataError: invalid input syntax for integer: "" CONTEXT: COPY test, line 3, column numeric_field: ""
FORMAT csv, HEADER false, NULL '""', QUOTE '"'
将给出:
NotSupportedError: CSV quote character must not appear in the NULL specification
仅供参考,为了测试 s3 中的卸载,我将在 PostgreSQL 中使用此命令:
CREATE IF NOT EXISTS TABLE PUBLIC.TEST(
TEXT_FIELD VARCHAR(),
NUMERIC_FIELD INT
);
CREATE EXTENSION IF NOT EXISTS aws_s3 CASCADE;
SELECT aws_s3.table_import_from_s3(
'PUBLIC.TEST',
'',
'(FORMAT csv, HEADER false, NULL ''""'', QUOTE ''"'')',
'bucket',
'test_0_0_0.csv',
'aws_region'
)
非常感谢您对我可以做些什么来实现它的任何想法?我很想找到一个不需要修改 snowflake 和 postgres 之间的 csv 的解决方案。我认为这是 Snowflake 方面的一个问题,因为引用 null 值真的没有意义。但 PostgreSQL 也无济于事。
当您将 NULL_IF
值设置为 '' 时,您实际上是在告诉 Snowflake 将 NULLS 转换为 BLANK,然后将其引用。当您从 Snowflake 复制出来时,复制选项在某种意义上是“向后”的,NULL_IF
更像是 IFNULL
。
这是我将在 Snowflake 端使用的代码,它会在您的 CSV 文件中生成一个未加引号的空字符串:
FILE_FORMAT = (
COMPRESSION = NONE,
TYPE = CSV,
FIELD_OPTIONALLY_ENCLOSED_BY = '"'
NULL_IF = ()
)
我正在尝试将数据从 Snowflake 转移到 Postgresql,为此我首先将其以 CSV 格式加载到 s3 中。在table中,文本中可能出现逗号,因此我使用FIELD_OPTIONALLY_ENCLOSED_BY
雪花卸载选项来引用有问题的单元格的内容。但是,当发生这种情况+空值时,我无法为 PostgreSQL 获取有效的 CSV。
我创建了一个简单的 table 来帮助您理解这个问题。在这里:
CREATE OR REPLACE TABLE PUBLIC.TEST(
TEXT_FIELD VARCHAR(),
NUMERIC_FIELD INT
);
INSERT INTO PUBLIC.TEST VALUES
('A', 1),
(NULL, 2),
('B', NULL),
(NULL, NULL),
('Hello, world', NULL)
;
COPY INTO @STAGE/test
FROM PUBLIC.TEST
FILE_FORMAT = (
COMPRESSION = NONE,
TYPE = CSV,
FIELD_OPTIONALLY_ENCLOSED_BY = '"'
NULL_IF = ''
)
OVERWRITE = TRUE;
Snowflake 将从中创建以下 CSV
"A",1
"",2
"B",""
"",""
"Hello, world",""
但在那之后,我无法将此 CSV 原样复制到 PostgreSQL Table 中。
甚至从 PostgreSQL 文档中想到我们在 NULL 选项旁边有:
Specifies the string that represents a null value. The default is \N (backslash-N) in text format, and an unquoted empty string in CSV format.
未在 PostgreSQL 中设置 COPY 选项 COPY INTO 将导致卸载失败。实际上它不会工作,因为我们还必须使用 QUOTE 指定使用的引号。这里是 QUOTE '"'
因此在卸载 POSTGRESQL 期间,使用:
FORMAT csv, HEADER false, QUOTE '"'
将给出:
DataError: invalid input syntax for integer: "" CONTEXT: COPY test, line 3, column numeric_field: ""
FORMAT csv, HEADER false, NULL '""', QUOTE '"'
将给出:
NotSupportedError: CSV quote character must not appear in the NULL specification
仅供参考,为了测试 s3 中的卸载,我将在 PostgreSQL 中使用此命令:
CREATE IF NOT EXISTS TABLE PUBLIC.TEST(
TEXT_FIELD VARCHAR(),
NUMERIC_FIELD INT
);
CREATE EXTENSION IF NOT EXISTS aws_s3 CASCADE;
SELECT aws_s3.table_import_from_s3(
'PUBLIC.TEST',
'',
'(FORMAT csv, HEADER false, NULL ''""'', QUOTE ''"'')',
'bucket',
'test_0_0_0.csv',
'aws_region'
)
非常感谢您对我可以做些什么来实现它的任何想法?我很想找到一个不需要修改 snowflake 和 postgres 之间的 csv 的解决方案。我认为这是 Snowflake 方面的一个问题,因为引用 null 值真的没有意义。但 PostgreSQL 也无济于事。
当您将 NULL_IF
值设置为 '' 时,您实际上是在告诉 Snowflake 将 NULLS 转换为 BLANK,然后将其引用。当您从 Snowflake 复制出来时,复制选项在某种意义上是“向后”的,NULL_IF
更像是 IFNULL
。
这是我将在 Snowflake 端使用的代码,它会在您的 CSV 文件中生成一个未加引号的空字符串:
FILE_FORMAT = (
COMPRESSION = NONE,
TYPE = CSV,
FIELD_OPTIONALLY_ENCLOSED_BY = '"'
NULL_IF = ()
)