
dbtでテスト失敗時のエラー・警告を切り替えることができるseverity・error_if・warn_ifの3つのconfigを試してみた
さがらです。
dbtでは、テスト失敗時のエラー・警告を切り替えることができるconfigとして、severity・error_if・warn_ifの3つが存在します。
この3つのパラメータをそれぞれdbt Cloudで試してみたので、本記事でその内容をまとめてみます。
事前準備:データの準備
検証用に、以下の内容のcsvをusers.csv
として、seeds
配下に作成します。username
列にて、aliceが4レコード、charlieが2レコードあり、データが重複している状態です。
user_id,username
1,alice
2,bob
3,charlie
4,david
5,eve
6,alice
7,charlie
8,alice
9,alice
10,frank
11,grace
この後、このseedを参照するmodelとyamlファイルを以下のように作成し、dbt build
を一度実行してテスト検証用のテーブルを生成しておきます。
models/stg_users.sql
select * from {{ ref('users') }}
models/stg_users.yml
version: 2
models:
- name: stg_users
columns:
- name: username
description: ユーザー名
前提知識:デフォルトのuniqueテストを実装してテスト
severity・error_if・warn_ifを試す前に、デフォルトのuniqueテストを実装してテストをしてみます。
以下のようにyamlファイルを変更します。
models/stg_users.yml
version: 2
models:
- name: stg_users
columns:
- name: username
description: ユーザー名
tests:
- unique
この状態でdbt test -s stg_users
を実行すると、エラーとなります。username
列にて、aliceが4レコード、charlieが2レコードあり重複が発生しているため、このような結果となります。
severity: warn
としてテスト失敗時にエラーではなく警告を出すようにしてみる
次に、severity: warn
としたときの挙動を確認してみます。デフォルトではseverityを設定せずともseverity: error
となっているためテストに失敗するとエラーとなるのですが、ユーザー側でseverity: warn
とすると指定したテストに失敗したときにエラーではなく警告を出すようになります。
以下のようにyamlファイルを変更します。
models/stg_users.yml
version: 2
models:
- name: stg_users
columns:
- name: username
description: ユーザー名
tests:
- unique:
config:
severity: warn
この状態でdbt test -s stg_users
を実行すると、警告となります。
error_if
とwarn_if
を用いて、テストに失敗したレコードの数に応じてエラーと警告を切り替えてみる
次にerror_if
とwarn_if
を用いて、テストに失敗したレコードの数に応じてエラーと警告を切り替えてみます。
「テストに失敗したレコードの数」の検知方法
「テストに失敗したレコードの数」の検知方法ですが、実際にdbt testで実行されているクエリを見ることで可能です。下図でいう赤枠部分が該当します。
この赤枠部分のクエリを実行してみると、下図のように結果が返ってきます。この場合「テストに失敗したレコードの数」は「2」となります。
注意点として、今回はuniqueのテストで試しましたが、aliceという値は4レコードがあるから「4」となる、ような仕様ではないということです。実際にどのようなクエリがdbt test
で実行されているかを見て、「テストに失敗したレコードの数」をどうカウントしているか確認した上で本機能を使っていきましょう。
error_if
とwarn_if
を用いて警告を出してみる
以下のようにyamlファイルを変更します。テストに失敗したレコードの総数が1個または2個の場合は警告、3個以上の場合はエラーとなります。
models/stg_users.yml
version: 2
models:
- name: stg_users
columns:
- name: username
description: ユーザー名
tests:
- unique:
config:
error_if: '>2'
warn_if: 'between 1 and 2'
この状態でdbt test -s stg_users
を実行すると「テストに失敗したレコードの数」は「2」のため、警告となります。
error_if
とwarn_if
を用いてエラーを出してみる
以下のようにyamlファイルを変更します。テストに失敗したレコードの総数が1個の場合は警告、2個以上の場合はエラーとなります。
models/stg_users.yml
version: 2
models:
- name: stg_users
columns:
- name: username
description: ユーザー名
tests:
- unique:
config:
error_if: '>1'
warn_if: '>0'
この状態でdbt test -s stg_users
を実行すると「テストに失敗したレコードの数」は「2」のため、エラーとなります。
severity: warn
とerror_if
をどちらも定義している場合どうなる?
参考:ここまでの内容を見て、「severity: warn
とerror_if
をどちらも定義している場合どういった挙動となるか?」気になった方もいると思います。
実は公式Docにも以下の言及があり、error_if
の処理はスキップされる仕様となります。
If severity: warn, dbt will skip the error_if condition entirely and jump straight to the warn_if condition. If the warn condition is met, the test warns; if it's not met, the test passes.
注意点として、error_if
をスキップしてしまうため、「テストに失敗したレコードの数」は「2」となる今回の場合、以下の書き方をしているとwarn_if: '=1'
だけで判定されてしまい、テストは成功となってしまいます…。=
を用いた条件設定は避けた方が良いです。
models/stg_users.yml
version: 2
models:
- name: stg_users
columns:
- name: username
description: ユーザー名
tests:
- unique:
config:
severity: warn
error_if: '>1'
warn_if: '=1'
この回避策として、下記のようにwarn_if: '>0'
とすることで条件に合致し、警告を出せるようになります。
models/stg_users.yml
version: 2
models:
- name: stg_users
columns:
- name: username
description: ユーザー名
tests:
- unique:
config:
severity: warn
error_if: '>1'
warn_if: '>0'
最後に
dbtでテスト失敗時のエラー・警告を切り替えることができるseverity・error_if・warn_ifの3つのconfigを試してみました。
使う機会は限定的かもしれませんが、テスト失敗時のエラー・警告を切り替えたい際にはぜひご活用ください!