教程:加载和卸载 Parquet 数据¶
简介¶
本教程介绍如何使用 COPY INTO <table> 命令,将暂存的 Parquet 文件的元素直接转换为表列,从而上传 Parquet 数据。本教程还介绍了如何使用 COPY INTO <location> 命令,将表数据卸载到 Parquet 文件中。
先决条件¶
本教程要求您:
下载 Snowflake 提供的 Parquet 数据文件。
创建数据库、表和一个虚拟仓库。
数据库、表和虚拟仓库是大多数 Snowflake 活动需要的基本 Snowflake 对象。
下载示例数据文件¶
要下载示例 Parquet 数据文件,请点击:download:cities.parquet</samples/cities.parquet>。或右键点击链接,然后将链接/文件保存到本地文件系统。
本教程假设已将文件解压到以下目录:
Linux/macOS:
/tmp/load
Windows:
C:\tempload
Parquet 数据文件中包含示例大陆数据。下面是一个代表性的示例:
{
"continent": "Europe",
"country": {
"city": [
"Paris",
"Nice",
"Marseilles",
"Cannes"
],
"name": "France"
}
}
创建数据库、表和虚拟仓库¶
以下命令创建本教程专用的对象。完成本教程后即可删除这些对象。
create or replace database mydatabase;
use schema mydatabase.public;
create or replace temporary table cities (
continent varchar default null,
country varchar default null,
city variant default null
);
create or replace warehouse mywarehouse with
warehouse_size='X-SMALL'
auto_suspend = 120
auto_resume = true
initially_suspended=true;
use warehouse mywarehouse;
请注意,这些命令会创建一个临时表。临时表仅在用户会话期间持续存在,并且其他用户无法看到这些表。
第 1 步:创建文件格式对象¶
执行 CREATE FILE FORMAT 命令以创建 sf_tut_parquet_format
文件格式。
CREATE OR REPLACE FILE FORMAT sf_tut_parquet_format
TYPE = parquet;
TYPE = 'parquet'
指示源文件格式类型。CSV 是默认文件格式类型。
第 2 步:创建暂存区对象¶
执行 CREATE STAGE 命令,创建内部 sf_tut_stage
暂存区。
CREATE OR REPLACE TEMPORARY STAGE sf_tut_stage
FILE_FORMAT = sf_tut_parquet_format;
与临时表类似,临时暂存区将在会话结束时自动删除。
第 3 步:暂存数据文件¶
执行 PUT 命令,将 parquet 文件从本地文件系统上传到指定的暂存区。
Linux 或 macOS
PUT file:///tmp/load/cities.parquet @sf_tut_stage;
Windows
PUT file://C:\temp\load\cities.parquet @sf_tut_stage;
第 4 步:将数据复制到目标表¶
将 cities.parquet
暂存数据文件复制到 CITIES
表。
copy into cities
from (select $1:continent::varchar,
$1:country:name::varchar,
$1:country:city::variant
from @sf_tut_stage/cities.parquet);
请注意以下事项:
SELECT 查询中的
$1
代表存储 Paraquet 数据的一个列。该查询将其检索到的每个 Parquet 元素值转换为特定列类型。
执行以下查询,以验证数据是否已复制。
SELECT * from cities;
查询返回以下结果:
+---------------+---------+-----------------+
| CONTINENT | COUNTRY | CITY |
|---------------+---------+-----------------|
| Europe | France | [ |
| | | "Paris", |
| | | "Nice", |
| | | "Marseilles", |
| | | "Cannes" |
| | | ] |
|---------------+---------+-----------------|
| Europe | Greece | [ |
| | | "Athens", |
| | | "Piraeus", |
| | | "Hania", |
| | | "Heraklion", |
| | | "Rethymnon", |
| | | "Fira" |
| | | ] |
|---------------+---------+-----------------|
| North America | Canada | [ |
| | | "Toronto", |
| | | "Vancouver", |
| | | "St. John's", |
| | | "Saint John", |
| | | "Montreal", |
| | | "Halifax", |
| | | "Winnipeg", |
| | | "Calgary", |
| | | "Saskatoon", |
| | | "Ottawa", |
| | | "Yellowknife" |
| | | ] |
+---------------+---------+-----------------+
第 5 步:卸载表¶
将 CITIES
表卸载到另一个 Parquet 文件中。
备注
默认情况下,Snowflake 会设置接受所有值的最小精度,从而优化卸载的 Parquet 数据文件中的表列。如果您更喜欢由“逻辑”列数据类型(即卸载 SQL 查询或源表中的类型)确定的一致输出文件架构,请将 ENABLE_UNLOAD_PHYSICAL_TYPE_OPTIMIZATION 会话参数设置为 FALSE。
copy into @sf_tut_stage/out/parquet_
from (select continent,
country,
c.value::string as city
from cities,
lateral flatten(input => city) c)
file_format = (type = 'parquet')
header = true;
请注意以下事项:
file_format = (type = 'parquet')
指定 parquet 作为暂存区中数据文件的格式。指定 Parquet 文件类型时,COPY INTO <location>
命令默认会将数据卸载到单独一列。header=true
选项指示命令保留输出文件中的列名。在嵌套的 SELECT 查询中:
FLATTEN 函数首先将
city
列数组元素展平到单独的列中。LATERAL 修饰符会将 FLATTEN 函数的输出与对象外部的信息联接起来,在本例中是
continent
和country
。
执行以下查询,验证数据是否已复制到暂存的 Parquet 文件中。
select t.$1 from @sf_tut_stage/out/ t;
查询返回结果如下(仅显示部分结果):
+---------------------------------+
| $1 |
|---------------------------------|
| { |
| "CITY": "Paris", |
| "CONTINENT": "Europe", |
| "COUNTRY": "France" |
| } |
|---------------------------------|
| { |
| "CITY": "Nice", |
| "CONTINENT": "Europe", |
| "COUNTRY": "France" |
| } |
|---------------------------------|
| { |
| "CITY": "Marseilles", |
| "CONTINENT": "Europe", |
| "COUNTRY": "France" |
| } |
+---------------------------------+
第 6 步:移除已成功复制的数据文件¶
确认已成功将数据从暂存区复制到表中后,可以使用 REMOVE 命令从内部暂存区中移除数据文件,从而保存到 数据存储 之中。
REMOVE @sf_tut_stage/cities.parquet;
第 7 步:清理¶
执行以下 DROP <object> 命令,将系统恢复到教程开始前的状态:
DROP DATABASE IF EXISTS mydatabase;
DROP WAREHOUSE IF EXISTS mywarehouse;
删除数据库会自动移除所有子数据库对象,例如表。