dbt の generic tests は、YAML で宣言的にデータ品質を担保できる最初の一歩です。本稿では、最も頻出の4種 unique / not_null / accepted_values / relationships を中心に、挙動と使い分けを実務目線で解説します。
試験対策としては、各テストのパラメータ、NULL の扱い、参照整合性の定義方法、where フィルタや severity などの設定が問われがちです。公式ドキュメントの安定機能に基づいて、再現性のある記述のみを扱います。
dbt の generic tests は、モデル(テーブル/ビュー)やその列に対して SQL マクロで生成される検証クエリです。schema.yml(任意名の YAML)にテストを宣言し、dbt test で実行すると、失敗行が返れば失敗、返らなければ成功と判定されます。
代表的な4種は、欠損禁止(not_null)、一意性(unique)、受理値の限定(accepted_values)、参照整合性(relationships)です。where で対象行を絞り、severity で失敗の扱い(error/warn)を制御できます。
| テスト | 主なユースケース | 失敗が示すこと | 実務上の注意 |
|---|---|---|---|
| not_null | 必須キーや必須属性の欠損禁止 | NULL が存在する | NULL の意味設計。派生列の NULL は集計ロジックで救済するか検討 |
| unique | 自然キー/サロゲートキーの一意性 | 重複値、または NULL を含む | dbt の unique は NULL も失敗に含む。明示的に not_null と併用すると原因特定が容易 |
| accepted_values | 状態コード・区分値のホワイトリスト | リスト外の値、または NULL(許容しない場合) | 数値や boolean は quote: false。NULL を許可するなら values に null を含める |
| relationships | 外部キー整合性(事実→次元) | 参照先に存在しないキーがある | 結合キーの型/トリム/大文字小文字。大型事実表ではコストに注意し where でスコープ |
テスト定義の流れ(概念)
最小の schema.yml 例(4種まとめ)
version: 2
models:
- name: dim_customers
columns:
- name: customer_id
tests:
- not_null
- unique
- name: status
tests:
- accepted_values:
values: ['active', 'inactive']
quote: true
- name: fct_orders
columns:
- name: customer_id
tests:
- relationships:
to: ref('dim_customers')
field: customer_id
- not_null
not_null は対象列に NULL が存在しないことを検証します。主キー、外部キー、運用上必須な属性に付けるのが基本です。
派生列(例: 正規化や集計で作ったフラグ)の NULL は「未判定」を意味する場合があり、無条件に not_null を付けると運用で詰まることがあります。NULL を許容し、ダッシュボード側で既定値補完する方が安全な場面もあります。
not_null に where を付ける例
version: 2
models:
- name: dim_products
columns:
- name: product_sku
tests:
- not_null:
where: "is_active = true"dbt の unique は、重複値に加えて NULL も失敗として扱います(実装上、NULL 行抽出と重複抽出を合成したクエリを生成)。そのため、厳密には unique 単体で not_null を内包します。
ただし、失敗原因の特定を容易にするため、主キー列には not_null と unique を両方記述するのがベストプラクティスです。複合一意性が必要な場合は、サロゲートキーを生成するか、カスタムテスト(あるいは実績あるパッケージのマクロ)を検討します。
unique と not_null の併用(主キー想定)
version: 2
models:
- name: dim_dates
columns:
- name: date_key
tests:
- not_null
- uniqueaccepted_values は、列の値が事前に許可した集合に含まれるかを検証します。業務コード、状態、フラグ列に有効です。数値・真偽値は quote: false、文字列は quote: true が分かりやすい指定です。
NULL を許容したい場合は、YAML の values に null を含めます(クオートしない null)。大小文字の扱いはデータベースの照合順序に依存するため、必要に応じて列側を正規化してからテストすると安定します。
accepted_values の例(NULL 許容、数値型)
version: 2
models:
- name: dim_status
columns:
- name: status
tests:
- accepted_values:
values: ['active', 'inactive', null]
quote: true
- name: importance_level
tests:
- accepted_values:
values: [1, 2, 3]
quote: false
where: "is_deprecated = false"relationships は、事実テーブルの外部キーが次元テーブルの主キーに存在することを検証します。to で参照先モデル、field で参照先の列を指定します。定義場所が columns セクションなら column_name は暗黙に対象列になります。
巨大な事実表ではコストが高くなりやすいので、where で直近 N 期間に絞るなどの運用が現実的です。キー型の不一致、前後空白、大小文字違いは定番の失敗要因です。
事実テーブルと次元テーブルの参照関係
relationships の YAML 例(列定義内)
version: 2
models:
- name: fct_orders
columns:
- name: customer_id
tests:
- not_null
- relationships:
to: ref('dim_customers')
field: customer_id
where: "order_date >= dateadd('day', -30, current_date)"運用では、スモールスタート(主要キーと主要ディメンションから)でテストを追加し、失敗時の対応手順(連絡先、ロールバック可否、許容度)を runbook 化しておくと安定します。CI では dbt test を PR 毎に実行し、severity=warn を段階的に error に引き上げる方式が安全です。
試験では、各テストの必須パラメータ、NULL の扱い、where・severity・quote の意味、relationships の参照指定(to と field)などが頻出です。unique が NULL も失敗として検知する点はよく問われます。
選択実行と重大度の使い分け(コマンド例)
# 直近で変更のあったモデル配下のテストのみ
# (実環境のバージョン・アダプタに応じてセレクタは調整)
dbt test -s state:modified+ type:generic
# unique テストだけを実行
dbt test -s test_type:unique
# 一部テストを警告扱いに(YAML 側)
version: 2
models:
- name: fct_orders
tests:
- dbt_utils.expression_is_true:
expression: "total_amount >= 0"
config:
severity: warnAnalytics Engineer
問題 1
fct_orders.status は 'pending' または 'completed' のほかに NULL も許容したい。最も適切な accepted_values の定義はどれか?
正解: A
dbt の accepted_values で NULL を許容するには、values に YAML の null を未クオートで含めます。B は文字列 'null' であり NULL ではありません。C は pending/completed を未クオートにしているため文字列として一致しません。D の allow_nulls は組み込みパラメータではありません。
unique と not_null は両方必要ですか?
dbt の unique は NULL も失敗として検知しますが、原因の切り分けとメッセージの明確化のため、主キー列では not_null と unique を併用するのが実務・試験ともに推奨です。
relationships で複合キー(2列以上)を検証できますか?
組み込み relationships は単一列前提です。複合キーは、サロゲートキーをモデル内で生成して relationships を当てるか、カスタムテストを作成して検証する方法が堅実です。
accepted_values で大文字小文字の違いはどう扱われますか?
比較の挙動はデータベースの照合に依存します。確実性が必要なら、モデル側で lower() などで正規化し、accepted_values でも小文字に統一して検証してください。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
dbt Model の基礎: SQL で定義する変換の最小単位
Analytics Engineer 向けに、dbt Model の定義、マテリアライゼーション、依存関係、インクリメン...
dbt Analytics Engineer 試験ガイド: 出題範囲・配点・申込の実務視点
dbt Analytics Engineer 認定の出題範囲、配点の考え方、申込から受験までの流れを、公式ドキュメントの...
dbt Cloud と dbt Core の違いと選び方:Analytics Engineer 試験に効く要点
dbt Cloud と dbt Core の機能差を、実務と資格対策の両面から整理。スケジューリング、IDE、RBAC、...
dbt プロジェクト構造ガイド: models / seeds / macros の実務レイアウト
Analytics Engineer 向けに、dbt プロジェクトのディレクトリ構造と命名規約、dbt_project....
dbt_project.yml の読み方:主要設定と命名を最短で掴む
dbt_project.yml の必須キー、命名解決(database.schema.identifier)、設定優先度...