dbt platformで祝日のみ実行する条件付きジョブを実装してみた

dbt platformで祝日のみ実行する条件付きジョブを実装してみた

2026.03.14

かわばたです。

dbt platformには定期的にジョブを実行する機能があります。
cronによる日時指定もできるので比較的自由度は高いです。
ただし、これだけでは表現できないイレギュラーなケースもあります。
例えば、「第二営業日の翌日9:00に実行」や「祝日のみ実行」などが当たります。

今回はdbt platformで祝日マスターテーブルを作成し、祝日のみ実行するジョブをdbt platformで実現する方法を検証しました。

【公式ドキュメント】
dbt seeds
https://docs.getdbt.com/docs/build/seeds

dbt run-operation
https://docs.getdbt.com/reference/commands/run-operation

対象読者

  • dbtで祝日判定を行いたい方
  • dbt platformで条件付きジョブ実行を実現したい方
  • dbt platformだけでイレギュラーケースを対応したい方

検証環境

  • dbt platform Enterprise版
    • Latestバージョン
  • Snowflakeトライアルアカウント Enterprise版

アプローチ

dbt platformのジョブスケジューラーには「祝日のみ実行」という機能がないため、以下の方法で実現します。

【処理フロー】
1. seed: 日本の祝日データをロード
2. model: 祝日マスターテーブル
3. macro: 祝日チェックマクロ(祝日でなければエラーで中断)
4. dbt platform Job: 毎日実行 → マクロで祝日判定 → 祝日なら後続処理実行

実際に試してみた

プロジェクト構成

holiday_dbt/
├── dbt_project.yml
├── profiles.yml
├── seeds/
│   └── japanese_holidays.csv      # 日本の祝日データ(2024-2026年)
├── models/
│   └── marts/
│         └── dim_holidays.sql       # 祝日マスターテーブル


└── macros/
    └── holiday_job_control.sql    # check_holiday_and_abort()

seedデータ(日本の祝日)

日本の祝日データをCSVで管理します。振替休日も含めています。

holiday_date,holiday_name,holiday_type
2024-01-01,元日,national
2024-01-08,成人の日,national
2024-02-11,建国記念の日,national
2024-02-12,振替休日,substitute
2024-02-23,天皇誕生日,national
2024-03-20,春分の日,national
2024-04-29,昭和の日,national
2024-05-03,憲法記念日,national
2024-05-04,みどりの日,national
2024-05-05,こどもの日,national
...

dbt_project.yml

seedのカラム型を明示的に指定します。


# Name your project! Project names should contain only lowercase characters
# and underscores. A good package name should reflect your organization's
# name or the intended use of these models
name: 'my_new_project'
version: '1.0.0'
config-version: 2

# This setting configures which "profile" dbt uses for this project.
profile: 'default'

# These configurations specify where dbt should look for different types of files.
# The `model-paths` config, for example, states that models in this project can be
# found in the "models/" directory. You probably won't need to change these!
model-paths: ["models"]
analysis-paths: ["analyses"]
test-paths: ["tests"]
seed-paths: ["seeds"]
macro-paths: ["macros"]
snapshot-paths: ["snapshots"]

target-path: "target"  # directory which will store compiled SQL files
clean-targets:         # directories to be removed by `dbt clean`
  - "target"
  - "dbt_packages"

# Configuring models
# Full documentation: https://docs.getdbt.com/docs/configuring-models

seeds:
  my_new_project:
    japanese_holidays:
      +column_types:
        holiday_date: date
        holiday_name: varchar(100)
        holiday_type: varchar(50)

models:
  my_new_project:
    marts:
      +materialized: table

祝日マスターテーブル(dim_holidays.sql)

seedデータに年・月・曜日を追加したマスターテーブルです。

