Dataform で JavaScript を使用する

このドキュメントでは、JavaScript を使用して Dataform でワークフローを開発する方法について説明します。このドキュメントでは、JavaScript を使用してワークフロー アクションを作成する方法と、JavaScript インクルードを作成して Dataform でコードを再利用する方法についても説明します。

Dataform コアを使用すると、SQLX と JavaScript を使用してワークフロー オブジェクトを作成できます。任意ですが、SQLX とともに JavaScript を使用して、ワークフローで類似の要素を繰り返し作成します。たとえば、JavaScript を使用して、特定のユーザー ID を削除して、ワークフロー内の各テーブルのビューを作成できます。 ワークフロー アクションを JavaScript のみで開発することもできます。

始める前に

  1. Google Cloud コンソールの [Dataform] ページに移動します。

    Dataform に移動

  2. リポジトリを作成または選択します。

  3. 開発ワークスペースを作成または選択します。

また、JavaScript 構文と次の JavaScript コンセプトを理解している必要があります。

  • 変数
  • 配列
  • 条件ステートメント
  • for ループ
  • マップ
  • 関数
  • オブジェクト
  • モジュールのエクスポートとインポート

必要なロール

JavaScript を使用してワークフローを開発し、JavaScript コードを使ってコードを再利用するために必要な権限を取得するには、ワークスペースに対する Dataform 編集者roles/dataform.editor)IAM ロールの付与を管理者に依頼してください。ロールの付与については、プロジェクト、フォルダ、組織へのアクセスを管理するをご覧ください。

必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。

SQLX ファイルに JavaScript コードを追加する

JavaScript コードを SQLX ファイルに追加する方法は 2 つあります。インラインと 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 コードを再利用するには、インクルードを作成します。 複数の 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

インクルードを使用して単一のリポジトリ全体でコードを再利用する

インクルードは、リポジトリにグローバルな 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. ファイルにカスタム評価関数を記述します。

  5. このファイルに次のコード スニペットを入力します。

     module.exports = { FUNCTION_NAME }
    

    FUNCTION_NAME は、関数の名前で置き換えます。

  6. 省略可: [書式] をクリックします。

次のコードサンプルは、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 ファイルでインクルードを参照する

SQLX ファイル内の任意のインクルード関数または定数を参照できます。インクルードを参照する構文は、インクルード ファイルの場所によって異なります。最上位の includes ファイルは 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. 省略可: [書式] をクリックします。

次のコードサンプルは、ネストされた includes/allConstants/constants.js ファイルで定義された firstDate 定数をテーブル定義 SQLX ファイルで参照しています。

  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 を渡す必要があります。

次のコードサンプルは、SUM を使用して指標を集計し、ディメンションでグループ化する renderScript JavaScript 関数を含む includes/script_builder.js ファイルを示しています。

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 コアをご覧ください。

パッケージを使用して複数のリポジトリ間でコードを再利用する

パッケージは、インポートして複数の Dataform リポジトリ間で使用し、ワークフロー開発を効率化できる JavaScript コードのコレクションです。

Dataform で独自のカスタム パッケージを作成することも、GitHub のオープンソース Dataform ページで公開されているオープンソースの Dataform パッケージを使用することもできます。

Dataform でパッケージの内容を使用するには、パッケージを Dataform リポジトリにインストールし、パッケージを使用する個々の JavaScript または SQLX ファイルにインポートする必要があります。 詳細については、パッケージをインストールするをご覧ください。

Dataform リポジトリに非公開 NPM パッケージをインストールするには、パッケージを認証する必要があります。

JavaScript のみでワークフローを作成する

このセクションでは、JavaScript を使用して Dataform でワークフロー アクションを作成する方法について説明します。Dataform コアではなく JavaScript を使用して、ワークフローで類似の要素を繰り返し作成することもできます。

SQLX でワークフローを開発する方法や、SQLX と JavaScript を組み合わせる方法の代わりに、JavaScript のみを使用して .js ファイルにワークフロー アクションを作成できます。1 つの 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")}
        )`
    );
  });

このコードサンプルでは、ブロックされたユーザー ID が含まれていない user_events_blocked_removeduser_settings_blocked_removeduser_logs_blocked_removed という名前の 3 つのビューを作成します。

1 つの JavaScript ファイル内に、Dataform グローバル メソッドと任意の JavaScript ES5 コード(ループや定数など)を使用して複数のアクションを作成できます。

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() メソッドで、テーブルのプロパティを 2 番目のメソッド引数として渡して設定できます。

テーブルのプロパティを publish() の 2 番目の引数として渡す手順は次のとおりです。

  1. 開発ワークスペースの [ファイル] ペインで definitions/ を展開します。

  2. JavaScript ファイルを選択します。

  3. ファイルで、次の形式でテーブル プロパティを publish() メソッドに追加します。

     method("first_method_argument", {
       property1: "property1_value",
       property2: "property2_value",
       property3: "property3_value",
     });
    
  4. 省略可: [書式] をクリックします。

次のサンプルコードは、プロパティをメソッドの 2 番目の引数として渡して、プロパティを 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 ファイルから 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 には、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 の declare JavaScript メソッドを使用して、1 つの 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 クエリは行を返さないようにする必要があります。クエリの実行時にクエリが行を返すと、アサーションは失敗します。 1 つの 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. 省略可: [書式] をクリックします。

次のコードサンプルは、source_table の値が NULL ではないことをアサートする JavaScript アサーションを示しています。

  assert("assertion1").query(ctx => "SELECT * FROM source_table WHERE value IS NULL");

JavaScript でカスタム SQL オペレーションを定義する

Dataform の operate 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. 省略可: [書式] をクリックします。

次のコードサンプルは、some_table に単一の新しい行を挿入し、新しい行の test_column2 に設定する JavaScript ファイル内のカスタム SQL オペレーションを示しています。

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

次のステップ