包含断言的测试表

本文档介绍了如何使用 Dataform Core 创建 Dataform 表断言并测试工作流代码。

断言简介

断言是一种数据质量测试查询,可查找违反查询中指定的一条或多条规则的行。如果查询返回任何行,则断言失败。Dataform 每次更新 SQL 工作流时都会运行断言,并会在任何断言失败时提醒您。

Dataform 会自动在 BigQuery 中创建包含已编译断言查询的结果的视图。如在工作流设置文件中配置一样,Dataform 会在断言架构中创建这些视图,您可以在其中检查断言结果。

例如,对于默认 dataform_assertions 架构,Dataform 会在 BigQuery 中按以下格式创建视图:dataform_assertions.assertion_name

您可以为所有 Dataform 表类型(表、增量表、视图和具体化视图)创建断言。

您可以通过以下方式创建断言:

准备工作

  1. 在 Google Cloud 控制台中,前往 Dataform 页面。

    转到 Dataform 页面

  2. 选择或创建代码库

  3. 选择或创建开发工作区

  4. 定义表

所需的角色

如需获取创建断言所需的权限,请让管理员向您授予工作区的 Dataform Editor (roles/dataform.editor) IAM 角色。如需详细了解如何授予角色,请参阅管理访问权限

您也可以通过自定义角色或其他预定义角色来获取所需的权限。

创建内置断言

您可以将内置的 Dataform 断言添加到表的 config 块中。Dataform 会在创建表后运行这些断言。在 Dataform 发布表后,您可以检查断言。

您可以在表的 config 代码块中创建以下断言:

  • nonNull

    此条件断言指定列在所有表行中不为 null。此条件适用于不能为 null 的列。

    以下代码示例展示了表的 config 块中的 nonNull 断言:

config {
  type: "table",
  assertions: {
    nonNull: ["user_id", "customer_id", "email"]
  }
}
SELECT ...
  • rowConditions

    此条件断言所有表行都遵循您定义的自定义逻辑。每个行条件都是一个自定义 SQL 表达式,并且系统会根据每个行条件评估表中的每个行。如果有任何表行违反任何行条件,则断言失败。

    以下代码示例展示了增量表的 config 块中的自定义 rowConditions 断言:

config {
  type: "incremental",
  assertions: {
    rowConditions: [
      'signup_date is null or signup_date > "2022-08-01"',
      'email like "%@%.%"'
    ]
  }
}
SELECT ...
  • uniqueKey

    此条件要求在指定的列中,没有任何表行具有相同的值。

    以下代码示例展示了视图的 config 块中的 uniqueKey 断言:

config {
  type: "view",
  assertions: {
    uniqueKey: ["user_id"]
  }
}
SELECT ...
  • uniqueKeys

    此条件断言在指定列中,没有表行具有相同的值。如果表中有多个行的所有指定列都具有相同的值,则断言失败。

    以下代码示例展示了表的 config 块中的 uniqueKeys 断言:

config {
  type: "table",
  assertions: {
    uniqueKeys: [["user_id"], ["signup_date", "customer_id"]]
  }
}
SELECT ...

config 代码块添加断言

如需向表的 config 块添加断言,请按以下步骤操作:

  1. 在开发工作区的文件窗格中,选择一个表定义 SQLX 文件。
  2. 在表文件的 config 代码块中,输入 assertions: {}
  3. assertions: {} 中,添加您的断言。
  4. 可选:点击格式

以下代码示例展示了在 config 代码块中添加的条件:

config {
  type: "table",
  assertions: {
    uniqueKey: ["user_id"],
    nonNull: ["user_id", "customer_id"],
    rowConditions: [
      'signup_date is null or signup_date > "2019-01-01"',
      'email like "%@%.%"'
    ]
  }
}
SELECT ...

使用 SQLX 创建手动断言

手动断言是您在专用 SQLX 文件中编写的 SQL 查询。手动断言 SQL 查询必须返回零行。如果查询在执行时返回行,则断言失败。

