Dataform 概览

本文档介绍了 Dataform 的概念和流程。

Dataform 是一种供数据分析师开发、测试、控制版本和安排复杂工作流以在 BigQuery 中进行数据转换的服务。

借助 Dataform,您可以在数据集成的提取、加载和转换 (ELT) 流程中管理数据转换。从源系统中提取原始数据并将其加载到 BigQuery 后,Dataform 可帮助您将其转换为定义明确、经过测试且记录完善的数据表套件。

借助 Dataform,您可以执行以下数据转换操作:

  • 开发和运行数据转换工作流。
  • 通过 Git 与团队成员协作开发工作流。
  • 管理大量表及其依赖项。
  • 声明源数据并管理表依赖项。
  • 查看工作流依赖项树的可视化呈现。
  • 在中央代码库中使用 SQL 代码管理数据。
  • 使用 JavaScript 重复使用代码。
  • 通过对源表和输出表进行质量测试来测试数据的正确性。
  • 对 SQL 代码进行版本控制。
  • 在 SQL 代码中记录数据表。

Dataform 中的数据转换流程

Dataform 的数据转换工作流如下:

  1. 借助 Dataform,您可以创建代码库来管理代码。
  2. 借助 Dataform,您可以创建工作区进行开发。
  3. 借助 Dataform,您可以在开发工作区中开发工作流。
  4. Dataform 将 Dataform 核心编译为 SQL。
  5. Dataform 运行依赖项树。

借助 Dataform,您可以创建代码库来管理代码

在 Dataform 代码库中,您可以使用 Dataform 核心(SQL 的扩展) 编写 SQLX 文件,并在其中定义工作流。Dataform 代码库支持版本控制。您可以将 Dataform 代码库关联到 第三方 Git 提供方

借助 Dataform,您可以创建工作区进行开发

您可以在 开发工作区 中创建 Dataform 代码库,以进行 Dataform 核心开发。在开发工作区中,您可以更改代码库、编译、测试,并通过 Git 将其推送到主代码库。

借助 Dataform,您可以在开发工作区中开发 Dataform 核心

在开发工作区中,您可以定义表及其依赖项和转换逻辑,并记录这些内容,以构建工作流。 您还可以在 JavaScript 中配置操作

Dataform 编译 Dataform 核心

编译期间,Dataform 会执行以下 任务:

  • 将 Dataform 核心编译为标准 SQL 工作流。
  • 将样板 SQL 语句(例如 CREATE TABLEINSERT)添加到与查询配置内联的代码中。
  • 将 JavaScript 转译(源到源编译)为 SQL。
  • 解析依赖项并检查错误,包括缺失或循环依赖项。
  • 构建要在 BigQuery 中运行的所有操作的依赖项树。

Dataform 编译是密封的,用于验证编译一致性,这意味着相同的代码每次都会编译为相同的 SQL 编译结果。 Dataform 会在无法访问互联网的沙盒环境中编译代码。在编译期间,无法执行其他操作,例如调用外部 API。

如需实时调试,您可以在开发工作区中的交互式图表中检查项目的已编译工作流。

Dataform 运行依赖项树

在 BigQuery 中,Dataform 会执行以下任务:

  • 按照依赖项树的顺序运行 SQL 命令。
  • 针对表和视图运行断言查询,以检查数据的正确性。
  • 运行您定义的其他 SQL 操作。
  • 更新 Knowledge Catalog (预览版)中的元数据。

执行后,您可以使用表和视图进行所有分析。

您可以查看日志,了解创建了哪些表、断言是否通过或失败、每个操作完成所需的时间以及其他信息。您还可以查看在 BigQuery 中运行的确切 SQL 代码。

Dataform 功能

借助 Dataform,您可以开发表、增量表或视图并将其部署到 BigQuery。Dataform 为以下活动提供 Web 环境:

  • 工作流开发
  • 与 GitHub、GitLab、Azure DevOps Services 和 Bitbucket 建立连接
  • 持续集成和持续部署
  • 执行工作流

