dbt

dbt not_null テストで必須列を守る: 実務とAnalytics Engineer対策

2026-04-19
NicheeLab編集部

not_null は、列に NULL が1件も存在しないことを保証する dbt 標準の汎用テスト。

ソース段階とモデル段階の両方で適用し、早期に欠損を検知するのが実務的にも試験的にも重要。

not_null の基本と試験で問われやすいポイント

not_null は、対象列に NULL が1件も無いことを検証する汎用テスト。dbt はテストを「失敗行を返すSELECT」として実行し、0行なら成功、1行以上なら失敗となる。公式ドキュメントの安定仕様で、モデル・ソース・シードに適用できる。

Analytics Engineer 試験では、どの段階で not_null を置くべきか(ソースとステージング/中間・ファクトの両方)、テスト設定(severity, store_failures, where)の理解、そして関連テスト(unique, relationships, accepted_values)との使い分けが狙われやすい。

  • 成功条件: 失敗行 = 0
  • 適用対象: models, sources, seeds
  • よくある併用: unique(主キー), relationships(外部キー的整合性)
  • 運用: 重要列は severity=error、観測列は warn で段階的に導入

データ品質チェーンにおける not_null の位置付け

Sourcesnot_null on raw colsStagingnot_null on cleaned keysCore/Fact Modelsnot_null on business keysBI/Export(消費)CI: dbt test(失敗=デプロイブロック)

YAMLでの実装パターン(models・sources・seeds)

最小構成は、列の tests セクションに not_null を列挙するだけ。重要度の高い列は severity=error、監視開始段階では warn を使い、CIの段階的導入を行う。where で論理削除行などを除外できる。store_failures を有効にすると失敗行が監査用テーブルとして保存され、原因調査が容易になる(保存先のスキーマ名や命名はアダプタに依存)。

ソース段階でも not_null を定義して、上流の欠損混入を早期発見する。ステージング以降では、主キー・外部キー・業務キー列を not_null で締めるのが基本。

  • models: ビジネスキー/主キー/外部キー列を対象に
  • sources: 上流品質の監視。値が必ず存在すべき列を指定
  • seeds: 参照マスタ等の必須列に適用
  • where: is_deleted=false 等の条件で除外が可能
  • store_failures: 失敗行の永続化で原因追跡を短縮

YAML例(models と sources での not_null 適用)

version: 2

models:
  - name: fct_orders
    description: Final fact table for orders
    columns:
      - name: order_id
        description: Primary key
        tests:
          - unique
          - not_null:  # クリティカル列はエラー
              severity: error
              store_failures: true
      - name: customer_id
        description: Foreign key to dim_customers
        tests:
          - not_null:
              severity: error
              where: "is_deleted = false"  # 論理削除行を除外する例
          - relationships:
              to: ref('dim_customers')
              field: customer_id

sources:
  - name: app
    schema: raw_app
    tables:
      - name: orders_raw
        columns:
          - name: order_id
            tests:
              - not_null  # 上流欠損の早期検知
          - name: created_at
            tests:
              - not_null: { severity: warn }  # 監視しつつ段階導入

実行とチューニング(severity・store_failures・選択実行)

dbt test は、対象ノードを選択して実行できる。モデル名指定で、そのモデルに紐づくテストだけを走らせる運用が最も安定。CIではクリティカル列は severity=error でブロック、観測段階は warn でログに残す方針が扱いやすい。

store_failures は、失敗行を調査用に保管する。長期で溜め込みたくない場合は、定期削除ポリシーや専用スキーマを活用する。

  • 基本実行: dbt test -s fct_orders
  • 特定タグ: 重要テストに tag を付け、dbt test -s tag:critical で実行
  • 全汎用テスト: dbt test -s test_type:generic(アダプタ/バージョンによりセレクタは変わるため公式ドキュメントを参照)
  • CI: 失敗=デプロイブロック(severity=error)。warn はログのみ

よくある落とし穴と回避策

空文字とNULLは別物: 多くのDWH(Snowflake, BigQuery, Redshift 等)では '' と NULL は異なる。not_null は空文字を検知しないため、上流で空文字が来る可能性がある場合はステージングで NULLIF(TRIM(col), '') を使って正規化してから not_null を適用する。

JOINでの欠損発生: LEFT JOIN は右側に不一致があると NULL を生む。not_null を守るべき列が JOIN 後に NULL になる場合、JOIN戦略の見直し(INNER JOIN化、事前フィルタ、COALESCEの適用)が必要。

