将包含 null 和空字符串的雪花表复制到可以使用 psql copy 命令导入的 csv

Bo *_* S. 6 csv string postgresql null snowflake-cloud-data-platform

所以,如果 Snowflake 中有这张表:

create table t (x string, y string) as select '', null;

并且您使用 file_format csv 将其复制到外部阶段,如果您未将 field_optionally_enlined_by 设置为 none 以外的其他值,则会出现此错误:

如果未指定文件格式选项 field_optionally_enlined_by ,则无法卸载空字符串。

所以,假设它设置为“”。

create stage some_stg
url='s3://<some-bucket>/<some-dir>'
file_format = (type = csv field_optionally_enclosed_by='"' compression = none)
credentials = (aws_role = '<your-arn-for-snowflake>')
Run Code Online (Sandbox Code Playgroud)

如果您不想让 Snowflake 使用您的 s3 存储桶,我确信这个问题会在内部阶段重现。

当您运行上面的表 t 的副本时:

copy into @some_stg/t.csv from t overwrite = true;

您会得到一个如下所示的文件 (t_0_0_0.csv):

"","\N"

在 postgres 中创建等效表后:

create table t (x varchar, y varchar);

当您使用 psql 复制将其加载到 postgres 时,如下所示:

psql -h <host> -U <user> -c "copy t from stdin with csv null '\N'" < t_0_0_0.csv

postgres上t的内容是:

x, y
"","\N"
Run Code Online (Sandbox Code Playgroud)

现在这是有道理的,因为雪花将 \N 放在双引号中,因此 psql 副本保留了它。如果您编辑 t_0_0_0.csv 并删除 \N 周围的双引号:

"",\N

并再次运行 psql copy 然后 \N 正确转换为 null

似乎没有一种方法可以从 Snowflake 生成支持空字符串和 null 的 csv 文件,并将其保存到 postgres 中。我弄乱了雪花配置 EMPTY_FIELD_AS_NULL 和 NULL_IF,在雪花的文档中它甚至谈到了这个问题:

When unloading empty string data from tables, choose one of the following options:

Preferred: Enclose strings in quotes by setting the FIELD_OPTIONALLY_ENCLOSED_BY option, to distinguish empty strings from NULLs in output CSV files.
Run Code Online (Sandbox Code Playgroud)

它确实“区分”了它们,但不是以 psql copy 可以使用的方式,而无需事先使用 sed 操作文件。

有谁知道如何生成雪花 csv,以 psql 复制可以重现的方式保留空字符串和空值?

小智 5

您是否尝试在文件格式中使用 NULL_IF 选项,以下文件格式将卸载您的雪花空数据。

CREATE OR REPLACE FILE FORMAT UPDATED_FORMAT_NAME
TYPE = 'CSV'
COMPRESSION = 'NONE'
FIELD_DELIMITER =','
NULL_IF=()
Run Code Online (Sandbox Code Playgroud)