はじめに
データアナリティクス事業本部のおざわです。
オプションを指定せずにdbt run
を実行すると、プロジェクト内の有効なモデルがマテリアライズ(実体化)されます。なにも指定せずにdbt run
した場合に、特定のモデルを除外できないか試してみたところ、Selectorsを使えば目的の動作ができましたので共有したいと思います。
今回使ったdbtのバージョンです。
❯ dbt --version
Core:
- installed: 1.7.7
- latest: 1.7.7 - Up to date!
Plugins:
- redshift: 1.7.3 - Up to date!
Selectorsとは
今回使うSelectorsは、一言でいうとリソースの選択方法に名前を付けておく機能です。
使い方としては、selectors.ymlにリソースの選択方法を定義しておきます。あとはコマンドを実行する時に--selector
フラグにselector名を渡すだけです。
今回やってみたようにdefault: true
にすることで、なにもオプションを指定せずにdbt run
やdbt test
を実行したときに処理する対象のリソースを変更できます。
プロジェクト構成
参考まで、プロジェクト構成になります。Selectorsはプロジェクト直下のselectors.yml
に定義します。
今回、除外対象としたモデルはexclude_me_model
です。モデルの中身はとくに重要ではないので割愛します。
my_project
├── ...
├── models
│ ├── marts
│ │ ├── customers.sql
│ │ ├── exclude_me_model.sql
│ │ └── schema.yml
│ ├── staging
│ │ ├── staging.yml
│ │ ├── stg_customers.sql
│ │ └── stg_orders.sql
│ └── source.yml
├── dbt_project.yml
├── selectors.yml
└── tests
└── ...
設定なしでdbt runとdbt test
selectors.ymlにはなにも書いていない状態でdbt run
してみると、全てのモデルが実行されています。
07:13:04 Running with dbt=1.7.7
07:13:04 Registered adapter: redshift=1.7.3
07:13:04 Found 1 seed, 4 models, 3 tests, 3 sources, 0 exposures, 0 metrics, 455 macros, 0 groups, 0 semantic models
07:13:04
07:13:05 Concurrency: 1 threads (target='dev')
07:13:05
07:13:05 1 of 4 START sql view model public.stg_customers ............................... [RUN]
07:13:07 1 of 4 OK created sql view model public.stg_customers .......................... [SUCCESS in 1.97s]
07:13:07 2 of 4 START sql view model public.stg_orders .................................. [RUN]
07:13:09 2 of 4 OK created sql view model public.stg_orders ............................. [SUCCESS in 1.71s]
07:13:09 3 of 4 START sql view model public.exclude_me_model ............................ [RUN]
07:13:10 3 of 4 OK created sql view model public.exclude_me_model ....................... [SUCCESS in 0.83s]
07:13:10 4 of 4 START sql view model public.customers ................................... [RUN]
07:13:11 4 of 4 OK created sql view model public.customers .............................. [SUCCESS in 1.14s]
07:13:11
07:13:11 Finished running 4 view models in 0 hours 0 minutes and 6.95 seconds (6.95s).
07:13:11
07:13:11 Completed successfully
07:13:11
07:13:11 Done. PASS=4 WARN=0 ERROR=0 SKIP=0 TOTAL=4
dbt test
も実行してみます。除外対象のモデルを含めて3つのテストを入れています。
❯ dbt test
07:13:38 Running with dbt=1.7.7
07:13:39 Registered adapter: redshift=1.7.3
07:13:39 Found 1 seed, 4 models, 3 tests, 3 sources, 0 exposures, 0 metrics, 455 macros, 0 groups, 0 semantic models
07:13:39
07:13:40 Concurrency: 1 threads (target='dev')
07:13:40
07:13:40 1 of 3 START test not_null_customers_customer_id ............................... [RUN]
07:13:40 1 of 3 PASS not_null_customers_customer_id ..................................... [PASS in 0.40s]
07:13:40 2 of 3 START test not_null_exclude_me_model_customer_id ........................ [RUN]
07:13:41 2 of 3 PASS not_null_exclude_me_model_customer_id .............................. [PASS in 0.46s]
07:13:41 3 of 3 START test unique_customers_customer_id ................................. [RUN]
07:13:41 3 of 3 PASS unique_customers_customer_id ....................................... [PASS in 0.32s]
07:13:41
07:13:41 Finished running 3 tests in 0 hours 0 minutes and 2.63 seconds (2.63s).
07:13:41
07:13:41 Completed successfully
07:13:41
07:13:41 Done. PASS=3 WARN=0 ERROR=0 SKIP=0 TOTAL=3
Selectorsで特定のモデルを除外してみる
今回はモデルにタグを設定して、そのタグが設定されたモデルを除外します。 タグについてはこちらのブログで紹介されていますのでご参照ください。
selectors.ymlでは以下のように設定しました。
unionで2つの条件を組み合わせています。fqnにワイルドカードを指定して全てのモデルを対象にし、excludeを使ってexclude_me
でタグ付けされたモデルを除外しています。
defaultは基本的に1つのselectorでtrue
にできますが、環境に応じて切り替える方法もドキュメントで紹介されています。
selectors.yml
selectors:
- name: my_default_selector
description: exclude tagged models by default
default: true
definition:
union:
- method: fqn
value: "*"
- exclude:
- method: tag
value: "exclude_me"
モデルには以下のようにexclude_me
タグを付けています。
schema.yml
version: 2
models:
- name: exclude_me_model
config:
tags: "exclude_me"
description: My lovely model
columns:
- name: customer_id
tests:
- not_null
dbt run と dbt testを実行
以上、設定してからdbt run
してみます。
Using default selector my_default_selector
と出力され、除外対象のモデルは実行されません。
❯ dbt run
07:58:26 Running with dbt=1.7.7
07:58:26 Registered adapter: redshift=1.7.3
07:58:26 Found 1 seed, 4 models, 3 tests, 3 sources, 0 exposures, 0 metrics, 455 macros, 0 groups, 0 semantic models
07:58:26 Using default selector my_default_selector
07:58:26
07:58:27 Concurrency: 1 threads (target='dev')
07:58:27
07:58:27 1 of 3 START sql view model public.stg_customers ............................... [RUN]
07:58:29 1 of 3 OK created sql view model public.stg_customers .......................... [SUCCESS in 1.93s]
07:58:29 2 of 3 START sql view model public.stg_orders .................................. [RUN]
07:58:31 2 of 3 OK created sql view model public.stg_orders ............................. [SUCCESS in 2.07s]
07:58:31 3 of 3 START sql view model public.customers ................................... [RUN]
07:58:32 3 of 3 OK created sql view model public.customers .............................. [SUCCESS in 1.18s]
07:58:33
07:58:33 Finished running 3 view models in 0 hours 0 minutes and 6.62 seconds (6.62s).
07:58:33
07:58:33 Completed successfully
07:58:33
07:58:33 Done. PASS=3 WARN=0 ERROR=0 SKIP=0 TOTAL=3
dbt test
もやってみます。こちらもUsing default selector my_default_selector
と出力され、除外対象のモデルではテストが実行されませんでした。
❯ dbt test
08:00:33 Running with dbt=1.7.7
08:00:33 Registered adapter: redshift=1.7.3
08:00:33 Found 1 seed, 4 models, 3 tests, 3 sources, 0 exposures, 0 metrics, 455 macros, 0 groups, 0 semantic models
08:00:33 Using default selector my_default_selector
08:00:33
08:00:34 Concurrency: 1 threads (target='dev')
08:00:34
08:00:34 1 of 2 START test not_null_customers_customer_id ............................... [RUN]
08:00:34 1 of 2 PASS not_null_customers_customer_id ..................................... [PASS in 0.33s]
08:00:34 2 of 2 START test unique_customers_customer_id ................................. [RUN]
08:00:35 2 of 2 PASS unique_customers_customer_id ....................................... [PASS in 0.34s]
08:00:35
08:00:35 Finished running 2 tests in 0 hours 0 minutes and 1.84 seconds (1.84s).
08:00:35
08:00:35 Completed successfully
08:00:35
08:00:35 Done. PASS=2 WARN=0 ERROR=0 SKIP=0 TOTAL=2
おわりに
以上、Selectorsを使って特定のモデルを除外してみました。除外対象を含めたすべてのモデルを実行したい場合は、all
のようなSelectorを作っておくのが良いと思います。
selectors.yml
selectors:
# 省略
- name: all
description: all models
definition:
union:
- method: fqn
value: "*"
また、除外対象だけを実行したい場合は、普通に--select
でタグ指定すれば実行できます。
❯ dbt run --select "tag:exclude_me"
01:02:22 Running with dbt=1.7.7
01:02:22 Registered adapter: redshift=1.7.3
... 省略 ...
01:02:26 Finished running 1 view model in 0 hours 0 minutes and 3.58 seconds (3.58s).
01:02:26
01:02:26 Completed successfully