0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Bigquery Dataform 〜実装編〜

Last updated at Posted at 2025-12-02

PONOS Advent Calendar 2025 3日目の記事です。

初めに:eyeglasses:

BigQueryでのデータ変換を効率化するDataform。
前回はその概要とメリットを紹介しましたが、今回は具体的な実装方法と、作業効率をさらに高めるためのテクニックをご紹介します!

1. ワークスペースの初期設定とGit連携

Dataformを使うには、まず開発環境(ワークスペース)とGitリポジトリを連携させます。これにより、チーム開発とバージョン管理が可能になります。

① ワークスペースの作成: Google CloudコンソールでDataformを開き、「ワークスペースを作成」からBigQueryプロジェクトを指定します。

② Gitリポジトリとの接続: 作成したワークスペースに、GitHubやBitbucketなどのGitリポジトリを接続します。

③ 開発ブランチの作成: mainブランチから個人用の開発ブランチ(例:feature/my-new-kpi)を作成し、ローカル環境と同じように作業を開始します。

このシンプルな設定だけで、すべてのSQLコードがバージョン管理下に置かれ、変更履歴の追跡やコードレビューが容易になります。

Webベースで開発して常にクエリ構文チェックでミスを防ぐも良し
ローカル環境で使い慣れたエディタにて開発するのも良し

スクリーンショット 2025-11-18 11.08.26.png

スクリーンショット 2025-11-18 13.43.54.png

スクリーンショット 2025-11-19 13.41.56.png

2. データ変換の基本:SQLXファイルの実装 📝

Dataformの心臓部は、通常のSQLに設定や依存関係を記述できる拡張言語 SQLX ファイルです。

2.1. 依存関係の定義 (ref()関数)

Dataformの最も強力な機能の一つが、依存関係の自動解決です。前処理されたテーブルを参照する際は、生のテーブル名を直接書くのではなく、ref()関数を使います。

✅ 実装例:前処理されたユーザーテーブルの作成

definitions/01_clean/clean_users.sqlx
config {
  type: "table",
  description: "重複を除去しクレンジングされたユーザーマスタ",
}

SELECT
  user_id,
  min(registration_time) as registration_time,
  max(last_login_time) as last_login_time
FROM
  `raw_data.users`
WHERE
  user_id IS NOT NULL
GROUP BY 1

✅ 実装例:KPIテーブルでの参照

definitions/02_aggregate/daily_kpi.sqlx
config {
  type: "table",
  description: "日別KPI集計テーブル",
}

SELECT
  t1.date,
  count(t1.user_id) as daily_active_users,
  sum(t2.sales_amount) as total_sales
FROM
  ${ref("clean_users")} as t1  -- clean_users.sqlx が先に実行されるよう自動で依存関係を解決
LEFT JOIN
  ${ref("raw_transactions")} as t2
  ON t1.user_id = t2.user_id AND t1.date = t2.date
GROUP BY 1

ポイント: ${ref("...")}を使うだけで、Dataformがclean_users.sqlxの処理完了を待ってからdaily_kpi.sqlxを実行する DAG(有向非巡回グラフ)を自動構築します。

2.2. マテリアライゼーション戦略の指定

configブロックのtypeパラメータで、テーブルの作成方法を簡単に指定できます。

type 説明 用途
"table" 標準テーブルとして作成(CREATE OR REPLACE)。最も一般的。 永続的な中間テーブル、分析用最終テーブル。
"view" ビューとして作成。クエリ実行時に毎回実行される。 データが頻繁に更新されるソース、一時的な参照。
"incremental" 増分テーブルとして作成。新しいレコードのみ追加。 巨大なログデータ、追加のみのトランザクションデータ。
"assertion" データ品質テスト(次項で解説)。 データ品質のチェック。

3. データ品質を担保するテクニック:アサーションの活用 🛡️

データ変換パイプラインにおいて最も重要なのが品質保証です。Dataformのアサーションを使えば、SQLで簡単にデータ品質テストを定義できます。

✅ 実装例:主キーの重複チェック

definitions/assertions/assert_unique_user_id.sqlx
config {
  type: "assertion",
  name: "assert_unique_user_id",
  tags: ["quality_check"]
}

SELECT
  user_id
FROM
  ${ref("clean_users")}
GROUP BY 1
HAVING count(user_id) > 1 -- 1より大きい場合はエラー(=重複がある) 

このアサーションは、clean_usersテーブルに対して実行され、もし結果が1行でも返された場合(重複レコードが存在した場合)、パイプラインの実行を失敗させることができます。これにより、品質の低いデータが分析環境に流れ込むことを防ぎます。

4. 共通ロジックの再利用:JavaScriptの活用 💡

Dataform Coreでは、SQLXファイル内にJavaScriptを埋め込むことができ、複雑なロジックや共通処理をモジュール化できます。

✅ 実装例:定数と共通処理の定義

JavaScript includes/constants.js
// プロジェクト横断で使う定数を定義
const PROJECT_ID = "data-project-prd";
const AD_PLATFORM_LIST = ["google_ads", "facebook_ads"];

// 共通で使うWHERE句を関数化
function is_active_user(months) {
  return `last_login_time >= date_sub(current_date(), interval ${months} month)`;
}

module.exports = {
  PROJECT_ID,
  AD_PLATFORM_LIST,
  is_active_user
};

✅ 実装例:SQLXでの呼び出し

definitions/02_aggregate/active_users.sqlx
config {
  type: "table"
}

-- JavaScriptモジュールをインポート
<script>
  const constants = require("constants");
</script>

SELECT
  user_id,
  last_login_time
FROM
  ${ref("clean_users")}
WHERE
  ${constants.is_active_user(3)} -- 3ヶ月以内にログインしたユーザーを抽出

JavaScriptを使うことで、同じロジックを複数のSQLファイルにコピペする手間がなくなり、コードの保守性と可読性が大幅に向上します。

5. まとめ

今回は、Dataformの具体的な実装として、ref()による依存関係定義、マテリアライゼーション、アサーションによる品質担保、そしてJavaScriptによる共通化のテクニックを紹介しました。

次回はより実践的な運用テクニックを紹介する予定です。
明日公開されるのでお楽しみに!!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?