{#
  ============================================================================
  dim_holidays - 日本の祝日マスターテーブル
  ============================================================================

#}

{{ config(
    materialized='table',
) }}

select
    -- === 基本カラム(seedデータから取得) ===
    holiday_date,                                   -- 祝日の日付
    holiday_name,                                   -- 祝日名
    holiday_type,                                   -- 祝日種別(national/substitute)

    -- === 派生カラム(分析・集計用) ===
    extract(year from holiday_date) as holiday_year,    -- 年(例: 2026)
    extract(month from holiday_date) as holiday_month,  -- 月(例: 1〜12)
    dayname(holiday_date) as day_of_week                -- 曜日(例: Mon, Tue)

from {{ ref('japanese_holidays') }}

祝日チェックマクロ(holiday_job_control.sql)

祝日でない場合にエラーを発生させ、ジョブを中断します。

{#
  ============================================================================
  run_only_on_holiday マクロ
  ============================================================================
  概要:
    モデル内で呼び出し、今日が祝日でない場合はモデルの実行を停止する

  使用方法:
    モデルのSQLファイル内で以下のように呼び出す
    {{ run_only_on_holiday('model_name') }}

  引数:
    model_name: ログ出力用のモデル名(任意の文字列)

#}
{% macro run_only_on_holiday(model_name) %}
    {# 祝日マスターテーブルから今日の祝日件数を取得するクエリを定義 #}

    {% set is_holiday_query %}
        select count(*) as cnt
        from {{ target.database }}.DBT_TKAWABATA.dim_holidays
        where holiday_date = current_date()
    {% endset %}

    {# execute: dbt compile時はfalse、dbt run時はtrue #}
    {# compile時にクエリ実行を防ぐためのガード条件 #}
    {% if execute %}
        {# Snowflakeに対してクエリを実行し、結果を取得 #}
        {% set result = run_query(is_holiday_query) %}

        {# 結果の1列目・1行目の値を取得し、0より大きければ祝日 #}
        {% set is_holiday = result.columns[0].values()[0] > 0 %}

        {% if not is_holiday %}
            {# 祝日でない場合: ログ出力してスキップ #}
            {{ log("Skipping " ~ model_name ~ " - today is not a holiday", info=True) }}
            {{ return(none) }}
        {% else %}
            {# 祝日の場合: ログ出力して処理を継続 #}
            {{ log("Running " ~ model_name ~ " - today is a holiday!", info=True) }}
        {% endif %}
    {% endif %}
{% endmacro %}

{#
  ============================================================================
  check_holiday_and_abort マクロ
  ============================================================================
  概要:
    dbt run-operation で呼び出し、今日が祝日でない場合はジョブ全体を中断する
    dbt platformのジョブで「祝日のみ実行」を実現するためのゲートキーパー

  使用方法:
    dbt platform Job の Commands で最初に実行する
    dbt run-operation check_holiday_and_abort
    dbt run 

  動作:
    祝日でない場合: Compilation Error を発生させ、ジョブを中断
    祝日の場合: ログ出力のみで正常終了、後続コマンドが実行される
#}
{% macro check_holiday_and_abort() %}
    {# 祝日マスターテーブルから今日の祝日件数を取得するクエリを定義 #}

    {% set is_holiday_query %}
        select count(*) as cnt
        from {{ target.database }}.DBT_TKAWABATA.dim_holidays
        where holiday_date = current_date()
    {% endset %}

    {# execute: dbt compile時はfalse、dbt run時はtrue #}
    {# compile時にクエリ実行を防ぐためのガード条件 #}
    {% if execute %}
        {# Snowflakeに対してクエリを実行し、結果を取得 #}
        {% set result = run_query(is_holiday_query) %}

        {# 結果の1列目・1行目の値(祝日件数)を取得 #}
        {% set holiday_count = result.columns[0].values()[0] %}

        {% if holiday_count == 0 %}
            {# 祝日でない場合: エラーを発生させてジョブを中断 #}
            {# これにより dbt platform の後続コマンドは実行されない #}
            {{ exceptions.raise_compiler_error("Today is not a holiday. Job aborted.") }}
        {% else %}
            {# 祝日の場合: ログ出力して正常終了 #}
            {{ log("Holiday check passed. Proceeding with job execution.", info=True) }}
        {% endif %}
    {% endif %}
{% endmacro %}

dbt platformでのジョブ設定

基盤モデルのデプロイ

まず、祝日マスターテーブルをデプロイします。

dbt seed
dbt run

dbt seed japanese_holidays
ベースとなる日本の祝日に関するデータ
2026-03-14_18h42_47

dbt run dim_holidays
派生カラムも作成し、祝日マスタを作成
2026-03-14_18h53_33

祝日のみ実行するジョブ

Environmentを本番用に作成し、jobを作成します。
以降のジョブ本体では model・test・snapshot等もまとめて対象にできるようdbt buildを利用します。

Job設定:

項目 設定値
Job name test_job
Environment Production
Triggers - Schedule Cron schedule
Timing Every day at 9:00 AM JST

Commands:

dbt run-operation check_holiday_and_abort
dbt build

2026-03-14_19h51_13

動作確認

祝日ではない日の場合(例: 2026-03-14)
→ エラーで中断、後続は実行されない

2026-03-14_19h35_44

祝日の場合
祝日マスタに2026-03-14を加えてジョブ実行していきます。
2026-03-14_19h41_54

想定通りジョブが通っています。
2026-03-14_20h04_48

モデルにマクロを設定して制御

dim_holidays.sqlにrun_only_on_holidayマクロを追加し、祝日でない場合はスキップする設定にしました。

{#
  ============================================================================
  dim_holidays - 日本の祝日マスターテーブル
  ============================================================================

#}

{{ config(
    materialized='table',
) }}

{# 祝日でない場合はこのモデルをスキップ #}
{{ run_only_on_holiday('dim_holidays') }}

select
    -- === 基本カラム(seedデータから取得) ===
    holiday_date,                                   -- 祝日の日付
    holiday_name,                                   -- 祝日名
    holiday_type,                                   -- 祝日種別(national/substitute)

    -- === 派生カラム(分析・集計用) ===
    extract(year from holiday_date) as holiday_year,    -- 年(例: 2026)
    extract(month from holiday_date) as holiday_month,  -- 月(例: 1〜12)
    dayname(holiday_date) as day_of_week                -- 曜日(例: Mon, Tue)

from {{ ref('japanese_holidays') }}

検証環境では同様の制御ができることを確認できました。
ただし、モデル内マクロによる制御はジョブ全体の停止とは性質が異なるため、用途に応じて使い分けが必要です。

また、こちらはジョブではなくモデルに対しての制御なので、下記のように指定していないモデルは実行されます。

2026-03-14_20h20_53

運用時のポイント

ジョブ失敗の通知設定

祝日でない日は意図的にジョブが失敗するため、dbt platformの通知設定で「祝日チェック失敗」を除外するか、別途監視ルールを設定することをおすすめします。

最後に

今回の検証で、dbtのseed、model、macroを組み合わせることで、dbt platformで「祝日のみ実行するジョブ」を実現できることが確認できました。

ポイントはマクロで祝日判定を行い、条件を満たさない場合はエラーで中断するという方法です。dbt platformのスケジューラー自体には条件実行機能がありませんが、この方法で柔軟なジョブ制御が可能になります。
祝日以外に関してはエラーとしてjobが終わるので通知設定は検討が必要です。

一部のケースだけがイレギュラーで、専用のオーケストレーションツールを導入するほどではない場合に活用いただければと思います。

この記事が何かの参考になれば幸いです!

この記事をシェアする

FacebookHatena blogX

関連記事