chisataki’s blog

リコリス・リコイルじゃありません

Dataformとは何者か?

概要

BigQuery用のSQLワークフローの開発、テスト、バージョン管理、スケジュール設定ができるサービス

具体的に何ができるの?

  • テーブル定義や集計処理を、SQLXというSQLの拡張言語で記述することで、テーブル間の依存関係を元にワークフローを実行できる
  • レコードの空欄(Null値)チェックや重複データが存在していないかなどのカスタム検証処理を実行できる
  • ファイルのバージョン管理にGitを使用。Dataformリポジトリを作成すれば、GitHubやGitLabリポジトリに接続できる。
  • ワークフロー構成(Dataformの機能の一つ)やWorkflows, Cloud Composerを使用して、ワークフローの実行をスケジュールできる
  • 依存関係を含んだワークフローを、インタラクティブ有向非巡回グラフ(DAG)として表示できる


DAG表示例:

DAG例. second_viewがfirst_viewを依存関係に持つ

Dataform実行の流れ

  1. リポジトリを作成
  2. 開発用のワークスペースを作成
  3. ワークスペースでワークフローを開発(SQLXあるいはJavascript)
  4. コードを(リアルタイムで)SQLクエリにコンパイル
  5. テーブルの依存関係に従ってワークフローを実施

SQLXファイルの構成

SQLXファイルはconfigブロック、jsブロック、本文ブロックの3つから構成される。

  • configブロック:作成するテーブルタイプ(通常のテーブル、増分テーブル、ビュー)やテスト項目、依存関係などを記述する
  • jsブロック:Javascriptを記述する。定義された定数はbodyブロックで使用することができる。
  • bodyブロック:実行するSQLコードを記述する。Dataformコア*の組み込み関数が使用できる(依存関係を参照するref関数など)



*Dataformコア:Dataform内部で使用される、テーブルとワークフローを作成するためのメタ言語(SQL拡張言語)。依存関係管理システム、テスト機能、ドキュメント(テーブルや列の説明など)を提供する。 @Dataform/core npm


SQLX記述例:

//configブロック
config : {
  type: "table",
  assertions: {
    nonNull: ["user_id", "customer_id"] // Null値がないことのテスト
  }
}

//jsブロック
js {
  const someDate = require("includes/sample.js"); // Javascript定数をインポート
}

//bodyブロック
SELECT 
  user_id,
  customer_id,
  session_date
FROM
  ${ref("some_table")} // 依存テーブルの参照
WHERE 
  session_date > ${someDate} // Javascript定数の参照


ワークフローの実行

SQLXファイルを作成したら、definitions/ フォルダに配置し、ファイル編集ペイン上部にある「実行を開始」から作成したワークフローが実行できます。


Javascriptのパッケージをインストールして使用する

上述のコードのように、Javascriptの定数や関数は自作してSQLXファイルのjsブロックで呼び出すことができますが、npmJSやGitHubで公開されているNPMパッケージをインストールして使うこともできます。 その場合、package.jsonファイルのdependenciesブロックに "パッケージ名":"URL" の形で記載します。

{
  "name": "your-repository",
  "dependencies": {
    "@dataform/core": "2.0.1",
    "dataform-scd": "https://github.com/dataform-co/dataform-scd/archive/0.4.tar.gz" // "ゆっくり変化するディメンション" パッケージのインストール 
  }
}

参照:ゆっくり変化するディメンション


検証処理(テスト項目)の記載方法

Dataformでは、Null値や重複レコードのチェック、またはカスタム作成したテスト項目をSQLXファイルのconfigブロック内のassertionsブロックに記載することで、テーブルの作成前に検証処理が可能になります。(もしテストが不合格であればテーブルの作成はされません)

config {
  type:"table",
  assertions: {
    nonNull : ["user_id"], // Nullではないことのテスト. 複数列記載可能
    uniqueKey : ["customer_id"], // 一意であることのテスト
    rowConditions : [
      'session_date is null or session_date > "2022-08-01"', // カスタムSQL式
    ]
  }
}    

参考:アサーションでテーブルを検証する