Contents
1. Dataform が担う役割と全体像
Dataform は SQLX(拡張 SQL) と JavaScript によりテーブル・ビューの定義やテストを記述し、依存関係を自動で DAG 化します。これにより手作業で実行順序を管理する必要がなくなり、Git でバージョン管理できるコードベースの ELT が実現します。
1‑1. コンポーネント別の位置付け
| コンポーネント | 主な役割 |
|---|---|
| Raw 層 | Cloud Storage / Pub/Sub から取得した生データを raw_* テーブルに保存 |
| Transform 層 | Dataform が SQLX/JS で変換ロジックを実行し、集計テーブル・ビューを生成 |
| Presentation 層 | Looker Studio 等が最終ビューを参照してレポート作成 |
| スケジューラ | Cloud Scheduler が定期的に dataform run をトリガー |
| CI/CD | Cloud Build または GitHub Actions がテスト・デプロイを自動化 |
この構成は Google の公式ドキュメントでも推奨されており、Dataform on BigQuery の概要 に詳しく記載されています。
2. Dataform プロジェクトの作成と資産定義
2‑1. 初期化手順とディレクトリ構造
まずは Cloud Shell(またはローカル環境)でプロジェクトを作成します。以下のコマンドは Git リポジトリ と連携した状態で Dataform の雛形を生成し、必要な npm パッケージをインストールする流れです。
|
1 2 3 4 5 6 7 8 9 |
# 作業ディレクトリ作成 mkdir my-bq-pipeline && cd my-bq-pipeline # Dataform プロジェクトの初期化(デフォルト DB/スキーマは自プロジェクトに合わせて指定) dataform init --default-database=my_project --default-schema=analytics # npm パッケージをインストール npm install @dataform/core @dataform/api |
ディレクトリ例
|
1 2 3 4 5 6 7 8 9 |
my-bq-pipeline/ ├─ dataform.json # Dataform の全体設定 ├─ package.json # npm スクリプト・依存関係 ├─ models/ # SQLX ファイル(テーブル / ビュー定義) │ ├─ raw_transactions.sqlx │ └─ sales_daily.sqlx └─ assertions/ # JavaScript で記述するデータ品質テスト └─ valid_amount.js |
2‑2. dataform.json と package.json のポイント
dataform.jsonは BigQuery プロジェクトやデフォルトスキーマ、認証情報を宣言します。package.jsonに登録したスクリプト (npm run test,npm run run) で CI/CD パイプラインから簡単に呼び出せます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ "name": "my-bq-pipeline", "version": "0.1.0", "scripts": { "test": "dataform test", "run": "dataform run" }, "dependencies": { "@dataform/core": "^2.2.0", "@dataform/api": "^2.2.0" } } |
2‑3. SQLX アセットの書き方(例:生データテーブル)
コードブロックの前に、外部ソースからデータを取得し BigQuery のテーブルとして永続化する 手順であることを説明します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
-- models/raw_transactions.sqlx config { type: "table", -- テーブルとして永続化 schema: "raw", -- スキーマは raw 層用に分離 description: "外部システムから取り込んだ取引データ" } /* EXTERNAL_QUERY を使うと、別プロジェクトや Cloud SQL のテーブルを直接参照できます。 以下の例では `source_table` が外部データベースに格納されている前提です。 */ SELECT * FROM EXTERNAL_QUERY( "project.region.location", "SELECT * FROM source_table" ); |
2‑4. JavaScript アセットでデータ品質テストを定義
JavaScript ファイルは Dataform の assert 関数 を利用して、クエリ結果が期待通りか検証します。ここでは「金額が負のレコードが無いこと」をチェックしています。
|
1 2 3 4 5 6 7 8 9 10 |
// assertions/valid_amount.js module.exports = (test) => { test.assert( // テスト対象クエリ sql => `SELECT COUNT(*) AS cnt FROM ${ref('raw_transactions')} WHERE amount < 0`, // 期待結果オブジェクト { expected: [{ cnt: "0" }] } ); }; |
2‑5. インクリメンタルビルドの仕組み
ref('table_name') が自動的に DAG のエッジとなり、変更があったノードだけを再実行します。たとえば sales_daily が更新された場合、依存している sales_summary も自動で再計算されます(公式ドキュメント参照: https://cloud.google.com/dataform/docs/reference/config#ref)。
3. クエリ最適化とコスト削減テクニック
BigQuery はスキャンしたデータ量に応じて課金されるため、パーティション と クラスタリング を正しく設定するだけで数十%のコスト削減が可能です。Google のベストプラクティス(2024‑2025 年版)によれば、日次パーティションと適切なクラスタキーを組み合わせることで スキャン量を最大 90 % 削減できると報告されています。
3‑1. パーティショニングとクラスタリングの設定例
以下は売上集計テーブル sales_daily に対し、日付でパーティション化し product_id でクラスタリングする構成です。コード前に「どのようなメリットが得られるか」を簡潔に説明します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
-- models/sales_daily.sqlx config { type: "table", schema: "analytics", partitionBy: {field: "dt", type: "day"}, -- 日次パーティション clusterBy: ["product_id"] -- 同一商品をまとめて格納 } /* この設定により、日付フィルタが無いクエリは対象日のみスキャンされ、 product_id が同じ行が物理的に近くなるため集計処理が高速化します。 */ SELECT DATE(event_timestamp) AS dt, product_id, SUM(amount) AS total_amount FROM ${ref("raw_transactions")} GROUP BY dt, product_id; |
3‑2. 増分ロード(CDC)を実現する MERGE 文
フルリロードは毎回全データをスキャンしますが、MERGE を使えば変更があった行だけを処理できます。以下の例では当日分のみを対象に増分更新しています。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
-- models/staging_transactions_incremental.sqlx config {type: "incremental"} -- インクリメンタルテーブルとして宣言 MERGE INTO ${self()} AS target USING ( SELECT * FROM ${ref("staging_transactions")} WHERE _PARTITIONTIME = CURRENT_DATE() ) AS source ON target.id = source.id WHEN MATCHED THEN UPDATE SET amount = source.amount, updated_at = CURRENT_TIMESTAMP() WHEN NOT MATCHED THEN INSERT (id, amount, created_at) VALUES (source.id, source.amount, CURRENT_TIMESTAMP()); |
効果の根拠
- パーティションプルーニングによりスキャン対象は当日分だけ(約 1/30)
- MERGE による行単位更新で、フルリロードと比べ 80 % 以上 のデータ量削減が期待できます(BigQuery の公式ドキュメント: https://cloud.google.com/bigquery/docs/using-merges)。
3‑3. ベストプラクティスまとめ
| 項目 | 推奨設定例 | 想定効果 |
|---|---|---|
| 日付型カラム | partitionBy: {field:"event_date", type:"day"} |
フィルタで 90 % データ除外可能 |
| 高頻度検索キー | clusterBy:["user_id"] |
同一ユーザー行が近接し、スキャン量削減 |
| 大規模テーブル | 複合クラスタリング例: ["country","device_type"] |
多次元絞り込みで更なるコスト削減 |
4. スケジューリングと CI/CD の実装
4‑1. Cloud Scheduler と Cloud Build の連携
目的:毎日決まった時刻に Dataform パイプラインを自動実行し、失敗した場合はリトライで耐障害性を確保します。以下の手順では、Scheduler が HTTP リクエストで Cloud Build トリガーを呼び出す構成です。
|
1 2 3 4 5 6 7 8 9 10 |
# Cloud Scheduler ジョブ作成例(毎日 02:00 JST に実行) gcloud scheduler jobs create http bq-pipeline-daily \ --schedule="0 2 * * *" \ --time-zone="Asia/Tokyo" \ --uri="https://cloudbuild.googleapis.com/v1/projects/${PROJECT_ID}/triggers/${TRIGGER_ID}:run" \ --http-method=POST \ --oauth-service-account-email=${SERVICE_ACCOUNT} \ --retry-count=3 \ --max-retry-duration=3600s |
--scheduleは cron 形式、タイムゾーンは必ず明示します。--retry-countと--max-retry-durationにより、エラー時の自動リトライが有効になります。
4‑2. CI/CD パイプライン例(Cloud Build)
ポイント:ビルドステップはすべて公式コンテナ (node:18) を使用し、依存関係インストール → テスト実行 → 本番デプロイの順に進めます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# cloudbuild.yaml steps: # 1️⃣ npm パッケージをインストール - name: node:18 entrypoint: npm args: ["ci"] # ci は lock ファイル通りにインストール # 2️⃣ Dataform テスト実行(assertion がすべて成功するか確認) - name: node:18 entrypoint: npx args: ["dataform", "test"] # 3️⃣ 本番環境へデプロイ(--default-schema=prod で本番スキーマを指定) - name: node:18 entrypoint: npx args: ["dataform", "run", "--default-schema=prod"] timeout: 600s # 最大実行時間は10分に設定 |
4‑3. 同様のフローを GitHub Actions で構築する場合
GitHub Actions の設定例です。環境変数 GOOGLE_APPLICATION_CREDENTIALS に GCP サービスアカウントキーを渡す点が重要です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# .github/workflows/dataform.yml name: Dataform CI/CD on: push: branches: [ main ] jobs: build-and-deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 # Node 環境のセットアップ - name: Setup Node uses: actions/setup-node@v3 with: node-version: '18' # 依存関係インストール(ci は lockfile に忠実) - run: npm ci # Dataform テスト実行 - name: Run Dataform tests run: npx dataform test # 本番デプロイ - name: Deploy to BigQuery (prod) env: GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GCP_KEY }} run: npx dataform run --default-schema=prod |
選択の指針
- Cloud Build は GCP 内で完結するためネットワーク遅延が少なく、IAM 管理が一元化できます。
- GitHub Actions はリポジトリ中心の開発フローに馴染みやすく、外部 CI ツールとの統合が容易です。
5. 可観測性・運用設計(モニタリング・IAM・ロールバック)
5‑1. ログとメトリクスでパイプラインを可視化
Dataform の実行は Cloud Build ステップとして出力され、すべて Cloud Logging に保存されます。以下の手順でカスタム指標を作成し、遅延や失敗をリアルタイムに検知できます。
- ログベース指標の作成(Console → Logging → Logs-based metrics)
- フィルタ例:
resource.type="cloud_build" AND jsonPayload.message:"dataform run" -
指標名:
custom_dataform_success_count(成功実行数カウント) -
アラートポリシーの設定(Console → Monitoring → Alerting)
- 条件例: 過去 5 分間で
custom_dataform_success_count < 1→ Slack / Email に通知
詳細は公式ドキュメント「Logging ベース指標とアラート」を参照してください。
5‑2. 最小権限 IAM ロール設計
| サービス | 推奨ロール(最小権限) | 主な権限 |
|---|---|---|
| BigQuery データセット | roles/bigquery.dataEditor(対象データセットのみ) |
テーブル作成・書き込み |
| Cloud Build (Dataform 実行) | roles/cloudbuild.builds.editor + roles/iam.serviceAccountUser |
ビルド実行、サービスアカウント使用 |
| Cloud Scheduler | roles/cloudscheduler.jobRunner |
ジョブ起動 |
| Cloud Logging & Monitoring | roles/logging.viewer, roles/monitoring.viewer |
ログ閲覧・メトリクス取得 |
IAM バインディング例
|
1 2 3 4 |
gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:${DATAFORM_SA}" \ --role="roles/bigquery.dataEditor" |
5‑3. 障害時のロールバック手順
- 失敗ジョブを特定:Cloud Logging のエラーログで
dataform runステップ ID を検索。 - コードを前バージョンに戻す:Git で対象コミットへチェックアウトし、インクリメンタル実行をリセット。
- 再デプロイ:
dataform run --full-refresh(全テーブル再作成)または--reset(増分のリセット)を実行。 - 品質検証:
dataform testで assertions を再度走らせ、期待通りの結果が得られるか確認。
|
1 2 3 4 5 |
# ロールバック例 git checkout HEAD~1 # 前回コミットへ戻す npx dataform run --full-refresh # テーブルを全刷新 npx dataform test # データ品質テスト実行 |
まとめ
- Dataform は SQL と JavaScript だけで ELT パイプライン全体をコード化し、依存関係・インクリメンタル実行を自動管理できる。
- パーティション+クラスタリング の適切な設計でクエリスキャン量を最大 90 % 削減し、コストを大幅に抑制可能。
- Cloud Scheduler + Cloud Build / GitHub Actions による CI/CD は、テスト自動化と本番デプロイの信頼性を向上させる。
- ログベース指標と最小権限 IAM を組み合わせた可観測性・セキュリティ設計で、障害時も迅速にロールバックできる。
これらのベストプラクティスを自社プロジェクトに取り入れれば、BigQuery と Dataform の連携によるデータ基盤構築が高速かつ安全に進められます。ぜひ実装してみてください。