DataformでJavaScriptを使ってBigQueryのデータを変換する方法

今回はGCP(Google Cloud Platform)で提供されているDataformというETL(Extract / Transform / Load)サービスについてお話します。

DataformではGCSやBigQueryなどのデータソースに格納されているデータを読み込み、SQLX(SQLの拡張)もしくはJavaScriptを使って変換して、データストアに保存することができます。

本記事ではデータ変換にjavaScriptを使うケースの例をご紹介します。

SQLXとJavaScriptでのデータ変換の違い

SQLXで記述する場合とJavaScriptで記述する場合の例を以下に示します。

config {
  type: "table"
}

SELECT id, name FROM project_id.dataform.sample1

↑SQLXの場合

const tables = ["sample1", "sample2", "sample3"];

tables.forEach(table => {
    const table_id = `project_id.dataform.${table}`;
    publish( `${table}_extract`, {
        type: "table",
    }).query(ctx => {
        return `SELECT id, name FROM ${table_id}`;
    });
})

↑JavaScriptの場合

見てわかる通り、SQLXは静的に定義を行うのに対して、javaScriptでは変数を使って動的に定義を行えます。

SQLXは単一の大きなフローを定義するようなケースに向いていて、JavaScriptは同じ構造を持つデータセットを複数繰り返し処理するのに向いている印象です。

JavaScriptでのDataform定義の書き方

前提としてサービスアカウントに対するIAMの設定やDataformのリポジトリ、ワークスペースの作成は完了しているものとします。

JavaScriptで定義を書く場合にはdefinitionsディレクトリ配下に<filename>.jsのファイル名でファイルを作成します。

基本的には一般的なJavaScriptを記述するのと同じように、変数やロジックを記載していきます。

declareやpublishなどのDataform用の関数が用意されていて、それを利用してデータの定義やクエリ実行を行う部分がポイントとなります。

よく利用する関数は以下です。

declare

データソースを定義する関数です。以下のように記述することでdataformデータセット内のsampleテーブルをデータソースとして指定できます。

    declare({
        schema: "dataform",
        name: "sample"
    });

ここで指定したデータソースはDataformの中でref関数によって参照できます。また、COMPILED GRAPHタブでデータソースとして可視化できます。

publish

実際にデータをストアする際に利用します。例えば以下のように記述することでdeclareで定義したデータソースsampleからid, nameの列を抜き出して、BigQuery内にsample_extractテーブルを作りデータをストアできます。

FROM句で、ref関数を使ってdeclareで定義したデータソースを指定しています。

    publish( `sample_extract`, {
        type: "table",
    }).query(ctx => {
        return `SELECT id, name FROM ${ctx.ref("sample")}`;
    });

そのほか、assert, operate, testなどのDataform関数を使うことができます。

まとめ

上記のdeclare関数とpublish関数を組み合わせると以下のようにして、複数のテーブルからデータを読み込んで、加工、それぞれの新しいテーブルに書き出すということができます。

const tables = ["sample1", "sample2", "sample3"];

tables.forEach(table => {

    declare({
        schema: "dataform",
        name: table
    });

    publish( `${table}_extract`, {
        type: "table",
    }).query(ctx => {
        return `SELECT id, name FROM ${ctx.ref(table)}`;
    });
});

これをCOMPILED GRAPHでみると以下のようになります。

この例では単純ですが、複数のテーブルからUNIONやJOINで結合するようなケースがあると可視化で分かりやすくなりそうですね。

今回はDataformでJavaScriptを使って、複数テーブルを処理する例をご説明しました。

JavaScriptが使えることで動的にSQLを組み立てることができて便利ですね。GCPにはいろんなサービスがあるので、GCSのファイルをデータソースにして読み込んだり、スケジューリングの機能と連携したり用途が広がりそうです。

ぜひ、Dataformを試してみてください!

カテゴリー: データ基盤
GLASSで一緒に働いてみませんか?