👍

プロダクトの仕様変更をdbtのaccepted_valuesで検知する

に公開

はじめに

プロダクト側で、DBのスキーマ変更やステータス、カテゴリの追加があったのに、データ基盤側の更新が漏れていたという問題に遭遇したことはありませんか?

この記事では、dbtのaccepted_valuesテストを活用して、プロダクトの仕様変更 (マスターデータの変更)を検知する方法を紹介します!

dbtのaccepted_valuesで仕様変更を検知する

前提

例えば、ECサイトのプロダクトで以下のようなステータス管理をしているとします。

-- プロダクト側のステータス定義
-- 1: pending(保留中)
-- 2: confirmed(確定)
-- 3: shipped(発送済み)
-- 4: delivered(配達完了)
-- 5: cancelled(キャンセル)

dbtでは、このステータスIDを分析しやすいラベルに変換するCASE文を書くことが多いと思います。

-- dbtモデル内のCASE文
SELECT
  order_id,
  CASE status_id
    WHEN 1 THEN '保留中'
    WHEN 2 THEN '確定'
    WHEN 3 THEN '発送済み'
    WHEN 4 THEN '配達完了'
    WHEN 5 THEN 'キャンセル'
    ELSE CONCAT('未定義:', status_id)
  END AS status_label
FROM orders

問題が発生するとき

プロダクト側で機能追加があり、新しいステータスが実装されました。

-- 新しく追加されたステータス
-- 6: returned(返品)
-- 7: refunded(返金済み)

しかし、データチームへの共有が漏れており、dbtのCASE文は更新されないままになっている状態です。その結果、「未定義:6」「未定義:7」というデータが表示されてしまいます。

このとき、以下のようなことが厄介な課題です。

  • エラーにならない: クエリは正常に実行されるため、ジョブは成功する
  • 気づきにくい: 新ステータスのデータ量が少ない初期段階では、集計結果への影響が小さく見逃されがち
  • 事後対応になる: ビジネスサイドから「この数字おかしくない?」と指摘されて初めて気づく

accepted_valuesによる自動検知

dbtの標準テストであるaccepted_valuesを使うと、カラムの値が「許可された値リスト」に含まれているかをチェックできます。これを利用して、想定外の値(新ステータス)が出現したときに自動で検知します。

以下のようなテストファイルを用意することで、status_id に 1〜5 以外の値が入ってくると、dbt test実行時に検知できるようになります。

# models/staging/stg_orders.yml
version: 2

models:
  - name: stg_orders
    columns:
      - name: status_id
        description: |
          注文ステータスID
          1: 保留中, 2: 確定, 3: 発送済み, 4: 配達完了, 5: キャンセル
        tests:
          - accepted_values:
              values: [1, 2, 3, 4, 5]
              quote: false
              config:
                severity: warn
                # オプション: 1件でもあれば警告
                warn_if: ">0"

このとき、severityをwarnにすることで、定義外の値が入ってきてもエラーで処理が止まることはなく、警告として検知することができます。

運用上の注意

アラート通知を設定する

severity: warn はジョブを止めないため、意識的にログを見に行かないと見逃す可能性があります。dbtやCI/CDパイプラインの設定で、「Warningが発生した場合もSlack等に通知する」ように設定しておくのがおすすめです。

CASE文には必ず ELSE 句を入れ、未定義の値が来たことが一目で分かるようにしておきます。

CASE status_id
  WHEN 1 THEN '保留中'
  WHEN 2 THEN '確定'
  -- ...
  ELSE CONCAT('未定義:', CAST(status_id AS STRING))
END AS status_label

これにより、テスト警告を見逃してしまった場合でも、LookerやTableauなどのBIツール上で「未定義」という値が表示されるため、異変に気づくセーフティネットになります。

まとめ

プロダクトの仕様変更によるステータスやカテゴリの変更漏れは、サイレントに発生しやすい問題です。

dbtのaccepted_values テストを使うことで、想定外の値を自動で検知できます。また、severity: warn を設定することで、パイプラインを止めずに「検知」と「データ更新」を両立できます。

テストを記述することでメタデータの付与もできるため、AI活用にもつながると思います。便利な機能を活用して、データ品質を守っていきましょう。

Discussion