以下部分介绍了 Dataform 的主要功能。

代码库

每个 Dataform 项目都存储在一个 代码库中。 Dataform 代码库包含一系列 JSON 配置文件、SQLX 文件和 JavaScript 文件。

Dataform 代码库包含以下类型的文件:

  • 配置文件

    借助配置 JSON 或 SQLX 文件,您可以配置工作流。 它们包含用于创建新表和视图的常规配置、执行时间表或架构。

  • 定义

    定义是 SQLX 和 JavaScript 文件,用于定义要在 BigQuery 中运行的新表、视图、 以及 其他 SQL 操作

  • 包含

    包含 是 JavaScript 文件,您可以在其中定义要在 项目中使用的变量和函数。

每个 Dataform 代码库都必须连接到自定义服务账号。您可以在创建代码库时选择自定义服务帐号。您可以 稍后修改服务账号

版本控制

Dataform 使用 Git 版本控制系统来维护对项目文件所做的每项更改的记录,并管理文件版本。

每个 Dataform 代码库都可以管理自己的 Git 代码库,也可以连接到远程第三方 Git 代码库。您可以 将 Dataform 代码库连接到 GitHub、GitLab、Azure DevOps Services 或 Bitbucket 代码库

用户可以在 Dataform 工作区内 对其工作流代码进行版本控制 。在 Dataform 工作区中,您可以从代码库拉取更改、提交所有或所选更改,并将其推送到代码库的 Git 分支。

工作流开发

在 Dataform 中,您可以在 开发工作区内更改文件和目录。 开发工作区是 Git 代码库内容的虚拟可修改副本。Dataform 会在会话之间保留开发工作区中文件的状态。

在开发工作区中,您可以 开发工作流操作 ,方法是使用Dataform 核心(包含 SQLX 和 JavaScript)或 仅使用 JavaScript。 您可以自动设置 Dataform 核心或 JavaScript 代码的格式。

Dataform 工作流的每个元素(例如表或断言)都对应于 Dataform 在 BigQuery 中执行的操作。 例如,表定义文件是在 BigQuery 中创建或更新表的操作。

在 Dataform 工作区中,您可以开发以下工作流操作:

您可以使用 JavaScript 通过以下方式重复使用 Dataform 工作流代码:

Dataform 会实时编译工作区中的工作流代码。 在工作区中,您可以查看每个文件中已编译的查询和操作详细信息。您还可以在已编辑的文件或代码库中查看编译状态和错误。

如需在将已编译的 SQL 查询运行到 BigQuery 之前对其输出进行测试,您可以在 Dataform 工作区中运行查询预览

如需检查工作区中定义的整个工作流,您可以 查看交互式编译图 ,该图显示了工作流中的所有已编译操作及其之间的关系。

工作流编译

Dataform 使用默认编译设置, 在工作流设置文件中配置, 将工作区中的工作流代码实时编译为 SQL, 从而创建工作区的编译结果。

您可以替换编译设置,以自定义 Dataform 将工作流编译为编译结果的方式。

借助 工作区编译替换, 您可以为代码库中的所有工作区配置编译替换。 您可以设置动态工作区替换,为每个工作区创建自定义编译结果,将工作区转换为隔离的开发环境。 您可以替换 Google Cloud Dataform 在其中运行工作区内容的 project,为所有已编译表的名称添加前 101}缀,并为默认架构添加后缀。

借助 发布配置, 您可以配置编译设置模板,以创建 Dataform 代码库的编译 结果。在发布配置中,您可以 替换 Dataform Google Cloud 在其中运行编译结果的 project,为所有已编译表的名称添加前缀,为默认架构添加 后缀,并添加编译变量。您还可以设置创建编译结果的频率。如需安排在所选发布配置中创建的编译 结果的运行,您可以 创建工作流配置

工作流运行

在工作流运行期间,Dataform 会运行工作流的编译结果,以在 BigQuery 中创建或更新资产。

如需在 BigQuery 中创建或刷新工作流中定义的表和视图,您可以 在开发工作区中手动启动工作流运行 ,或安排运行。

