stable Tech Blog
🔃

Databricks JobのdbtタスクでFull RefreshとIncrementalを切り替える

に公開

はじめに

どうも、stable株式会社でデータエンジニアをしているtaroimoです。

dbtを用いてDatabricks上のテーブル群を運用していると、通常はインクリメンタルモデルで日次更新を行いつつ、データ不整合が発生した際にはフルリフレッシュで再計算したいケースがあります。

本記事では、Databricks Jobのパラメータ機能を活用し、単一のジョブ定義で実行時にオプションを切り替える方法を紹介します。さらに、Terraformで複数ジョブを管理している場合の実装パターンも解説します。

  • フルリフレッシュ専用のジョブを別途作成する
  • ジョブ定義を手動で書き換えて実行する

といった対応をすることなく、スマートな運用が可能になります。

実現したいこと

  • 通常時: dbt buildでインクリメンタル実行
  • 異常時: dbt build --full-refreshでフルリフレッシュ実行
  • 柔軟性: -selectなどの他のオプションも組み合わせ可能
  • 管理性: 単一のジョブ定義で運用

技術的な仕組み

Databricks Jobにおけるdbtタスクの概要

Databricks Jobは、データパイプラインの実行やスケジューリングを管理するDatabricksのワークフロー機能です。

dbtタスクは、このJobの中でdbtプロジェクトを実行するためのタスクタイプです。Gitリポジトリまたはワークスペース上のdbtプロジェクトを指定し、dbt runなどのdbtコマンドをDatabricksの管理画面から設定・実行できます。実行基盤にはDatabricksのSQLウェアハウスを使用するため、環境を自前で用意する必要はありません。

Databricks Jobのパラメータ機能

Databricks Jobには実行時にパラメータを渡す機能があり、{{job.parameters.パラメータ名}}という構文でコマンド内から参照できます。

公式ドキュメント:

動的値参照の仕組み

ここでは、terraformを利用してDatabricks環境を管理していることを前提に、dbtの更新処理タスクを定義します。

parameter {
  name  = "dbt_args"
  default = ""
}

task {
  dbt_task {
    commands = [
      "dbt deps",
      "dbt build {{job.parameters.dbt_args}}"
    ]
  }
}

ポイント:

  • パラメータのデフォルト値を空文字に設定
  • 空文字の場合はdbt buildのみが実行される
    • インクリメンタルモデルの場合、差分更新
  • --full-refreshのように値が渡された場合は、渡された通りに実行される

Terraformでの実装

単一ジョブの実装例

resource "databricks_job" "dbt_job" {
  name                = "transform_my_models"
  description         = "dbtモデルの実行ジョブ(パラメータ対応)"
  max_concurrent_runs = 1

  # パラメータ定義
  parameter {
    name    = "dbt_args"
    default = ""
  }

  environment {
    environment_key = "default"
    spec {
      dependencies = [
        "dbt-core==1.9.10",
        "dbt-databricks==1.10.1",
      ]
      environment_version = "4"
    }
  }

  git_source {
    url      = "<https://github.com/your-org/dbt-project.git>"
    branch   = "main"
    provider = "gitHub"
  }

  task {
    task_key         = "dbt_run"
    environment_key  = "default"

    dbt_task {
      commands = [
        "dbt deps",
        "dbt build -s +my_models {{job.parameters.dbt_args}}"
      ]
      project_directory = "your_project"
      warehouse_id      = "your_warehouse_id"
    }
  }

  schedule {
    quartz_cron_expression = "0 0 6 * * ?"
    timezone_id            = "Asia/Tokyo"
    pause_status           = "UNPAUSED"
  }
}

Terraform applyの実行結果

既存ジョブへのパラメータ追加は、リソースの更新として扱われます:

Plan: 0 to add, 1 to change, 0 to destroy.

# 既存ジョブにパラメータが追加される
~ resource "databricks_job" "dbt_jobs" {
    id   = "XXXXXXXXX"
    name = "transform_my_models"

  + parameter {
      + name    = "dbt_args"
      + default = ""
    }
}

運用方法

通常実行(インクリメンタル)

スケジュール実行、または手動実行でそのまま実行します。パラメータはデフォルトの空文字が使われます。

実行されるコマンド:
dbt build -s +my_models

フルリフレッシュ実行

Databricks UIの「Run now with different parameters」から下記の流れで実行します:

  1. ジョブ詳細画面で「Run now」の横の▼をクリック
  2. 「Run now with different parameters」を選択
  3. dbt_argsパラメータに--full-refreshを入力
  4. Runを押して実行
実行されるコマンド:
dbt build -s +my_models --full-refresh

その他の活用例

# 変数を渡す
dbt_args: --vars '{"start_date": "2024-01-01"}'

# デバッグ
dbt_args: --debug

設計上の考慮点

パラメータのデフォルト値は空文字に

デフォルト値を--full-refreshにしてしまうと、スケジュール実行時に毎回フルリフレッシュされてしまいます。実務では通常運用をインクリメンタルにするケースがほとんどだと思われます。
空文字をデフォルトに設定することを推奨します。

既存ジョブへの影響

既存のジョブにパラメータを追加する際は、Terraform planで変更内容を確認してから適用することをお勧めします。パラメータ追加自体はジョブの動作に影響しませんが、意図しない変更が含まれていないか確認しましょう。

まとめ

Databricks Jobのパラメータ機能を使うことで:

  • 単一のジョブ定義で柔軟な実行オプションを実現
  • 通常時はインクリメンタル、異常時はフルリフレッシュという運用が容易に

特に、既存のTerraform管理パターンを大きく変更せずに導入できる点が実用的です。

dbtとDatabricksの組み合わせで運用している方は、ぜひ試してみてください。

参考

stable Tech Blog
stable Tech Blog

Discussion