在資料表單中使用 JavaScript

本文將說明如何使用 JavaScript 在 Dataform 中開發工作流程。本文也說明如何使用 JavaScript 建立工作流程動作,以及如何建立 JavaScript 包含項目,以便在 Dataform 中重複使用程式碼。

Dataform 核心可讓您使用 SQLX 和 JavaScript 建立工作流程動作。雖然是選用功能,但您可以在工作流程中,搭配使用 JavaScript 和 SQLX,重複建立類似元素。舉例來說,您可以使用 JavaScript 建立工作流程中每個表格的檢視畫面,並移除特定使用者 ID。您也可以完全使用 JavaScript 開發工作流程動作。

事前準備

  1. 前往 Google Cloud 控制台的「Dataform」頁面。

    前往 Dataform

  2. 選取或建立存放區

  3. 選取或建立開發工作區

此外,您也必須熟悉 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 檔案,請按照下列步驟操作:

  1. 在「檔案」窗格中,點按 includes/ 旁的 「更多」

  2. 點選「建立檔案」

  3. 在「建立新檔案」窗格中,執行下列步驟:

    1. 在「Add a file path」(新增檔案路徑) 欄位中,輸入 includes/,然後輸入檔案名稱和 .js。例如:includes/constants.js

      檔名只能包含數字、字母、連字號和底線。

    2. 點選「建立檔案」

建立 JavaScript 常數

如要建立可在專案中重複使用的常數,請按照下列步驟操作:

  1. 前往開發工作區。

  2. 在「檔案」窗格中,展開 includes/

  3. 建立或選取副檔名為 .js 的 JavaScript 檔案。

  4. 在檔案中輸入下列程式碼片段:

     const CONSTANT_NAME = CONSTANT_VALUE;
     module.exports = { CONSTANT_NAME };
    

    更改下列內容:

    • CONSTANT_NAME:常數名稱
    • CONSTANT_VALUE:常數的值
  5. 選用:按一下「格式」

下列程式碼範例會在 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 函式,請按照下列步驟操作:

  1. 前往開發工作區。

  2. 在「檔案」窗格中,展開 includes/

  3. 建立或選取副檔名為 .js 的 JavaScript 檔案。

  4. 在檔案中編寫自訂 JavaScript 函式。

  5. 在檔案中輸入下列程式碼片段:

     module.exports = { FUNCTION_NAME }
    

    FUNCTION_NAME 換成您的函式名稱。

  6. 選用:按一下「格式」

下列程式碼範例顯示名為 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 函式參照巢狀包含項目,請按照下列步驟操作:

  1. 前往開發工作區。

  2. 在「檔案」窗格中,展開 definitions/

  3. 選取 SQLX 檔案。

  4. config 區塊中,輸入下列程式碼片段:

     js {
       var { VARIABLE_NAME } = require("SUBDIRECTORY_INCLUDE");
     }
    

    更改下列內容:

    • VARIABLE_NAME:要匯入的常數或函式名稱
    • SUBDIRECTORY_INCLUDE:巢狀 includes 檔案的路徑
  5. 選用:按一下「格式」

下列程式碼範例會在資料表定義 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_removeduser_settings_blocked_removeduser_logs_blocked_removed 的檢視畫面,其中不含任何遭封鎖的使用者 ID。

您可以在一個 JavaScript 檔案中,使用 Dataform 全域方法和任意 JavaScript ES5 程式碼 (例如迴圈和常數),建立多個動作。

您可以在 Dataform 中使用 JavaScript 定義下列動作:

建立 JavaScript 檔案

將定義和資料來源宣告的 JavaScript 檔案儲存在 definitions/ 目錄中。如要在 definitions/ 目錄中建立新的 JavaScript 檔案,請按照下列步驟操作:

  1. 在「檔案」窗格中,點按 definitions/ 旁的 「更多」

  2. 點選「建立檔案」

  3. 在「建立新檔案」窗格中,執行下列步驟:

    1. 在「Add a file path」(新增檔案路徑) 欄位中,在 definitions/ 後方輸入檔案名稱,然後輸入 .js。例如:definitions/definitions.js

      檔名只能包含數字、字母、連字號和底線。

    2. 點選「建立檔案」

使用 JavaScript 設定工作流程動作屬性

您可以使用下列 Dataform 全域方法,透過 Dataform 建立 SQL 工作流程動作:

  • declare:用於宣告資料來源。
  • publish:用於定義資料表。
  • assert:用於建立判斷。
  • operate:用於定義自訂 SQL 作業。

每個全域方法都包含可用於設定所建立物件的屬性。如要進一步瞭解全域方法及其屬性,請參閱 Dataform 核心參考資料

在建立資料表的 publish() 方法中,您可以將資料表屬性做為第二個方法引數傳遞,藉此設定資料表屬性。

如要將資料表屬性做為 publish() 的第二個引數傳遞,請按照下列步驟操作:

  1. 在開發工作區的「檔案」窗格中,展開 definitions/

  2. 選取 JavaScript 檔案。

  3. 在檔案中,以下列格式將資料表屬性新增至 publish() 方法:

     method("first_method_argument", {
       property1: "property1_value",
       property2: "property2_value",
       property3: "property3_value",
     });
    
  4. 選用:按一下「格式」

以下程式碼範例說明如何將屬性做為方法的第二個引數傳遞,藉此將屬性設定為 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 檔案中的 serviceNameserviceId 變數:

  const {serviceName, serviceId} = service;

參考檔案巢狀包含

如要參照巢狀包含檔案,請在 JavaScript require 函式中輸入檔案名稱。