如需在新的 SQLX 文件中添加手动断言,请按以下步骤操作:

  1. Files 窗格中,点击 definitions/ 旁边的 More 菜单。
  2. 点击创建文件
  3. 添加文件路径字段中,输入文件名,后跟 .sqlx。例如 definitions/custom_assertion.sqlx

    文件名只能包含数字、字母、连字符和下划线。

  4. 点击创建文件

  5. Files 窗格中,点击新文件。

  6. 在文件中,输入:

    config {
      type: "assertion"
    }
    
  7. config 代码块下方,编写您的 SQL 查询或多个查询。

  8. 可选:点击格式

以下代码示例展示了 SQLX 文件中的手动断言,该断言断言 sometable 中的字段 ABc 绝不为 NULL

config { type: "assertion" }

SELECT
  *
FROM
  ${ref("sometable")}
WHERE
  a IS NULL
  OR b IS NULL
  OR c IS NULL

将断言设置为依赖项

当工作流操作 B 依赖于具有断言的工作流操作 A 时,操作 A 的断言失败不会阻止 Dataform 执行操作 B。要仅在操作 A 的断言通过时执行操作 B,您需要将操作 A 的断言设置为操作 B 的依赖项。BBBB

您可以通过以下方式将断言设置为所选操作的依赖项:

将所选断言设置为依赖项

您可以将选定的断言手动设置为依赖项,方法是将其添加到已修改操作的 config 代码块中的 dependencies: [ "" ]

例如,如果操作 B 依赖于操作 A,而您希望操作 B 仅依赖于操作 A 的选定断言,则可以将选定的断言添加到操作 B 的 config 块中。BBBBB

您可以手动将所选断言设置为除数据源声明以外的所有操作类型的依赖项。

将所选依赖项操作的断言设为依赖项

您可以设置 includeDependentAssertions 参数,自动将所选依赖项工作流操作的所有直接断言设为修改操作的依赖项。Dataform 会在每次编译操作期间将这些断言添加为依赖项,以确保在依赖项操作的断言发生更改时,依赖项处于最新状态。

例如,如果操作 C 依赖于操作 A 和 B,但您只希望操作 C 依赖于操作 A 的断言,则可以修改操作 C 并设置 includeDependentAssertions 参数以自动将操作 A 的所有断言设置为操作 C 的依赖项。CCCCCCC

您可以为以下类型的操作设置 includeDependentAssertions 参数:

  • table
  • view
  • operations
将所有依赖项操作的断言设置为依赖项

您可以设置 dependOnDependencyAssertions 参数,自动将已修改操作的所有依赖项操作的所有直接断言设置为修改后的操作的其他依赖项。Dataform 会在每次编译操作期间将这些断言添加为依赖项,以确保在依赖项操作的断言发生更改时,依赖项处于最新状态。

例如,如果操作 C 依赖于操作 A 和 B,您可以修改操作 C 并设置 dependOnDependencyAssertions 参数以自动将操作 A 和 B 的所有断言设置为操作 C 的依赖项。CCCCCC

您可以为以下类型的操作设置 dependOnDependencyAssertions 参数:

  • table
  • view
  • operations

如果您在单个文件中设置 dependOnDependencyAssertions 参数和 includeDependentAssertions 参数,则 includeDependentAssertions 参数的优先级更高。例如,如果您将所选依赖项操作的 dependOnDependencyAssertions 设置为 true,同时将 includeDependentAssertions 设置为 false,则 Dataform 不会将该操作的断言添加到依赖项中。

以下代码示例展示了同一表定义文件中设置的 dependOnDependencyAssertionsincludeDependentAssertions 参数:

// filename is tableName.sqlx

config {
type: "table",
dependOnDependencyAssertions: true,
dependencies: [ "actionA", {name: "actionB", includeDependentAssertions: false} ]
}

SELECT * FROM ${ref("actionC")}

在上述代码示例中,Dataform 在编译期间会将 actionAactionC 的所有直接断言添加到 tableName 的依赖项中。