当您触发工作流运行时,Dataform 会按照依赖项定义的顺序执行操作。对于每个操作,Dataform 会执行以下步骤:

  1. 在 BigQuery 中执行已编译的 SQL。
  2. 更新执行日志中的操作状态。
  3. 操作成功完成后,Dataform 会自动启动元数据同步到 Knowledge Catalog (预览版)。 此丰富过程会使用 SQLX 配置中定义的语义元数据更新 Knowledge Catalog。 同步是异步进行的,并使用重试机制,确保元数据更新不会影响流水线延迟或导致工作流失败(如果 Dataplex API 暂时不可用)。

您可以通过以下方式在 BigQuery 中安排 Dataform 运行:

您还可以 使用 Cloud Build 触发器自动运行

如需调试错误,您可以通过以下方式监控运行:

Dataform 核心

Dataform 核心是一种开源元语言,用于创建 SQL 表和工作流。Dataform 核心通过提供依赖项管理系统、自动数据质量测试和数据文档来扩展 SQL。

您可以使用 Dataform 核心执行以下操作:

  • 定义表、视图、具体化视图或增量表。
  • 定义数据转换逻辑。
  • 声明源数据并管理表依赖项。
  • 在代码中记录表和列说明。
  • 在不同的查询中重复使用函数和变量。
  • 编写数据断言以验证数据一致性。

在 Dataform 中,您可以使用 Dataform 核心开发工作流并将资产部署到 BigQuery。

Dataform 核心是 开源 Dataform 数据建模框架 的一部分,该框架还包括 Dataform CLI。 您可以在 Dataform CLI 之外通过 Dataform CLI 在本地编译和运行 Dataform 核心 Google Cloud。

如需使用 Dataform 核心,您需要编写 SQLX 文件。每个 SQLX 文件都包含一个查询,该查询定义了 Dataform 在 BigQuery 中创建和更新的数据库关系。

Dataform 会实时编译 Dataform 核心代码,以创建可在 BigQuery 中运行的 SQL 编译结果。

Dataform 编译是密封的,用于验证编译一致性,这意味着相同的代码每次都会编译为相同的 SQL 编译结果。 Dataform 会在无法访问互联网的沙盒环境中编译代码。在编译期间,无法执行其他操作,例如调用外部 API。

SQLX 文件配置块

SQLX 文件由配置块和正文组成。所有配置属性和配置块本身都是可选的。鉴于此,任何纯 SQL 文件都是 Dataform 按原样运行的有效 SQLX 文件。

在配置块中,您可以执行以下操作:

指定查询元数据

您可以使用配置元数据配置 Dataform 如何将查询具体化到 BigQuery 中,例如输出表类型、目标数据库或标签。

记录数据

您可以直接在配置块中记录表 及其字段。表的文档会 直接推送到 BigQuery 和 Knowledge Catalog (预览版)。 您可以解析此文档并将其推送给其他工具。

以下代码示例展示了如何在 SQLX 文件的配置块中定义输出表类型、记录表以及为 Knowledge Catalog 添加元数据:

config {
  type: "table",
  description: "This table joins orders information from OnlineStore & payment information from PaymentApp",
  columns: {
    order_date: "The date when a customer placed their order",
    id: "Order ID as defined by OnlineStore",
    order_status: "The status of an order, for example, sent, delivered",
    customer_id: "Unique customer ID",
    payment_status: "The status of a payment, for example, pending, paid",
    payment_method: "How the customer chose to pay",
    item_count: "The number of items the customer ordered",
    amount: "The amount the customer paid"
  },
  metadata: {
    overview: "This table provides joined orders and payment data.",
    extraProperties: {
      generic: {
        system: "BigQuery",
        type: "table"
      }
    }
  }
}

定义数据质量测试

您可以定义数据质量测试(称为 断言), 来检查唯一性、null 值或自定义条件。 Dataform 会在创建表后将配置块中定义的断言添加到工作流依赖项树中。您还可以在配置块之外的单独 SQLX 文件中定义断言。

