数据卸载注意事项

本主题提供从表中卸载数据的最佳实践、一般准则和重要注意事项。目的在于帮助更轻松地使用 COPY INTO <location> 命令,分暂存区将数据从 Snowflake 表导出到文件。

本主题内容:

空字符串和 NULL 值

空字符串是长度为零或无字符的字符串,而 NULL 值则代表没有任何数据。在 CSV 文件中,一个 NULL 值通常由两个连续的分隔符(例如 ,,)表示,这代表该字段不包含任何数据;但您可以使用字符串值来表示 NULL (例如 null)或任何唯一字符串。空字符串通常由带引号的空字符串(例如 '')表示,以指示该字符串包含零个字符。

通过以下文件格式选项,可以在卸载或加载数据时区分空字符串和 NULL 值。有关这些文件格式的详细信息,请参阅 CREATE FILE FORMAT

FIELD_OPTIONALLY_ENCLOSED_BY = 'character' | NONE

使用此选项可将字符串括在指定字符之间,包括:单引号 (')、双引号 (") 或 NONE。

卸载数据时无需将字符串值括在引号之间。COPY INTO(后接指定位置)命令可卸载空字符串值,而不必使用引号括起来,EMPTY_FIELD_AS_NULL 选项设置为 FALSE。如果 EMPTY_FIELD_AS_NULL 选项设置为 TRUE (禁止如此设置),则在输出文件中无法区分空字符串和 NULL 值。

字段包含此字符时,请使用相同的字符对其进行转义。例如,如果值是双引号字符,且字段包含字符串 "A",则应按照这种方式对双引号进行转义:""A""

默认:NONE

EMPTY_FIELD_AS_NULL = TRUE | FALSE
  • 从表中卸载空字符串数据时,请选择以下选项之一:

    • 首选:设置 FIELD_OPTIONALLY_ENCLOSED_BY 选项来将字符串括在引号之间,以在 CSV 输出文件中区分空字符串和 NULLs。

    • FIELD_OPTIONALLY_ENCLOSED_BY 选项设置为 NONE (默认值),以将字符串保留为不括起的状态,并将 EMPTY_FIELD_AS_NULL 值设置为 FALSE,以将空字符串卸载为空字段。

      重要

      如果选择此选项,请确保使用 NULL_IF 选项为 NULL 数据指定替换字符串,从而区分输出文件中的 NULL 值和空字符串。如果稍后选择从输出文件加载数据,则将指定相同的 NULL_IF 值来识别数据文件中的 NULL 值。

  • 将数据加载到表中时,使用此选项可指定是否为输入文件中的空字段插入 SQL NULL。如果设置为 FALSE,Snowflake 会尝试将空字段转换为相应列类型。空字符串会插入到数据类型位 STRING 的列中。对于其他列类型,COPY 命令将引发错误。

默认:TRUE

NULL_IF = ( 'string1' [ , 'string2' ... ] )

从表中卸载数据时:Snowflake 会将 SQL NULL 值转换为列表中的第一个值。在指定要解析为 NULL 的值时,请务必谨慎。例如,如果要将数据卸载到将由另一个系统读取的文件中,请确保指定该系统将解析为 NULL 的值。

默认:\\N (即 NULL,假设 ESCAPE_UNENCLOSED_FIELD 值为 \\ (默认))

示例:在使用引号的情况下卸载和加载数据

在以下示例中,一组数据从 null_empty1 表卸载到用户的暂存区。然后,使用输出数据文件将数据加载到 null_empty2 表中:

-- Source table (null_empty1) contents
+---+------+--------------+
| i | V    | D            |
|---+------+--------------|
| 1 | NULL | NULL value   |
| 2 |      | Empty string |
+---+------+--------------+

-- Create a file format that describes the data and the guidelines for processing it
create or replace file format my_csv_format
  field_optionally_enclosed_by='0x27' null_if=('null');

-- Unload table data into a stage
copy into @mystage
  from null_empty1
  file_format = (format_name = 'my_csv_format');

-- Output the data file contents
1,'null','NULL value'
2,'','Empty string'

-- Load data from the staged file into the target table (null_empty2)
copy into null_empty2
    from @mystage/data_0_0_0.csv.gz
    file_format = (format_name = 'my_csv_format');

select * from null_empty2;

+---+------+--------------+
| i | V    | D            |
|---+------+--------------|
| 1 | NULL | NULL value   |
| 2 |      | Empty string |
+---+------+--------------+
Copy

示例:在不使用引号的情况下卸载和加载数据

在以下示例中,一组数据从 null_empty1 表卸载到用户的暂存区。然后,使用输出数据文件将数据加载到 null_empty2 表中:

-- Source table (null_empty1) contents
+---+------+--------------+
| i | V    | D            |
|---+------+--------------|
| 1 | NULL | NULL value   |
| 2 |      | Empty string |
+---+------+--------------+

-- Create a file format that describes the data and the guidelines for processing it
create or replace file format my_csv_format
  empty_field_as_null=false null_if=('null');

-- Unload table data into a stage
copy into @mystage
  from null_empty1
  file_format = (format_name = 'my_csv_format');

-- Output the data file contents
1,null,NULL value
2,,Empty string

-- Load data from the staged file into the target table (null_empty2)
copy into null_empty2
    from @mystage/data_0_0_0.csv.gz
    file_format = (format_name = 'my_csv_format');

select * from null_empty2;

+---+------+--------------+
| i | V    | D            |
|---+------+--------------|
| 1 | NULL | NULL value   |
| 2 |      | Empty string |
+---+------+--------------+
Copy

卸载到单个文件

默认情况下,COPY INTO(后接指定位置)语句将表数据分隔开来,并输出到一组输出文件中,以利用并行操作。每个文件的大小上限是使用 MAX_FILE_SIZE copy 选项设置的。默认值为 16777216 (16 MB),不过可以增大,以容纳更大的文件。Amazon S3、Google Cloud Storage 或 Microsoft Azure 暂存区支持的最大文件大小为 5 GB。

要将数据卸载到单个输出文件(可能以降低性能为代价),请在语句中指定 SINGLE = true copy 选项。您可以选择指定路径中文件的名称。

备注

如果 COMPRESSION 选项设置为 true,请为压缩方法指定带有适当文件扩展名的文件名,以便解压缩输出文件。例如,如果指定了 GZIP 压缩方法,请指定 GZ 文件扩展名。

例如,将 mytable 表数据卸载到指定暂存区中名为 myfile.csv 的单个文件中。增加 MAX_FILE_SIZE 限值,以适应大型数据集:

copy into @mystage/myfile.csv.gz from mytable
file_format = (type=csv compression='gzip')
single=true
max_file_size=4900000000;
Copy

将关系表卸载到 JSON

可以将 OBJECT_CONSTRUCT 函数与 COPY 命令结合使用,从而将关系表中的行转换为单个 VARIANT 列,并将行卸载到文件中。

例如:

-- Create a table
CREATE OR REPLACE TABLE mytable (
 id number(8) NOT NULL,
 first_name varchar(255) default NULL,
 last_name varchar(255) default NULL,
 city varchar(255),
 state varchar(255)
);

-- Populate the table with data
INSERT INTO mytable (id,first_name,last_name,city,state)
 VALUES
 (1,'Ryan','Dalton','Salt Lake City','UT'),
 (2,'Upton','Conway','Birmingham','AL'),
 (3,'Kibo','Horton','Columbus','GA');

-- Unload the data to a file in a stage
COPY INTO @mystage
 FROM (SELECT OBJECT_CONSTRUCT('id', id, 'first_name', first_name, 'last_name', last_name, 'city', city, 'state', state) FROM mytable)
 FILE_FORMAT = (TYPE = JSON);

-- The COPY INTO location statement creates a file named data_0_0_0.json.gz in the stage.
-- The file contains the following data:

{"city":"Salt Lake City","first_name":"Ryan","id":1,"last_name":"Dalton","state":"UT"}
{"city":"Birmingham","first_name":"Upton","id":2,"last_name":"Conway","state":"AL"}
{"city":"Columbus","first_name":"Kibo","id":3,"last_name":"Horton","state":"GA"}
Copy

将关系表卸载到具有多个列的 Parquet

可以使用 SELECT 语句作为 COPY 语句的输入,从而将关系表中的数据卸载到多列 Parquet 文件中。SELECT 语句指定关系表中要包含在卸载文件中的列数据。使用 HEADER = TRUE copy 选项,将列标题包含在输出文件中。

例如,将 mytable 表中三个列 (idnamestart_date)中的行卸载到一个或多个具有指定格式 myfile.parquet 的文件中:

COPY INTO @mystage/myfile.parquet FROM (SELECT id, name, start_date FROM mytable)
  FILE_FORMAT=(TYPE='parquet')
  HEADER = TRUE;
Copy

将数值列显式转换为 Parquet 数据类型

默认情况下,将表数据卸载到 Parquet 文件时,定点数字 列将作为 DECIMAL 列卸载,而 浮点数字 列将作为 DOUBLE 列卸载。

若要为卸载的数据集选择 Parquet 数据类型,请在 COPY INTO <location> 语句中调用 CAST、:: 函数,将特定表列转换为显式数据类型。COPY INTO <location> 语句中的查询允许选择要卸载的特定列,并接受转换 SQL 函数以转换列数据。

COPY INTO <location> 语句中的查询支持 SELECT 语句的语法和语义,以查询要卸载的特定 Snowflake 表列。使用 CAST、:: 函数可将数值列中的数据转换为特定数据类型。

下表展示了 Snowflake 数值数据类型与 Parquet 物理和逻辑数据类型之间的映射:

Snowflake 逻辑数据类型

Parquet 物理数据类型

Parquet 逻辑数据类型

TINYINT

INT32

INT(8)

SMALLINT

INT32

INT(16)

INT

INT32

INT(32)

BIGINT

INT64

INT(64)

FLOAT

FLOAT

不适用

DOUBLE

DOUBLE

不适用

下面的示例演示了一个 COPY INTO <location> 语句,该语句将每个卸载列中的数值数据转换为不同的数据类型,以显式选择 Parquet 文件中的数据类型:

COPY INTO @mystage
FROM (SELECT CAST(C1 AS TINYINT) ,
             CAST(C2 AS SMALLINT) ,
             CAST(C3 AS INT),
             CAST(C4 AS BIGINT) FROM mytable)
FILE_FORMAT=(TYPE=PARQUET);
Copy

浮点数会被截断

浮点数 列卸载到 CSV 或 JSON 文件时,Snowflake 会将值截断为大约 (15,9)。

将浮点数列卸载到 Parquet 文件时,这些值 不会 被截断。

语言: 中文