Dataform で 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 コードを追加する

JavaScript コードを SQLX ファイルに追加する方法は、インラインと JavaScript ブロック内の 2 つがあります。

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/ のサブディレクトリにあります。

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}

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 ファイルでワークフロー アクションを作成できます。Dataform グローバル メソッドと任意の JavaScript ES5 コード(ループや定数など)を使用して、1 つの 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")}
        )`
    );
  });

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

Dataform グローバル メソッドと任意の JavaScript ES5 コード(ループや定数など)を使用して、1 つの 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() メソッドでは、テーブル プロパティを 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. contextable 引数に、パラメータがコンテキスト オブジェクトであるクエリ関数を入力します。

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

次のコードサンプルは、パブリッシュメソッドのコンテキスト対応引数にラップされた ref クエリ関数を示しています。

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

JavaScript を使用してワークフローのデータソースを宣言する

Dataform の 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 オペレーションの詳細については、オペレーションを作成するをご覧ください。

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 に新しい行を 1 つ挿入し、新しい行の test_column2 に設定する JavaScript ファイルのカスタム SQL オペレーションを示しています。

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

次のステップ