以下代码示例展示了如何在 SQLX 文件的配置块中定义质量测试:

config {
  assertions: {
    uniqueKey: ["id"]
  }
}

SQLX 文件正文

在 SQLX 文件的正文中,您可以执行以下操作:

定义表

如需定义新表,您可以使用 SQL SELECT 语句和 ref 函数。

ref 函数是 SQLX 内置函数,对于 Dataform 中的依赖项管理至关重要。借助 ref 函数,您可以引用 Dataform 项目中定义的表,而不是对数据表的架构和表名称进行硬编码。

Dataform 使用 ref 函数构建要创建或更新的所有表的依赖项树。编译后,Dataform 会添加 CREATEREPLACEINSERT 等样板语句。

以下代码示例展示了如何使用 ref 函数在 SQLX 文件中引用表。

config { type: "table" }

SELECT
  order_date AS date,
  order_id AS order_id,
  order_status AS order_status,
  SUM(item_count) AS item_count,
  SUM(amount) AS revenue

FROM ${ref("store_clean")}

GROUP BY 1, 2, 3

输出类似于以下内容:

CREATE OR REPLACE TABLE Dataform.orders AS

SELECT
  order_date AS date,
  order_id AS order_id,
  order_status AS order_status,
  SUM(item_count) AS item_count,
  SUM(amount) AS revenue

FROM Dataform_stg.store_clean

GROUP BY 1, 2, 3

如需详细了解其他依赖项管理(例如 有条件地执行代码、使用其他 Dataform 核心内置 函数),请参阅Dataform 核心参考

定义其他 SQL 操作

如需将 Dataform 配置为在创建表或视图之前或 之后运行一个或多个 SQL 语句,您可以 指定预查询和后查询操作

以下代码示例展示了如何在后查询操作中配置表或视图访问权限。

SELECT * FROM ...

post_operations {
  GRANT `roles/bigquery.dataViewer` ON TABLE ${self()} TO "group:someusers@dataform.co"
}

封装 SQL 代码

如需定义可重复使用的函数来生成 SQL 代码的重复部分,您可以使用 JavaScript 块。您只能在定义 JavaScript 块的 SQLX 文件内重复使用该块中定义的代码。如需在整个代码库中重复使用代码,您可以 创建包含

如需动态修改查询,您可以在正文中的任何位置使用内嵌 JavaScript。

以下代码示例展示了如何在 SQLX 文件中定义 JavaScript 块,并在查询中内嵌使用该块:

js {
  const columnName = "foo";
}

SELECT 1 AS ${columnName} FROM "..."

限制

Dataform 存在以下已知限制:

  • Dataform 在 Google Cloud 纯 V8 运行时中运行,不 支持 Node.js 提供的其他功能和模块。如果您的 现有代码库需要任何 Node.js 模块, 您需要移除这些依赖项。

    如果 package.json 中没有名称字段,则每次安装软件包时,系统都会在 package-lock.json 上生成差异。如需避免此结果,您需要在 package.json 中添加 name 属性。

  • 不支持 package.json 中依赖项的 git+https:// 网址。

    将此类网址转换为纯 https:// 归档网址。 例如,将 git+https://github.com/dataform-co/dataform-segment.git#1.5 转换为 https://github.com/dataform-co/dataform-segment/archive/1.5.tar.gz

  • 无法手动运行单元测试。

  • 无法在开发工作区中搜索文件内容。

  • Dataform 核心 3.0.0. 开始, Dataform 不会分发 Docker 映像。您可以构建自己的 Dataform Docker 映像,该映像可用于运行等效于 Dataform CLI 命令的命令。如需构建自己的 Docker 映像,请参阅 Docker 文档中的 “容器化应用”

  • 以下 Dataform API 方法不符合 AIP.134 指南,因为它们将 * 通配符条目视为错误请求,并在省略 field_mask 时更新所有字段而不是设置字段:

  • 如果安排的工作流配置运行在下一次安排的运行开始之前未完成,则下一次安排的运行将被跳过并标记为错误。

后续步骤