型変換・派生列: CAST 失敗や条件分岐により意図せず NULL を生むことがある。派生直後に COALESCE でデフォルト値を与えるか、期待値の範囲を accepted_values と併用して品質を補強する。

  • 空文字対策: NULLIF(TRIM(col), '') で正規化してから not_null
  • JOIN対策: INNER JOIN化、事前整合、COALESCE
  • 派生列対策: COALESCE/デフォルト付与 + 補助テスト
  • 大規模対策: where で範囲を絞る(運用ポリシーと併用)

必須列を守る設計とガバナンス

ソース段階での not_null は早期検知、ステージング・コア段階の not_null は契約保証の役割を担う。特に主キー・外部キー・ビジネスキーは、not_null と unique/relationships を組み合わせて恒常監視する。

CI/CD では、クリティカル列の not_null 失敗をデプロイブロックの条件にする。失敗行は store_failures によって監査スキーマへ保存し、失敗検出から復旧までのSLAをドキュメント化する。

  • 層ごとに必須列を定義し、テストを重ねがけ
  • クリティカル列は severity=error でブロック
  • 失敗行の保存とアラートでMTTR短縮
  • ドキュメント化: どの列が必須か、なぜ必須かを明示

not_null と関連テストの使い分け(比較表)

not_null は「存在」を保証するが、完全性は他テストとの組み合わせで担保する。代表的なテストとの比較を押さえておくと、試験の選択問題にも強くなる。

  • 主キー: not_null + unique
  • 外部キー的整合: not_null + relationships
  • コード値: not_null + accepted_values
テスト目的代表的な失敗例運用のコツ
not_nullNULLの排除(存在保証)JOIN不一致でNULL化、空文字をNULL化していないステージングでNULL正規化→not_null適用
unique重複の排除(一意性)同じIDが複数行not_nullと併用して主キー保証
relationships参照整合性(外部キー)親テーブルに存在しないID親子両方でnot_nullを付与し、孤児検出
accepted_valuesコード体系の遵守予定外のカテゴリ値NULLを別扱いにしたい場合は併用順序に注意

問題で確認

Analytics Engineer

問題 1

次の要件を同時に満たす最も適切な設定はどれか。要件: 1) fct_orders.order_id は必須であるためCIで失敗したらデプロイを止めたい、2) is_deleted=true の行は検証対象から除外したい、3) 失敗行は調査のため保存したい。

  1. order_id に not_null を定義し、severity=error、where="is_deleted = false"、store_failures=true を設定する
  2. order_id に not_null を定義し、severity=warn、where="is_deleted = true"、store_failures=false を設定する
  3. order_id に unique のみを定義し、CIでは tests をスキップする
  4. order_id に accepted_values を定義し、許容値に NULL を含めない

正解: A

CIでブロックするには severity=error、除外条件は is_deleted=false、失敗行の保存は store_failures=true。not_null が要件に最も合致する。

よくある質問

not_null は空文字 '' を検知しますか?

多くのDWHで '' は NULL ではありません。not_null は NULL のみを検知します。空文字対策はステージングで NULLIF(TRIM(col), '') による正規化を併用してください。

大規模テーブルで not_null の実行時間が長いです。短縮できますか?

where で対象範囲を絞る、パーティション列に条件を付ける、重要列のみを先に実行する(タグで選択)などが実務的です。全件検証はバッチで定期実施すると安全です。

ソースとモデルのどちらで not_null を定義すべきですか?

両方です。ソースで上流欠損を早期検知し、モデル側では主キー・外部キー・ビジネスキーなど契約上必須の列を再度検証して品質を二重化します。

この記事で学んだ内容を問題で確認しましょう

16,000問以上の問題で実力チェック

無料で問題を解いてみる
この記事の著者

NicheeLab編集部

データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。


関連記事
dbt

dbt Model の基礎: SQL で定義する変換の最小単位

Analytics Engineer 向けに、dbt Model の定義、マテリアライゼーション、依存関係、インクリメン...

dbt

dbt Analytics Engineer 試験ガイド: 出題範囲・配点・申込の実務視点

dbt Analytics Engineer 認定の出題範囲、配点の考え方、申込から受験までの流れを、公式ドキュメントの...

dbt

dbt Cloud と dbt Core の違いと選び方:Analytics Engineer 試験に効く要点

dbt Cloud と dbt Core の機能差を、実務と資格対策の両面から整理。スケジューリング、IDE、RBAC、...

dbt

dbt プロジェクト構造ガイド: models / seeds / macros の実務レイアウト

Analytics Engineer 向けに、dbt プロジェクトのディレクトリ構造と命名規約、dbt_project....

dbt

dbt_project.yml の読み方:主要設定と命名を最短で掴む

dbt_project.yml の必須キー、命名解決(database.schema.identifier)、設定優先度...

dbtの記事一覧 (100件)
© 2026 NicheeLab All rights reserved.