下列程式碼範例會參照 includes/allServices/service.js 檔案中的 serviceNameserviceId 變數:

  const {serviceName, serviceId} = require("includes/allServices/service.js");

在 JavaScript 方法中使用 Dataform 查詢函式

Dataform 提供許多內建函式,可在查詢中使用,例如 refself。如要進一步瞭解 Dataform 內建函式,請參閱 Dataform API 參考資料

如要在 JavaScript 方法中使用內建查詢函式,請按照下列步驟操作:

  1. 在開發工作區的「檔案」窗格中,展開 definitions/

  2. 選取 JavaScript 檔案。

  3. 在檔案中輸入全域 Dataform JavaScript 方法。

  4. 在該方法中,輸入可設定環境的 ctx 引數。

  5. 選用:如果您使用 JavaScript 範本字串,請將可設定環境的引數放在反引號 `` 中。

  6. 在可設定環境的引數中,輸入查詢函式,並將其參數設為環境物件。

  7. 選用:按一下「格式」

下列程式碼範例顯示包裝在發布方法的可設定環境引數中的 ref 查詢函式:

  publish("example").query(ctx => `SELECT * FROM ${ctx.ref("other_table")}`);

使用 JavaScript 宣告工作流程資料來源

您可以使用 Dataform 宣告 JavaScript 方法,在一個 JavaScript 宣告檔案中宣告多個資料來源。如要進一步瞭解 declare 方法,請參閱 Dataform 核心參考資料。如要進一步瞭解 Dataform 中的資料來源,請參閱「宣告資料來源」。

如要在 JavaScript 檔案中宣告資料來源,請按照下列步驟操作:

  1. 在開發工作區的「檔案」窗格中,展開 definitions/

  2. 選取 JavaScript 檔案。

  3. 在檔案中輸入下列程式碼片段:

     declare({
       database: "DATABASE_PROJECT_ID",
       schema: "BIGQUERY_SCHEMA",
       name: "RELATION_NAME",
     });
    

    更改下列內容:

    • DATABASE_PROJECT_ID:包含資料來源的專案 ID
    • BIGQUERY_SCHEMA:外部關係所在的 BigQuery 資料集
    • RELATION_NAME:關係的名稱,您稍後可以在 Dataform 中使用這個名稱參照資料來源
  4. 如要在同一個檔案中宣告其他資料來源,請在檔案中新增額外的 declare 區塊。

  5. 選用:按一下「格式」

使用 JavaScript 定義資料表

您可以使用 Dataform JavaScript publish 方法建立表格。如要進一步瞭解發布方法,請參閱 Dataform 核心參考資料

您可以定義下列資料表類型:

  • 資料表
  • 累加資料表
  • 查看

如要進一步瞭解如何在 Dataform 中定義資料表,請參閱「建立資料表」。

如要在 JavaScript 檔案中定義表格,請按照下列步驟操作:

  1. 在開發工作區的「檔案」窗格中,展開 definitions/

  2. 選取 JavaScript 檔案。

  3. 在檔案中輸入下列程式碼片段:

     publish("TABLE_NAME").query(ctx => "SELECT_QUERY");
    

    更改下列內容:

    • TABLE_NAME:資料表名稱
    • SELECT_QUERY:定義資料表的 SQL SELECT 陳述式
  4. 如要設定資料表類型、新增資料表依附元件及新增資料表說明,請設定 publish 方法的物件屬性

  5. 如要在同一檔案中定義其他資料表,請重複執行步驟 3 和步驟 4。

  6. 選用:按一下「格式」

使用 JavaScript 定義手動斷言

您可以使用 Dataform 斷言 JavaScript 方法,在 JavaScript 檔案中手動建立 SQL 斷言。如要進一步瞭解 assert 方法,請參閱 Dataform 核心參考資料

手動斷言 SQL 查詢必須傳回零個資料列。如果查詢在執行時傳回資料列,斷言就會失敗。您可以在一個 JavaScript 檔案中建立多項斷言。

如要進一步瞭解 Dataform 中的斷言,請參閱測試資料品質

如要在 JavaScript 檔案中建立手動斷言,請按照下列步驟操作:

  1. 在開發工作區的「檔案」窗格中,展開 definitions/

  2. 選取 JavaScript 檔案。

  3. 在檔案中輸入下列程式碼片段:

     assert("ASSERTION_NAME").query(ctx => "CUSTOM_ASSERTION_QUERY");
    

    更改下列內容:

    • ASSERTION_NAME:自訂判斷的名稱
    • CUSTOM_ASSERTION_QUERY:SQL 斷言查詢
  4. 如要在同一個檔案中建立其他判斷,請重複步驟 3。

  5. 選用:按一下「格式」

下列程式碼範例顯示 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 作業,請按照下列步驟操作:

  1. 在開發工作區的「檔案」窗格中,展開 definitions/

  2. 選取 JavaScript 檔案。

  3. 在檔案中輸入下列程式碼片段:

     operate("OPERATION_NAME").queries(ctx => "CUSTOM_SQL_QUERY");
    

    更改下列內容:

    • OPERATION_NAME:自訂作業的名稱
    • CUSTOM_SQL_QUERY:自訂 SQL 查詢
  4. 如要在同一檔案中定義其他自訂 SQL 作業,請重複步驟 3。

  5. 選用:按一下「格式」

下列程式碼範例顯示 JavaScript 檔案中的自訂 SQL 作業,該作業會在 some_table 中插入單一新資料列,並將新資料列的 test_column 設為 2

  operate("operation1").queries("INSERT INTO some_table (test_column) VALUES (2)");

後續步驟