将所选断言设为依赖项

如需仅在所选断言通过时执行工作流操作,您可以将所选断言添加到已修改操作的 config 块的 dependencies: [ "" ] 中。

如需将选定的断言设置为所选工作流操作的依赖项,请按以下步骤操作:

  1. 在开发工作区的 Files 窗格中,展开 definitions/
  2. 选择工作流操作 SQLX 文件。
  3. 在操作文件的 config 代码块中,输入 dependencies: [ "" ]
  4. dependencies: [ "" ] 中,使用以下某种格式输入操作断言的名称或要设为依赖项的手动断言的文件名:

    nonNull

    config {
      type: "ACTION_TYPE",
      dependencies: [ "ACTION_DATASET_NAME_ACTION_NAME_assertions_nonNull"]
    }
    

    请替换以下内容:

    • ACTION_TYPE:工作流操作的类型:tableviewoperations
    • ACTION_DATASET_NAME:其中定义了操作的数据集的名称。默认数据集在工作流设置文件中定义
    • ACTION_NAME:在其中定义了断言的操作的名称。

    rowConditions

    config {
      type: "ACTION_TYPE",
      dependencies: [ "ACTION_DATASET_NAME_ACTION_NAME_assertions_rowConditions"]
    }
    

    请替换以下内容:

    • ACTION_TYPE:工作流操作的类型:tableviewoperations
    • DATASET_NAME:在其中定义了操作的数据集的名称。 默认数据集在工作流设置文件中定义
    • ACTION_NAME:在其中定义了断言的操作的名称。

    uniqueKey

    config {
      type: "ACTION_TYPE",
      dependencies: [ "ACTION_DATASET_NAME_ACTION_NAME_assertions_uniqueKey_INDEX"]
    }
    

    请替换以下内容:

    • ACTION_TYPE:工作流操作的类型:tableviewoperations
    • DATASET_NAME:在其中定义了表的数据集的名称。 默认数据集在工作流设置文件中定义
    • ACTION_NAME:在其中定义了断言的表的名称。
    • INDEX:要作为依赖项添加的 uniqueKey 断言中定义的键数组的索引。例如 01。如果断言中只定义了一个键数组,则索引为 0

    uniqueKeys

    config {
      type: "ACTION_TYPE",
      dependencies: [ "ACTION_DATASET_NAME_ACTION_NAME_assertions_uniqueKeys_INDEX"]
    }
    

    请替换以下内容:

    • ACTION_TYPE:工作流操作的类型:tableviewoperations
    • DATASET_NAME:在其中定义了表的数据集的名称。 默认数据集在工作流设置文件中定义
    • ACTION_NAME:在其中定义了断言的表的名称。
    • INDEX:您要作为依赖项添加的 uniqueKeys 断言中定义的键数组的索引,例如 01。如果断言中只定义了一个键数组,则索引为 0

    手动断言

    config {
      type: "ACTION_TYPE",
      dependencies: [ "MANUAL_ASSERTION_NAME"]
    }
    

    请替换以下内容:

    • ACTION_TYPE:工作流操作的类型:tableviewoperations
    • MANUAL_ASSERTION_NAME 是手动断言的名称。
  5. 如需将其他断言作为依赖项添加到修改后的表,请重复第 4 步

  6. 可选:点击格式

以下代码示例展示了添加到表 A 的断言,这些断言在 dataform 数据集中定义:

config {
  type: "table",
  assertions: {
    uniqueKey: ["user_id"],
    nonNull: ["user_id", "customer_id"],
  }
}

以下代码示例显示了作为依赖项添加到表 B 中的表 A 断言:

config {
  type: "table",
  dependencies: [ "dataform_A_assertions_uniqueKey_0",  "dataform_A_assertions_nonNull"]
}

以下代码示例展示了在 manualAssertion.sqlx 文件中定义的手动断言,并作为依赖项添加到视图中:

