数据卸载注意事项¶
本主题提供从表中卸载数据的最佳实践、一般准则和重要注意事项。目的在于帮助更轻松地使用 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 |
+---+------+--------------+
示例:在不使用引号的情况下卸载和加载数据¶
在以下示例中,一组数据从 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 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;
将关系表卸载到 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"}
将关系表卸载到具有多个列的 Parquet¶
可以使用 SELECT 语句作为 COPY 语句的输入,从而将关系表中的数据卸载到多列 Parquet 文件中。SELECT 语句指定关系表中要包含在卸载文件中的列数据。使用 HEADER = TRUE
copy 选项,将列标题包含在输出文件中。
例如,将 mytable
表中三个列 (id
、name
、start_date
)中的行卸载到一个或多个具有指定格式 myfile.parquet
的文件中:
COPY INTO @mystage/myfile.parquet FROM (SELECT id, name, start_date FROM mytable)
FILE_FORMAT=(TYPE='parquet')
HEADER = TRUE;
将数值列显式转换为 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);
浮点数会被截断¶
将 浮点数 列卸载到 CSV 或 JSON 文件时,Snowflake 会将值截断为大约 (15,9)。
将浮点数列卸载到 Parquet 文件时,这些值 不会 被截断。