1. 使用 Google Cloud Storage 和 BigQuery 构建从 Snowflake 到 Spanner 的反向 ETL 流水线
简介
在此 Codelab 中,我们将构建一个从 Snowflake 到 Spanner 的反向 ETL 流水线。传统上,ETL(提取、转换、加载)流水线会将数据从运营数据库移至 Snowflake 等数据仓库以进行分析。反向 ETL 流水线则相反:它将经过整理和处理的数据从数据仓库移回运营系统,以便为应用提供支持、为面向用户的功能提供服务,或用于实时决策。
目标是将汇总数据集从 Snowflake Iceberg 表迁移到 Spanner(一种全球分布式关系型数据库,非常适合高可用性应用)。
为此,我们使用 Google Cloud Storage (GCS) 和 BigQuery 作为中间步骤。下面详细介绍了数据流以及此架构背后的原因:
- 以 Iceberg 格式将 Snowflake 数据导出到 Google Cloud Storage (GCS):
- 第一步是以开放且定义明确的格式从 Snowflake 中提取数据。表以 Apache Iceberg 格式导出。此过程会将底层数据写入为一组 Parquet 文件,并将表的元数据(架构、分区、文件位置)写入为 JSON 和 Avro 文件。在 GCS 中暂存此完整表结构可使数据具有可移植性,并且任何了解 Iceberg 格式的系统都可以访问这些数据。
- 将 GCS 中的 Iceberg 表转换为 BigQuery BigLake 外部表:
- 我们不直接将数据从 GCS 加载到 Spanner,而是将 BigQuery 用作强大的中间平台。您将在 BigQuery 中创建一个BigLake 外部表,该表直接指向 GCS 中的 Iceberg 元数据文件。这样做具有很多优势:
- 无数据重复:BigQuery 从元数据中读取表结构,并直接查询 Parquet 数据文件,而无需提取这些文件,从而节省大量时间和存储费用。
- 联合查询:它允许对 GCS 数据运行复杂的 SQL 查询,就像对原生 BigQuery 表运行查询一样。
- BigQuery to Spanner:
- 最后一步是将数据从 BigQuery 迁移到 Spanner。您将使用 BigQuery 中的一项强大功能(称为
EXPORT DATA查询)来实现此目的,这是“反向 ETL”步骤。 - 运营就绪状态:Spanner 专为事务性工作负载而设计,可为应用提供强一致性和高可用性。通过将数据迁移到 Spanner 中,面向用户的应用、API 和其他需要低延迟点查询的运营系统可以访问这些数据。
- 可伸缩性:此模式可利用 BigQuery 的分析能力来处理大型数据集,然后通过 Spanner 的全球可伸缩基础架构高效地提供结果。
服务和术语
- Snowflake - 一种云数据平台,提供数据仓库即服务。
- Spanner - 一款全代管式全球分布式关系型数据库。
- Google Cloud Storage - Google Cloud 的 Blob 存储服务。
- BigQuery - 一种全托管式无服务器数据仓库,可用于数据分析。
- Iceberg - 一种由 Apache 定义的开放表格式,可对常见的开源数据文件格式进行抽象化处理。
- Parquet - Apache 的一种开源列式二进制数据文件格式。
学习内容
- 如何将数据加载到 Snowflake 中
- 如何创建 GCS 存储分区
- 如何以 Iceberg 格式将 Snowflake 表导出到 GCS
- 如何设置 Spanner 实例
- 如何将 BigQuery 中的 BigLake 外部表加载到 Spanner 中
2. 设置、要求和限制
前提条件
- Snowflake 账号
- 若要从 BigQuery 导出到 Spanner,您需要拥有一个 Google Cloud 账号,并具有 BigQuery 企业级或更高级别的预留。
- 通过网络浏览器访问 Google Cloud 控制台
- 用于运行 Google Cloud CLI 命令的终端
- 如果您的 Google Cloud 组织已启用
iam.allowedPolicyMemberDomains政策,管理员可能需要授予例外权限,以允许来自外部网域的服务账号。我们将在后面的步骤中介绍相关内容(如适用)。
限制
请务必注意此流水线中可能会出现的一些限制和数据类型不兼容问题。
从 Snowflake 到 Iceberg
Snowflake 和 Iceberg 的列数据类型有所不同。如需了解有关在它们之间进行转换的信息,请参阅 Snowflake 文档。
Iceberg to BigQuery
使用 BigQuery 查询 Iceberg 表时,存在一些限制。如需查看完整列表,请参阅 BigQuery 文档。请注意,目前不支持 BIGNUMERIC、INTERVAL、JSON、RANGE 或 GEOGRAPHY 等类型。
BigQuery to Spanner
从 BigQuery 到 Spanner 的 EXPORT DATA 命令不支持所有 BigQuery 数据类型。导出具有以下类型的表格会导致错误:
STRUCTGEOGRAPHYDATETIMERANGETIME
此外,如果 BigQuery 项目使用的是 GoogleSQL 方言,则以下数值类型也不支持导出到 Spanner:
BIGNUMERIC
如需查看完整且最新的限制列表,请参阅官方文档:导出到 Spanner 的限制。
Snowflake
在此 Codelab 中,您可以使用现有的 Snowflake 账号,也可以设置免费试用账号。
Google Cloud Platform IAM 权限
Google 账号需要拥有以下权限才能执行此 Codelab 中的所有步骤。
服务账号 | ||
| 允许创建服务账号。 | |
Spanner | ||
| 允许创建新的 Spanner 实例。 | |
| 允许运行 DDL 语句来创建 | |
| 允许运行 DDL 语句以在数据库中创建表。 | |
Google Cloud Storage | ||
| 允许创建新的 GCS 存储分区来存储导出的 Parquet 文件。 | |
| 允许将导出的 Parquet 文件写入 GCS 存储分区。 | |
| 允许 BigQuery 从 GCS 存储分区读取 Parquet 文件。 | |
| 允许 BigQuery 列出 GCS 存储分区中的 Parquet 文件。 | |
Dataflow | ||
| 允许从 Dataflow 声明工作项。 | |
| 允许 Dataflow 工作器将消息发送回 Dataflow 服务。 | |
| 允许 Dataflow 工作器将日志条目写入 Google Cloud Logging。 | |
为方便起见,您可以使用包含这些权限的预定义角色。
|
|
|
|
|
|
|
|
设置可重复使用的属性
在本实验中,您将需要反复使用一些值。为简化操作,我们将这些值设置为 shell 变量,以便稍后使用。
- GCP_REGION - GCP 资源将位于的特定区域。如需查看区域列表,请点击此处。
- GCP_PROJECT - 要使用的 GCP 项目 ID。
- GCP_BUCKET_NAME - 要创建的 GCS 存储分区名称,也是存储数据文件的位置。
export GCP_REGION = <GCP REGION HERE>
export GCP_PROJECT= <GCP PROJECT HERE>
export GCS_BUCKET_NAME = <GCS BUCKET NAME HERE>
export SPANNER_INSTANCE = <SPANNER INSTANCE ID HERE>
export SPANNER_DB = <SPANNER DATABASE ID HERE>
Google Cloud 项目
项目是 Google Cloud 中的基本组织单元。如果管理员已提供可供使用的密钥,则可以跳过此步骤。
您可以使用如下所示的 CLI 创建项目:
gcloud projects create $GCP_PROJECT
gcloud config set project $GCP_PROJECT
如需详细了解如何创建和管理项目,请点击此处。
设置 Spanner
如需开始使用 Spanner,您需要预配一个实例和一个数据库。如需详细了解如何配置和创建 Spanner 实例,请点击此处。
创建实例
gcloud spanner instances create $SPANNER_INSTANCE \
--config=regional-$GCP_REGION \
--description="Codelabs Snowflake RETL" \
--processing-units=100 \
--edition=ENTERPRISE
创建数据库
gcloud spanner databases create $SPANNER_DB \
--instance=$SPANNER_INSTANCE
3. 创建 Google Cloud Storage 存储分区
Google Cloud Storage (GCS) 将用于存储 Snowflake 生成的 Parquet 数据文件和 Iceberg 元数据。为此,您首先需要创建一个新存储分区作为文件目标位置。在本地机器上的终端窗口中,按照以下步骤操作。
创建存储桶
使用以下命令在特定区域(例如 us-central1)中创建存储分区。
gcloud storage buckets create gs://$GCS_BUCKET_NAME --location=$GCP_REGION
验证存储分区创建
该命令成功执行后,列出所有存储分区以检查结果。新存储分区应显示在结果列表中。存储分区引用通常会在存储分区名称前面显示 gs:// 前缀。
gcloud storage ls | grep gs://$GCS_BUCKET_NAME
测试写入权限
此步骤可确保本地环境已正确通过身份验证,并且拥有将文件写入新创建的存储分区的必要权限。
echo "Hello, GCS" | gcloud storage cp - gs://$GCS_BUCKET_NAME/hello.txt
验证上传的文件
列出存储分区中的对象。系统应显示刚刚上传的文件的完整路径。
gcloud storage ls gs://$GCS_BUCKET_NAME
您应该会看到以下输出内容:
gs://$GCS_BUCKET_NAME/hello.txt
如需查看存储分区中对象的内容,可以使用 gcloud storage cat。
gcloud storage cat gs://$GCS_BUCKET_NAME/hello.txt
文件内容应可见:
Hello, GCS
清理测试文件
Cloud Storage 存储分区现已设置完毕。现在可以删除临时测试文件了。
gcloud storage rm gs://$GCS_BUCKET_NAME/hello.txt
输出应确认删除:
Removing gs://$GCS_BUCKET_NAME/hello.txt... / [1 objects] Operation completed over 1 objects.
4. 从 Snowflake 导出到 GCS
在本实验中,您将使用 TPC-H 数据集,这是决策支持系统的行业标准基准。该架构可模拟包含客户、订单、供应商和零件的真实业务环境,非常适合演示实际的数据分析和数据移动场景。默认情况下,所有 Snowflake 账号都可以使用此数据集。
您将创建一个新的汇总表,而不是使用原始的标准化 TPC-H 表。此新表将联接 orders、customer 和 nation 表中的数据,以生成非规范化的全国销售总额汇总视图。这种预聚合步骤是分析中的常见做法,因为它可以为特定使用情形(在本场景中,是供运营应用使用)准备数据。
允许 Snowflake 访问 Google Cloud Storage
如需允许 Snowflake 将数据写入 GCS 存储分区,您需要创建两项内容:外部卷和必要的权限。
- 外部卷是一种 Snowflake 对象,可提供指向 GCS 存储分区中特定位置的安全链接。它本身不存储数据,而是保存 Snowflake 访问云存储所需的配置。
- 出于安全考虑,云存储分区默认设为私享。创建外部卷时,Snowflake 会生成一个专用服务账号。必须向此服务账号授予从相应存储分区读取数据和向相应存储分区写入数据的权限。
创建数据库
- 在左侧菜单的 Horizon Catalog 下,将光标悬停在 Catalog 上,然后点击 Database Explorer
- 进入数据库页面后,点击右上角的 + 数据库按钮。
- 将新数据库命名为
codelabs_retl_db
创建工作表
如需针对数据库运行 SQL 命令,您需要工作表。
如需创建工作表,请执行以下操作:
- 在左侧菜单的处理数据下,将光标悬停在项目上,然后点击工作区
- 在我的工作区边栏下,点击 + 添加新内容按钮,然后选择 SQL 文件
创建外部卷
在 Snowflake 工作表中运行以下命令以创建卷。
CREATE EXTERNAL VOLUME codelabs_retl_ext_vol
STORAGE_LOCATIONS =
(
(
NAME = 'codelabs_retl_ext_vol'
STORAGE_PROVIDER = 'GCS'
STORAGE_BASE_URL = 'gcs://<Your bucket name>/snowflake_extvol'
)
);
获取 Snowflake 服务账号
DESC(描述)新创建的外部卷,以获取 Snowflake 为其生成的唯一服务账号。
DESC EXTERNAL VOLUME codelabs_retl_ext_vol;
- 在结果窗格中,查找 JSON 属性,找到包含以
"NAME":"codelabs_retl_ext_vol"开头的 JSON 字符串的property_value条目 - 在 JSON 对象中找到
STORAGE_GCP_SERVICE_ACCOUNT属性,然后复制其值(看起来像电子邮件地址)。这是需要访问 GCS 存储分区的服务账号标识符。 - 将此服务账号存储到 shell 实例中的环境变量中,以便日后重复使用
export GCP_SERVICE_ACCOUNT=<Your service account>
向 Snowflake 授予 GCS 权限
现在,必须向 Snowflake 服务账号授予写入 GCS 存储分区的权限。
gcloud storage buckets add-iam-policy-binding gs://$GCS_BUCKET_NAME \
--member="serviceAccount:$GCP_SERVICE_ACCOUNT" \
--role="roles/storage.objectAdmin"
gcloud storage buckets add-iam-policy-binding gs://$GCS_BUCKET_NAME \
--member="serviceAccount:$GCP_SERVICE_ACCOUNT" \
--role="roles/storage.legacyBucketReader"
验证 Snowflake 中的访问权限
返回到 Snowflake 工作表,运行以下命令以验证 Snowflake 现在是否可以成功连接到 GCS 存储分区。
SELECT SYSTEM$VERIFY_EXTERNAL_VOLUME('codelabs_retl_ext_vol');
结果应为包含 "success":true 的 JSON 对象。
如需详细了解 Snowflake 中的外部卷,请参阅官方文档。
导出示例订单数据
现在,您可以在 Snowflake 中创建 Iceberg 表了。以下命令指示 Snowflake 运行查询,并使用 Iceberg 格式将结果存储在 GCS 中。数据文件将为 Parquet 格式,元数据将为 Avro 和 JSON 格式,所有这些文件都将存储在 codelabs_retl_ext_vol 外部卷定义的位置。
创建数据库
- 在左侧菜单的 Horizon Catalog 下,将光标悬停在 Catalog 上,然后点击 Database Explorer
- 进入数据库页面后,点击右上角的 + 数据库按钮。
- 将新数据库命名为
codelabs_retl_db
USE DATABASE codelabs_retl_db;
CREATE ICEBERG TABLE REGIONAL_SALES_ICEBERG (
NATION_NAME STRING,
MARKET_SEGMENT STRING,
ORDER_YEAR INTEGER,
ORDER_PRIORITY STRING,
TOTAL_ORDER_COUNT INTEGER,
TOTAL_REVENUE NUMBER(24,2),
UNIQUE_CUSTOMER_COUNT INTEGER
)
EXTERNAL_VOLUME = 'codelabs_retl_ext_vol'
CATALOG = 'SNOWFLAKE'
BASE_LOCATION = 'regional_sales_iceberg'
AS (
SELECT
n.n_name AS nation_name,
c.c_mktsegment AS market_segment,
YEAR(o.o_orderdate) AS order_year,
o.o_orderpriority AS order_priority,
COUNT(o.o_orderkey) AS total_order_count,
ROUND(SUM(o.o_totalprice), 2) AS total_revenue,
COUNT(DISTINCT c.c_custkey) AS unique_customer_count
FROM SNOWFLAKE_SAMPLE_DATA.TPCH_SF1.orders AS o
INNER JOIN SNOWFLAKE_SAMPLE_DATA.TPCH_SF1.customer AS c
ON o.o_custkey = c.c_custkey
INNER JOIN SNOWFLAKE_SAMPLE_DATA.TPCH_SF1.nation AS n
ON c.c_nationkey = n.n_nationkey
GROUP BY
n.n_name,
c.c_mktsegment,
YEAR(o.o_orderdate),
o.o_orderpriority
);
如需详细了解如何使用 Snowflake 创建和管理 Iceberg 表,请参阅官方文档。
验证 GCP 中的数据
现在,检查 GCS 存储分区。您应该会看到 Snowflake 创建的文件。这表示导出成功。Iceberg 元数据将位于 metadata 文件夹中,实际数据将以 Parquet 文件的形式位于 data 文件夹中。
gcloud storage ls "gs://$GCS_BUCKET_NAME/snowflake_extvol/**"
确切的文件名会有所不同,但结构应如下所示:
gs://$GCS_BUCKET_NAME/snowflake_extvol/ gs://$GCS_BUCKET_NAME/snowflake_extvol/regional_sales_iceberg.snvrAWuR/data/snow_cbsKIRmdDmo_wLg128fugxg_0_2_009.parquet ... gs://$GCS_BUCKET_NAME/snowflake_extvol/regional_sales_iceberg.snvrAWuR/metadata/00001-62f831ff-6708-4494-94c5-c891b7ad447f.metadata.json ...
现在,数据已从 Snowflake 复制到 Google Cloud Storage 中,并采用 Iceberg 格式。
既然我们已经有了这个列表,不妨将 metadata.json 文件保存到一个环境变量中,因为我们稍后会用到它。
export GCS_METADATA_JSON=$(gcloud storage ls "gs://$GCS_BUCKET_NAME/snowflake_extvol/**" | grep .metadata.json)
5. 配置 BigQuery 外部表
现在,Iceberg 表已位于 Google Cloud Storage 中,下一步是让 BigQuery 可以访问该表。为此,您可以创建 BigLake 外部表。
BigLake 是一种存储引擎,可用于在 BigQuery 中创建直接从 Google Cloud Storage 等外部来源读取数据的表。对于本实验,它是使 BigQuery 能够了解刚刚导出的 Iceberg 表的关键技术,而无需注入数据。
为了实现此目的,我们需要两个组件:
- Cloud 资源连接:这是 BigQuery 与 GCS 之间的安全链接。它使用特殊的服务账号来处理身份验证,确保 BigQuery 具有从 GCS 存储分区读取文件所需的权限。
- 外部表定义:此定义会告知 BigQuery 在 GCS 中查找 Iceberg 表的元数据文件的位置以及应如何解读该文件。
配置与 Google Cloud Storage 的连接
首先,系统会创建允许 BigQuery 访问 GCS 的连接。此命令会在 BigQuery 中创建连接资源。
bq mk \
--connection \
--project_id=$GCP_PROJECT \
--location=$GCP_REGION \
--connection_type=CLOUD_RESOURCE \
codelabs-retl-connection
成功响应应如下所示:
Connection 12345678.region.codelabs-retl-connection successfully created
如需详细了解 BigQuery 中的 Cloud 资源连接,请参阅 Google Cloud 文档。
授权 BigQuery 连接读取数据
新的 BigQuery 连接有自己的服务账号,该账号需要获得从 Google Cloud Storage 存储分区读取数据的权限。
1. 获取连接服务账号
首先,从刚刚创建的连接中获取服务账号 ID:
bq show \
--location $GCP_REGION \
--connection codelabs-retl-connection
结果将显示一个包含匹配连接的表格。
我们将 serviceAccountId 设置为环境变量,以供稍后使用。
export GCP_BQ_SERVICE_ACCOUNT=<Your service account email>
2. 授予权限
运行以下命令,授权服务账号查看 GCS 存储分区中的数据。
gcloud storage buckets add-iam-policy-binding \
gs://$GCS_BUCKET_NAME \
--member serviceAccount:$GCP_BQ_SERVICE_ACCOUNT \
--role roles/storage.objectViewer
创建外部表
现在,在 BigQuery 中创建 BigLake 外部表。此命令不会移动任何数据。它只是在 GCS 中创建指向现有数据的指针。您需要提供 Snowflake 创建的某个 .metadata.json 文件的路径。
bq mk --dataset --location=$GCP_REGION codelabs_retl
bq mk \
--table \
--location=$GCP_REGION \
--external_table_definition=ICEBERG=$GCS_METADATA_JSON@projects/$GCP_PROJECT/locations/$GCP_REGION/connections/codelabs-retl-connection \
codelabs_retl.regional_sales
验证 BigQuery 中的数据
现在,您可以使用标准 SQL 查询此表,就像查询任何其他 BigQuery 表一样。BigQuery 将使用该连接从 GCS 动态读取 Parquet 文件。
bq query \
--location=$GCP_REGION \
--nouse_legacy_sql "SELECT * FROM \`$GCP_PROJECT.codelabs_retl.regional_sales\` LIMIT 10;"
6. 将数据从 BigQuery 导入到 Spanner:最后一步
流水线的最后也是最重要的部分已经完成:将数据从 BigLake 表移至 Spanner。这是“反向 ETL”步骤,其中数据在数据仓库中经过处理和整理后,会被加载到运营系统中供应用使用。
Spanner 是一种全代管式全球分布式关系型数据库。它提供传统关系型数据库的事务一致性,但具有 NoSQL 数据库的横向可伸缩性。因此,它是构建可扩缩且高度可用的应用的理想选择。
流程如下:
- 在 Spanner 数据库中创建与数据结构匹配的表架构。
- 运行 BigQuery
EXPORT DATA查询,将数据直接从 BigLake 表加载到 Spanner 表中。
创建 Spanner 表
在从 BigQuery 转移数据之前,必须在 Spanner 中创建一个具有兼容架构的目标表。
gcloud spanner databases ddl update $SPANNER_DB \
--instance=$SPANNER_INSTANCE \
--ddl="$(cat <<EOF
CREATE TABLE regional_sales (
nation_name STRING(MAX),
market_segment STRING(MAX),
order_year INT64,
order_priority STRING(MAX),
total_order_count INT64,
total_revenue NUMERIC,
unique_customer_count INT64
) PRIMARY KEY (nation_name, market_segment, order_year, order_priority);
EOF
)"
从 BigQuery 导出数据
这是最后一步。在 BigQuery BigLake 表中准备好源数据,并在 Spanner 中创建目标表后,实际的数据迁移过程非常简单。系统将使用单个 BigQuery SQL 查询:EXPORT DATA。
此查询专门针对此类场景而设计。它可以高效地将数据从 BigQuery 表(包括 BigLake 表等外部表)导出到外部目标位置。在这种情况下,目标是 Spanner 表。
bq query --location=$GCP_REGION --use_legacy_sql=false <<EOF
EXPORT DATA OPTIONS (
uri="https://spanner.googleapis.com/projects/${GCP_PROJECT}/instances/${SPANNER_INSTANCE}/databases/${SPANNER_DB}",
format='CLOUD_SPANNER',
spanner_options="""{
"table": "regional_sales",
"priority": "HIGH"
}"""
) AS
SELECT * FROM \`${PROJECT_ID}.codelabs_retl.regional_sales\`
EOF
查询完成后,“结果”窗格应显示“更新完成”。
7. 验证 Spanner 中的数据
恭喜!已成功构建并执行完整的反向 ETL 流水线。最后一步是验证数据是否已按预期到达 Spanner。
gcloud spanner databases execute-sql \
--instance=$SPANNER_INSTANCE \
$SPANNER_DB \
--sql='SELECT * FROM regional_sales LIMIT 10'
导入的示例数据会按要求显示:
nation_name market_segment order_year order_priority total_order_count total_revenue unique_customer_count ALGERIA AUTOMOBILE 1992 1-URGENT 375 59232423.66 298 ALGERIA AUTOMOBILE 1992 2-HIGH 328 47371891.08 269 ALGERIA AUTOMOBILE 1992 3-MEDIUM 346 52823195.87 262 ALGERIA AUTOMOBILE 1992 4-NOT SPECIFIED 365 52935998.34 288 ALGERIA AUTOMOBILE 1992 5-LOW 380 54920263.68 293 ALGERIA AUTOMOBILE 1993 1-URGENT 394 63145618.78 312 ALGERIA AUTOMOBILE 1993 2-HIGH 340 50737488.4 277 ALGERIA AUTOMOBILE 1993 3-MEDIUM 383 55871057.46 298 ALGERIA AUTOMOBILE 1993 4-NOT SPECIFIED 365 56424662.05 291 ALGERIA AUTOMOBILE 1993 5-LOW 363 54673249.06 283
分析型数据世界与运营型数据世界之间的差距已成功弥合。
8. 清理
清理 Spanner
删除 Spanner 数据库和实例
gcloud spanner instances delete $SPANNER_INSTANCE
清理 GCS
删除为托管数据而创建的 GCS 存储分区
gcloud storage rm --recursive gs://$GCS_BUCKET_NAME
清理 BigQuery
bq rm -r codelabs_retl
bq rm --connection --location=$GCP_REGION codelabs-retl-connection
清理 Snowflake
删除数据库
- 在左侧菜单的 Horizon Catalog 下,将光标悬停在 Catalog 上,然后点击 Database Explorer
- 点击
CODELABS_RETL_DB数据库右侧的 ... 以展开选项,然后选择 Drop - 在随即显示的确认对话框中,选择 Drop Database
删除工作簿
- 在左侧菜单的处理数据下,将光标悬停在项目上,然后点击工作区
- 在我的工作区边栏中,将鼠标悬停在此实验中使用的不同工作区文件上,以显示其他选项,然后点击该选项
- 选择删除,然后在随即显示的确认对话框中再次选择删除。
- 针对您为此实验创建的所有 SQL 工作区文件执行此操作。
删除外部卷
- 在左侧菜单的 Horizon Catalog 下,将光标悬停在 Catalog 上,然后点击 External Data
- 点击
CODELABS_RETL_EXT_VOL右侧的
,然后选择舍弃外部卷,然后在确认对话框中再次点击舍弃外部卷
9. 恭喜
恭喜您完成此 Codelab。
所学内容
- 如何将数据加载到 Snowflake 中
- 如何创建 GCS 存储分区
- 如何以 CSV 格式将 Snowflake 表导出到 GCS
- 如何设置 Spanner 实例
- 如何使用 Dataflow 将 CSV 表加载到 Spanner