Dataform 核心可讓您使用 SQLX 和 JavaScript 建立工作流程動作。雖然是選用功能,但您可以在工作流程中,搭配使用 JavaScript 和 SQLX,重複建立類似元素。舉例來說,您可以使用 JavaScript 建立工作流程中每個表格的檢視畫面,並移除特定使用者 ID。您也可以完全使用 JavaScript 開發工作流程動作。
事前準備
此外,您也必須熟悉 JavaScript 語法和下列 JavaScript 概念:
- 變數
- 陣列
- 條件陳述式
- For 迴圈
- 地圖
- 函式
- 物件
- 匯出及匯入模組
必要的角色
如要取得使用 JavaScript 開發工作流程,以及透過 JavaScript 包含項目重複使用程式碼所需的權限,請要求管理員授予您工作區的 Dataform 編輯器 (roles/dataform.editor
) IAM 角色。如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和機構的存取權」。
在 SQLX 檔案中新增 JavaScript 程式碼
您可以透過兩種方式在 SQLX 檔案中新增 JavaScript 程式碼:內嵌或在 JavaScript 區塊內。
您可以在 SQLX 檔案中使用 JavaScript 區塊定義函式或常數。您可以使用內嵌 JavaScript 動態修改 SQLX 或 SQL 查詢。
下列程式碼範例顯示 self
Dataform Core 內建 JavaScript 函式,已內嵌至 SQLX 檔案的 post_operations
區塊:
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/
旁的 「更多」。點選「建立檔案」。
在「建立新檔案」窗格中,執行下列步驟:
在「Add a file path」(新增檔案路徑) 欄位中,輸入
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
的自訂 JavaScript 函式,並儲存在 includes/functions.js
檔案中。函式會產生 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 的語法取決於 include 檔案的位置。頂層包含檔案位於 includes/
目錄中。巢狀包含檔案位於 includes/
的子目錄中。
在 SQLX 檔案中參照頂層 include
- 如要在 Dataform 核心查詢中參照頂層 include 函式或常數,請輸入 include 定義檔案名稱 (不含
.js
副檔名),然後輸入匯出物件的名稱。
下列程式碼範例會在資料表定義 SQLX 檔案中,參照 includes/constants.js
檔案中定義的 firstDate
常數:
config {type: "table"}
select * from source_table where date > ${constants.firstDate}
在 SQLX 檔案中參照巢狀包含項目
如要參照 definitions
子目錄中的 include,請使用 JavaScript require
函式和 js {}
區塊匯入 include。
如要使用 require
JavaScript 函式參照巢狀包含項目,請按照下列步驟操作:
前往開發工作區。
在「檔案」窗格中,展開
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}
搭配 Dataform 核心 ref
函式使用 JavaScript 納入函式
如要搭配 Dataform 核心 ref
函式使用 JavaScript 包含函式,您需要在 SQLX 檔案內的 JavaScript 包含函式中傳遞 ref
做為引數。
下列程式碼範例顯示 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 Core ref
函式做為引數傳遞:
${script_builder.renderScript(
ref("source_table"),
["country", "device_type"],
["revenue", "pageviews", "sessions"])}
下列程式碼範例顯示編譯為 SQL 的 definitions/stats_per_country_and_device.sqlx
查詢:
SELECT country AS country,
device_type AS device_type,
SUM(revenue) AS revenue,
SUM(pageviews) AS pageviews,
SUM(sessions) AS sessions
FROM my_schema.source_table
GROUP BY 1, 2
如要進一步瞭解 Dataform 核心 ref
函式,請參閱 Dataform 核心。
透過套件在多個存放區中重複使用程式碼
套件是 JavaScript 程式碼的集合,您可以在多個 Dataform 存放區匯入及使用這些程式碼,簡化工作流程開發作業。
您可以在 Dataform 中建立自己的自訂套件,也可以使用開放原始碼的 Dataform 套件,這些套件可在 GitHub 開放原始碼 Dataform 頁面上取得。
如要在 Dataform 中使用套件內容,您必須先在 Dataform 存放區中安裝套件,然後將套件匯入要使用套件的個別 JavaScript 或 SQLX 檔案。詳情請參閱「安裝套件」。
如要在 Dataform 存放區中安裝私人 NPM 套件,您需要驗證套件。
完全使用 JavaScript 建立工作流程
本節說明如何在 Dataform 中使用 JavaScript 建立工作流程動作。您可能想使用 JavaScript,而不是 Dataform 核心,在工作流程中重複建立類似元素。
除了使用 SQLX 或 SQLX 搭配 JavaScript 開發工作流程,您也可以只使用 JavaScript,在 .js
檔案中建立工作流程動作。您可以在一個 JavaScript 檔案中,使用 Dataform 全域方法和任意 JavaScript ES5 程式碼 (例如迴圈和常數),建立多個工作流程動作。每個 Dataform 全域 JavaScript 方法都包含可用於設定所建立物件的屬性。
您可以在 Dataform 中只使用 JavaScript,建立下列工作流程動作:
- 資料來源聲明
- 資料表
- 手動聲明
- 自訂 SQL 作業
您可以使用 JavaScript 在工作流程中重複建立類似動作。舉例來說,您可以建立工作流程中每個資料表的檢視畫面,並移除特定使用者 ID。
下列 JavaScript 程式碼範例可讓您建立每個資料表的檢視區塊,其中 user_id
欄位的值不對應至 blocked_user_ids
清單中的值:
const tableNames = ["user_events", "user_settings", "user_logs"];
tableNames.forEach(tableName => {
publish(tableName + "_blocked_removed").query(
ctx => `
SELECT * FROM ${ctx.ref(tableName)}
WHERE user_id NOT IN (
SELECT user_id
FROM ${ctx.ref("blocked_user_ids")}
)`
);
});
這段程式碼範例會建立三個名為 user_events_blocked_removed
、user_settings_blocked_removed
和 user_logs_blocked_removed
的檢視畫面,其中不含任何遭封鎖的使用者 ID。
您可以在一個 JavaScript 檔案中,使用 Dataform 全域方法和任意 JavaScript ES5 程式碼 (例如迴圈和常數),建立多個動作。
您可以在 Dataform 中使用 JavaScript 定義下列動作:
建立 JavaScript 檔案
將定義和資料來源宣告的 JavaScript 檔案儲存在 definitions/
目錄中。如要在 definitions/
目錄中建立新的 JavaScript 檔案,請按照下列步驟操作:
在「檔案」窗格中,點按
definitions/
旁的 「更多」。點選「建立檔案」。
在「建立新檔案」窗格中,執行下列步驟:
在「Add a file path」(新增檔案路徑) 欄位中,在
definitions/
後方輸入檔案名稱,然後輸入.js
。例如:definitions/definitions.js
。檔名只能包含數字、字母、連字號和底線。
點選「建立檔案」。
使用 JavaScript 設定工作流程動作屬性
您可以使用下列 Dataform 全域方法,透過 Dataform 建立 SQL 工作流程動作:
每個全域方法都包含可用於設定所建立物件的屬性。如要進一步瞭解全域方法及其屬性,請參閱 Dataform 核心參考資料。
在建立資料表的 publish()
方法中,您可以將資料表屬性做為第二個方法引數傳遞,藉此設定資料表屬性。
如要將資料表屬性做為 publish()
的第二個引數傳遞,請按照下列步驟操作:
在開發工作區的「檔案」窗格中,展開
definitions/
。選取 JavaScript 檔案。
在檔案中,以下列格式將資料表屬性新增至
publish()
方法:method("first_method_argument", { property1: "property1_value", property2: "property2_value", property3: "property3_value", });
選用:按一下「格式」。
以下程式碼範例說明如何將屬性做為方法的第二個引數傳遞,藉此將屬性設定為 publish()
方法:
publish("table1", {
type: "table",
dependencies: ["other_table"],
description: {
"Value is 1"
}
}).query(ctx => "SELECT 1 AS test");
在 JavaScript 檔案中加入參照
您可以在 JavaScript 檔案中參照任何包含的函式、巨集或常數。如要進一步瞭解 Dataform 中的 include,請參閱本文件的「使用 include 在單一存放區中重複使用程式碼」一節。
在 JavaScript 檔案中參照 include 的語法,取決於 include 檔案的位置。Dataform 會將這類檔案儲存在 includes 目錄中。
參考頂層 include
- 如要參照頂層的 include 檔案,請在宣告變數時參照檔案名稱。
下列程式碼範例會參照 includes/service.js
檔案中的 serviceName
和 serviceId
變數:
const {serviceName, serviceId} = service;
參考檔案巢狀包含
如要參照巢狀包含檔案,請在 JavaScript require 函式中輸入檔案名稱。
下列程式碼範例會參照 includes/allServices/service.js
檔案中的 serviceName
和 serviceId
變數:
const {serviceName, serviceId} = require("includes/allServices/service.js");
在 JavaScript 方法中使用 Dataform 查詢函式
Dataform 提供許多內建函式,可在查詢中使用,例如 ref
和 self
。如要進一步瞭解 Dataform 內建函式,請參閱 Dataform API 參考資料。
如要在 JavaScript 方法中使用內建查詢函式,請按照下列步驟操作:
在開發工作區的「檔案」窗格中,展開
definitions/
。選取 JavaScript 檔案。
在檔案中輸入全域 Dataform JavaScript 方法。
在該方法中,輸入可設定環境的
ctx
引數。選用:如果您使用 JavaScript 範本字串,請將可設定環境的引數放在反引號
``
中。在可設定環境的引數中,輸入查詢函式,並將其參數設為環境物件。
選用:按一下「格式」。
下列程式碼範例顯示包裝在發布方法的可設定環境引數中的 ref
查詢函式:
publish("example").query(ctx => `SELECT * FROM ${ctx.ref("other_table")}`);
使用 JavaScript 宣告工作流程資料來源
您可以使用 Dataform 宣告 JavaScript 方法,在一個 JavaScript 宣告檔案中宣告多個資料來源。如要進一步瞭解 declare 方法,請參閱 Dataform 核心參考資料。如要進一步瞭解 Dataform 中的資料來源,請參閱「宣告資料來源」。
如要在 JavaScript 檔案中宣告資料來源,請按照下列步驟操作:
在開發工作區的「檔案」窗格中,展開
definitions/
。選取 JavaScript 檔案。
在檔案中輸入下列程式碼片段:
declare({ database: "DATABASE_PROJECT_ID", schema: "BIGQUERY_SCHEMA", name: "RELATION_NAME", });
更改下列內容:
DATABASE_PROJECT_ID
:包含資料來源的專案 IDBIGQUERY_SCHEMA
:外部關係所在的 BigQuery 資料集RELATION_NAME
:關係的名稱,您稍後可以在 Dataform 中使用這個名稱參照資料來源
如要在同一個檔案中宣告其他資料來源,請在檔案中新增額外的
declare
區塊。選用:按一下「格式」。
使用 JavaScript 定義資料表
您可以使用 Dataform JavaScript publish
方法建立表格。如要進一步瞭解發布方法,請參閱 Dataform 核心參考資料。
您可以定義下列資料表類型:
- 資料表
- 累加資料表
- 查看
如要進一步瞭解如何在 Dataform 中定義資料表,請參閱「建立資料表」。
如要在 JavaScript 檔案中定義表格,請按照下列步驟操作:
在開發工作區的「檔案」窗格中,展開
definitions/
。選取 JavaScript 檔案。
在檔案中輸入下列程式碼片段:
publish("TABLE_NAME").query(ctx => "SELECT_QUERY");
更改下列內容:
TABLE_NAME
:資料表名稱SELECT_QUERY
:定義資料表的 SQL SELECT 陳述式
如要設定資料表類型、新增資料表依附元件及新增資料表說明,請設定
publish
方法的物件屬性。如要在同一檔案中定義其他資料表,請重複執行步驟 3 和步驟 4。
選用:按一下「格式」。
使用 JavaScript 定義手動斷言
您可以使用 Dataform 斷言 JavaScript 方法,在 JavaScript 檔案中手動建立 SQL 斷言。如要進一步瞭解 assert 方法,請參閱 Dataform 核心參考資料。
手動斷言 SQL 查詢必須傳回零個資料列。如果查詢在執行時傳回資料列,斷言就會失敗。您可以在一個 JavaScript 檔案中建立多項斷言。
如要進一步瞭解 Dataform 中的斷言,請參閱測試資料品質。
如要在 JavaScript 檔案中建立手動斷言,請按照下列步驟操作:
在開發工作區的「檔案」窗格中,展開
definitions/
。選取 JavaScript 檔案。
在檔案中輸入下列程式碼片段:
assert("ASSERTION_NAME").query(ctx => "CUSTOM_ASSERTION_QUERY");
更改下列內容:
ASSERTION_NAME
:自訂判斷的名稱CUSTOM_ASSERTION_QUERY
:SQL 斷言查詢
如要在同一個檔案中建立其他判斷,請重複步驟 3。
選用:按一下「格式」。
下列程式碼範例顯示 JavaScript 判斷,可判斷 source_table
中沒有任何值是 NULL
:
assert("assertion1").query(ctx => "SELECT * FROM source_table WHERE value IS NULL");
使用 JavaScript 定義自訂 SQL 作業
您可以使用 Dataform 的 JavaScript 運算方法,在 JavaScript 檔案中定義自訂 SQL 作業。如要進一步瞭解 Dataform 中的自訂 SQL 作業,請參閱「建立作業」。
如要使用 JavaScript 定義自訂 SQL 作業,請按照下列步驟操作:
在開發工作區的「檔案」窗格中,展開
definitions/
。選取 JavaScript 檔案。
在檔案中輸入下列程式碼片段:
operate("OPERATION_NAME").queries(ctx => "CUSTOM_SQL_QUERY");
更改下列內容:
OPERATION_NAME
:自訂作業的名稱CUSTOM_SQL_QUERY
:自訂 SQL 查詢
如要在同一檔案中定義其他自訂 SQL 作業,請重複步驟 3。
選用:按一下「格式」。
下列程式碼範例顯示 JavaScript 檔案中的自訂 SQL 作業,該作業會在 some_table
中插入單一新資料列,並將新資料列的 test_column
設為 2
:
operate("operation1").queries("INSERT INTO some_table (test_column) VALUES (2)");