config {
  type: "view",
  dependencies: [ "manualAssertion"]
}

以下代码示例展示了 manual_assertion 文件以及作为依赖项添加到表中的 sometable 表的断言:

config {
  type: "table",
  dependencies: [ "manual_assertion",  "dataform_sometable_assertions_nonNull" ,  "dataform_sometable_assertions_rowConditions"]
}

SELECT * FROM ${ref("referenced_table")} LEFT JOIN ...

将所选操作的断言设为依赖项

如需仅在所选依赖项操作的所有直接断言通过时执行工作流操作,请在修改后的操作中将 includeDependentAssertions 参数设置为 true。在编译期间,Dataform 会自动将所选依赖项操作的直接断言添加到依赖项中。默认值为 false

如需将所选依赖项操作的所有断言设为依赖项,请按以下步骤操作:

  1. 在开发工作区的 Files 窗格中,展开 definitions/
  2. 选择工作流操作 SQLX 文件。
  3. 在文件中,可通过以下任一方式将 includeDependentAssertions 参数设置为 true

    config 代码块中

    config {
    type: "ACTION_TYPE",
    dependencies: [{name: "dEPENDENCY_ACTION_NAME", includeDependentAssertions: true}]
    }
    

    请替换以下内容:

    • ACTION_TYPE:工作流操作的类型:tableviewoperations
    • DEPENDENCY_ACTION_NAME:依赖项操作的名称,您要将其设置为所修改操作的依赖项的断言。

    SELECT 语句中

      config { type: "ACTION_TYPE" }
    
      SELECT * FROM ${ref({name: "DEPENDENCY_ACTION_NAME", includeDependentAssertions: true})}
    

    请替换以下内容:

    • ACTION_TYPE:工作流操作的类型:tableviewoperations
    • DEPENDENCY_ACTION_NAME:依赖项操作的名称,您要将其设置为所修改操作的依赖项的断言。
  4. 可选:点击格式

以下代码示例展示了依赖于 viewAtableBtableB 的所有断言的 tableC

// filename is tableC.sqlx

config {
type: "table",
dependencies: ["viewA", {name: "tableB", includeDependentAssertions: true}]
}

SELECT * FROM ...

在上述代码示例中,Dataform 会在编译期间自动将 tableB 的所有直接断言作为依赖项添加到 tableC 中。

将所有依赖项操作的断言设置为依赖项

如需仅在所有依赖项操作的所有直接断言通过时执行工作流操作,请在修改后的操作中将 dependOnDependencyAssertions 参数设置为 true。在编译期间,Dataform 会自动将依赖项操作的直接断言添加为依赖项。默认值为 false

在单个文件中设置 dependOnDependencyAssertions 参数和 includeDependentAssertions 参数时,includeDependentAssertions 参数对于为其设置的依赖关系操作的优先级更高。

如需将所选依赖项操作的所有断言设为依赖项,请按以下步骤操作:

  1. 在开发工作区的 Files 窗格中,展开 definitions/
  2. 选择工作流操作 SQLX 文件。
  3. 在该文件中,按以下格式将 dependOnDependencyAssertions 参数设置为 true

    config {
    type: "ACTION_TYPE",
    dependOnDependencyAssertions: true,
    dependencies: [ "dependency1", "dependency2" ]
    }
    

    替换 ACTION_TYPE:工作流操作的类型。支持的值包括 tableviewoperations

  4. 可选:点击格式

以下代码示例展示了依赖于 sometableAsometabletableBsometableCsometableD 以及依赖关系表的所有直接断言的 sometableE

// filename is sometableE.sqlx

config {
type: "table",
dependOnDependencyAssertions: true,
dependencies: [ "sometableA", "sometableB" ]
}

SELECT * FROM ${ref("sometableC")}
SELECT * FROM ${ref("sometableD")}

在上述代码示例中,Dataform 会在编译期间自动将 sometableAsometableBsometableCsometableD 的所有直接断言作为依赖项添加到 sometableE

后续步骤