借助 Dataform 核心,您可以使用 SQLX 和 JavaScript 创建工作流操作。虽然是可选的,但您可以使用 JavaScript 和 SQLX 在工作流程中重复创建类似元素。例如,您可以使用 JavaScript 创建工作流中每个表的视图,并移除特定用户 ID。您还可以完全使用 JavaScript 开发工作流操作。
准备工作
此外,您还必须熟悉 JavaScript 语法和以下 JavaScript 概念:
- 变量
- 数组
- 条件语句
- For 循环
- 地图
- 函数
- 对象
- 导出和导入模块
所需的角色
如需获得使用 JavaScript 开发工作流以及通过 JavaScript 包含项重用代码所需的权限,请让您的管理员为您授予工作区的 Dataform Editor (roles/dataform.editor) IAM 角色。如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。
向 SQLX 文件添加 JavaScript 代码
您可以通过以下两种方式将 JavaScript 代码添加到 SQLX 文件中:内嵌或在 JavaScript 块内。
您可以使用 JavaScript 块在 SQLX 文件中定义函数或常量。您可以使用内嵌 JavaScript 动态修改 SQLX 或 SQL 查询。
以下代码示例展示了内联添加到 SQLX 文件中 post_operations 块的 self Dataform 核心内置 JavaScript 函数:
config {type: "table"}
SELECT * FROM ...
post_operations {
GRANT `roles/bigquery.dataViewer`
ON
TABLE ${self()}
TO "group:allusers@example.com", "user:otheruser@example.com"
}
以下代码示例展示了在 JavaScript 块中定义的常量,以及在 SQLX 文件中的查询内联使用该常量的示例:
js {
const columnName = "foo";
}
SELECT 1 AS ${columnName} FROM "..."
通过 JavaScript 封装在单个 SQLX 文件中重用代码
您可以重复使用 JavaScript 代码,从而简化 Dataform 中的开发流程。 如需在单个 SQLX 文件中重复使用 JavaScript 常量和函数,您可以将它们封装在 JavaScript 块中。如需在单个 Dataform 代码库中重复使用 JavaScript 代码,您可以创建 include。 如需在多个 Dataform 代码库中重复使用 JavaScript 代码,您可以创建或导入软件包。
如需创建可在单个 SQLX 文件中重复使用的 SQL 代码,您可以将函数和常量封装在 JavaScript 块中。您只能在定义 JavaScript 代码块的 SQLX 文件内重用该代码块中定义的代码。如需了解详情,请参阅 Dataform 核心。
以下代码示例展示了在 JavaScript 块中定义并在 SQLX 文件中的查询内联使用的常量和函数:
js {
const foo = 1;
function bar(number){
return number+1;
}
}
select
${foo} as one,
${bar(foo)} as two
通过包含在单个代码库中重复使用代码
Include 是 JavaScript 常量或函数,在您的代码库中是全局的。
您可以在代码库的 includes 目录中定义包含项。然后,您可以在 JavaScript 和 SQLX 文件中跨代码库重复使用这些变量。
以下代码示例展示了 includes/constants.js 文件中 launch_date 常量的定义:
// filename is includes/constants.js
const launch_date = "11.11.2011";
module.exports = { launch_date };
以下代码示例展示了 SQLX 文件中的表定义查询中引用的 launch_date 常量:
config {type: "table"}
SELECT * FROM source_table WHERE date > ${constants.launch_date}
创建包含项的 JavaScript 文件
如需在 includes/ 目录中创建新的 JavaScript 文件,请按以下步骤操作:
在文件窗格中,点击
includes/旁边的 更多。点击创建文件。
在创建新文件窗格中,执行以下操作:
在添加文件路径字段中的
includes/后面输入文件名称,然后输入.js。例如includes/constants.js。文件名只能包含数字、字母、连字符和下划线。
点击创建文件。
创建 JavaScript 常量
如需创建可在整个项目中重复使用的常量,请按以下步骤操作:
前往您的开发工作区。
在文件窗格中,展开
includes/。创建或选择一个扩展名为
.js的 JavaScript 文件。在文件中输入以下代码段:
const CONSTANT_NAME = CONSTANT_VALUE; module.exports = { CONSTANT_NAME };替换以下内容:
- CONSTANT_NAME:常量的名称
- CONSTANT_VALUE:常量的值
可选:点击格式。
以下代码示例在 includes/constants.js 文件中定义了 PROJECT_ID 常量:
// filename is includes/constants.js
const PROJECT_ID = "my_project_name";
module.exports = { PROJECT_ID };
以下代码示例引用了 SQLX 文件中表定义查询中的 PROJECT_ID 常量:
config { type: "table" }
SELECT * FROM ${constants.PROJECT_ID}.my_schema_name.my_table_name
以下代码示例展示了编译为 SQL 的先前 Dataform 核心表定义查询:
SELECT * FROM my_project_name.my_schema_name.my_table_name
创建自定义 JavaScript 函数
如需创建可在整个项目中重复使用的自定义 JavaScript 函数,请按照以下步骤操作:
前往您的开发工作区。
在文件窗格中,展开
includes/。创建或选择一个扩展名为
.js的 JavaScript 文件。在该文件中,编写您的自定义 JavaScript 函数。
在文件中输入以下代码段:
module.exports = { FUNCTION_NAME }将
FUNCTION_NAME替换为您的函数的名称。可选:点击格式。
以下代码示例展示了一个名为 renderScript 且存储在 includes/functions.js 文件中的自定义 JavaScript 函数。该函数会生成一个 SQL 脚本:
function renderScript(table, dimensions, metrics) {
return `
select
${dimensions.map(field => `${field} as ${field}`).join(",")},
${metrics.map(field => `sum(${field}) as ${field}`).join(",\n")}
from ${table}
group by ${dimensions.map((field, i) => `${i + 1}`).join(", ")}
`;
}
module.exports = { renderScript };
以下代码示例展示了如何在 Dataform 核心表定义查询中使用自定义 renderScript JavaScript 函数:
config {
type: "table",
tags: ["advanced", "hourly"],
disabled: true
}
${functions.renderScript(ref("source_table"),
["country", "device_type"],
["revenue", "pageviews", "sessions"]
)}
以下代码示例展示了之前编译为 SQL 的 Dataform 核心表定义查询:
select
country as country,
device_type as device_type,
sum(revenue) as revenue,
sum(pageviews) as pageviews,
sum(sessions) as sessions
from "dataform"."source_table"
group by 1, 2
在 SQLX 文件中引用 include
您可以在 SQLX 文件中引用任何 include 函数或常量。引用包含文件的语法取决于包含文件的位置。顶级 include 文件直接位于 includes/ 目录中。
嵌套的 include 文件位于 includes/ 的子目录中。
在 SQLX 文件中引用顶级 include
- 如需在 Dataform 核心查询中引用顶级 include 函数或常量,请输入 include 定义文件名(不含
.js扩展名),后跟导出的对象名称。
以下代码示例在表定义 SQLX 文件中引用了 includes/constants.js 文件中定义的 firstDate 常量:
config {type: "table"}
select * from source_table where date > ${constants.firstDate}
在 SQLX 文件中引用嵌套的 include
如需引用位于 definitions 子目录中的 include,请使用 JavaScript require 函数和 js {} 块导入 include。
如需使用 require JavaScript 函数引用嵌套的 include,请按以下步骤操作:
前往您的开发工作区。
在文件窗格中,展开
definitions/。选择一个 SQLX 文件。
在
config块中,输入以下代码段:js { var { VARIABLE_NAME } = require("SUBDIRECTORY_INCLUDE"); }替换以下内容:
- VARIABLE_NAME:要导入的常量或函数的名称
- SUBDIRECTORY_INCLUDE:嵌套
includes文件的路径
可选:点击格式。
以下代码示例在表定义 SQLX 文件中引用了嵌套 includes/allConstants/constants.js 文件中定义的 firstDate 常量:
config {type: "table"}
js {
var { firstDate } = require("includes/allConstants/constants");
}
select * from source_table where date > ${firstDate}
将 JavaScript include 函数与 Dataform 核心 ref 函数搭配使用
如需将 JavaScript include 函数与 Dataform 核心 ref 函数搭配使用,您需要在 SQLX 文件中将 ref 作为 JavaScript include 函数的实参进行传递。
以下代码示例展示了 includes/script_builder.js 文件,其中包含使用 SUM 汇总指标并按维度对其进行分组的 renderScript JavaScript 函数:
function renderScript(table, dimensions, metrics) {
return `
SELECT
${dimensions.map((field) => `${field} AS ${field}`).join(",\\n")},
${metrics.map((field) => `SUM(${field}) AS ${field}`).join(",\\n")}
FROM ${table}
GROUP BY ${dimensions.map((field, i) => `${i + 1}`).join(", ")}
`;
}
module.exports = { renderScript };
以下代码示例展示了 definitions/stats_per_country_and_device.sqlx 文件中使用的 renderScript JavaScript 函数,其中 Dataform 核心 ref 函数作为实参传递:
${script_builder.renderScript(
ref("source_table"),
["country", "device_type"],
["revenue", "pageviews",