在資料表單中使用 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 Editor (roles/dataform.editor) IAM 角色。如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和機構的存取權」。

您或許還可透過自訂角色或其他預先定義的角色取得必要權限。

在 SQLX 檔案中加入 JavaScript 程式碼

您可以透過兩種方式將 JavaScript 程式碼新增至 SQLX 檔案:內嵌或在 JavaScript 區塊內。

您可以使用 JavaScript 區塊,在 SQLX 檔案中定義函式或常數。您可以使用內嵌 JavaScript 動態修改 SQLX 或 SQL 查詢。

以下程式碼範例顯示 self Dataform 核心內建的 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 程式碼,您可以建立包含項目。如要在多個 Dataform 存放區中重複使用 JavaScript 程式碼,您可以建立或匯入套件。

如要建立可在單一 SQLX 檔案中重複使用的 SQL 程式碼部分,您可以在 JavaScript 區塊中封裝函式和常數。您只能在定義區塊的 SQLX 檔案中,重複使用 JavaScript 區塊中定義的程式碼。詳情請參閱「Dataform 核心」。

下列程式碼範例顯示在 JavaScript 區塊中定義的常數和函式,並在 SQLX 檔案的查詢中內嵌使用:

js {
 const foo = 1;
 function bar(number){
     return number+1;
 }
}

select
 ${foo} as one,
 ${bar(foo)} as two

使用包含項目在單一存放區重複使用程式碼

包含項目是指向儲存庫全域的 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. 在「新增檔案路徑」欄位中,在 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 檔案中參照所包含的檔案

您可以在 SQLX 檔案中參照任何內含函式或常數。參照 include 的語法取決於 include 檔案的位置。頂層包含檔案位於 includes/ 目錄中。巢狀包含檔案位於 includes/ 的子目錄中。

在 SQLX 檔案中參照頂層包含項目

  • 如要在 Dataform 核心查詢中參照頂層包含函式或常數,請輸入包含定義檔案名稱 (不含 .js 副檔名),後面接著輸入匯出的物件名稱。

以下程式碼範例會在資料表定義 SQLX 檔案中,參照 includes/constants.js 檔案中定義的 firstDate 常數:

  config {type: "table"}
  select * from source_table where date > ${constants.firstDate}

在 SQLX 檔案中參照巢狀的內嵌檔案

如要參照位於 definitions 子目錄中的包含項目,請使用 JavaScript require 函式和 js {} 區塊匯入包含項目。

如要使用 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}

使用 JavaScript 內含函式搭配 Dataform 核心 ref 函式

如要將 JavaScript 加入函式與 Dataform 核心 ref 函式搭配使用,您必須在 SQLX 檔案中將 ref 做為 JavaScript 加入函式的引數傳遞。

下列程式碼範例顯示 includes/script_builder.js 檔案,其中包含 renderScript JavaScript 函式,可使用 SUM 匯總指標,並依維度分組:

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", "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 中自行建立自訂套件,或使用 GitHub 開放原始碼 Dataform 頁面提供的開放原始碼 Dataform 套件。

如要在 Dataform 中使用檔案包的內容,您必須在 Dataform 存放區中安裝檔案包,然後將檔案包匯入要使用該檔案包的個別 JavaScript 或 SQLX 檔案。詳情請參閱「安裝套件」。

如要在 Dataform 存放區中安裝私人 NPM 套件,您需要驗證套件

僅使用 JavaScript 建立工作流程

本節說明如何使用 JavaScript 在 Dataform 中建立工作流程動作。您可能會想使用 JavaScript 而非 Dataform 核心,在工作流程中重複建立類似的元素。

除了在 SQLX 中開發工作流程,或將 SQLX 與 JavaScript 結合,您也可以只使用 JavaScript 在 .js 檔案中建立工作流程動作。您可以使用 Dataform 全域方法和任意 JavaScript ES5 程式碼 (例如迴圈和常數),在單一 JavaScript 檔案中建立多個工作流程動作。每個 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。

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

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

建立 JavaScript 檔案

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

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

  2. 點選「建立檔案」

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

    1. 在「新增檔案路徑」欄位中,在 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 中的包含項目,請參閱本文件的「透過包含項目在單一存放區中重複使用程式碼」一節。

在 JavaScript 檔案中參照內含項目的語法取決於內含檔案的位置。Dataform 會將這類檔案儲存在 includes 目錄中。

參考頂層包含

  • 如要參照頂層包含檔案,請在宣告變數時參照檔案名稱。

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

  const {serviceName, serviceId} = service;

參照巢狀包含

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

以下程式碼範例會參照 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 宣告檔案中宣告多個資料來源。如要進一步瞭解宣告方法,請參閱 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 assert JavaScript 方法,在 JavaScript 檔案中建立手動 SQL 斷言。如要進一步瞭解斷言方法,請參閱 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 作業,請參閱「新增自訂 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)");

後續步驟