dbt-checkpointの導入手順メモ
この記事は、dbt Advent Calendar 2024 シリーズ2 の3日目の記事です。
dbt Advent Calendar 2024
https://qiita.com/advent-calendar/2024/dbt
dbt(Data Build Tool)の自動検証ツールに、
dbt-checkpointというものがあり、試してみたので導入手順メモを残しておきます。
dbt-checkpoint/dbt-checkpoint | GitHub
https://github.com/dbt-checkpoint/dbt-checkpoint
このエントリでは、公式とは異なる手順で導入します(理由は後ほど記載)。
導入手順
dbtのプロジェクトを準備
Gitのリポジトリ用にディレクトリを作ります。
mkdir dbt-checkpoint-study && cd $_
git init
Python仮想環境を用意します。
python -m venv venv
. venv/bin/activate
echo "venv" >> .gitignore
dbtをインストールします(ここでは、とりあえずsqlite向けを入れます)。
pip install dbt-sqlite
pip freeze > requirements.txt
dbtプロジェクトを初期化します。
dbt init sample
echo "logs" >> .gitignore
sample/profiles.ymlを用意します。
sample/profiles.yml
sample:
outputs:
dev:
type: sqlite
threads: 1
database: sample
schema: main
schemas_and_paths:
main: /tmp/dbt-sample.db
schema_directory: /tmp/dbt-sample
target: dev
動作確認します。
bash -c 'cd sample && dbt debug'
プロジェクトにdbt-checkpointを設定
dbt-checkpointを実行するMakefileとpre-commitを導入します。
.pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: dbt_checkpoint
name: dbt_checkpoint
entry: make -C sample check -k
language: system
pass_filenames: false
sample/Makefile ※一部のルールしか記載していないので、必要に応じて要追記
SOURCES := $(shell find . -name "*.yml" -or -name "*.sql")
MANIFEST := target/manifest.json
CATALOG := target/catalog.json
CHECKS := check_model_columns_have_desc check_script_semicolon
setup: # install dbt-checkpoint
@test -d .venv || python -m venv .venv
@.venv/bin/pip freeze | grep pre_commit_hooks | grep dbt-checkpoint --silent || .venv/bin/pip install git+https://github.com/dbt-checkpoint/dbt-checkpoint.git@v2.0.6
$(MANIFEST): $(SOURCES)
@.venv/bin/python -m dbt_checkpoint.dbt_parse
$(CATALOG): $(SOURCES)
@.venv/bin/python -m dbt_checkpoint.dbt_docs_generate
check_model_columns_have_desc: $(MANIFEST) $(CATALOG)
@find models -name "*.sql" | xargs .venv/bin/python -m dbt_checkpoint.check_model_columns_have_desc
check_script_semicolon: $(MANIFEST)
@find models -name "*.sql" | xargs .venv/bin/python -m dbt_checkpoint.check_script_semicolon
check: setup $(CHECKS)
clean: # cleanup
rm -rf .venv
rm -rf target
未インストールの場合、以下を参照してpre-commitをインストールしておきます。
pre-commit
https://pre-commit.com/
リポジトリにpre-commitのhookを登録します。
pre-commit install
コミットすると、dbt_checkpointが実行されることが確認できます。
git add .
git commit -a -m "initial commit"
$ git commit -a -m "initial commit"
bug: pre-commit's script is installed in migration mode
run `pre-commit install -f --hook-type pre-commit` to fix this
Please report this bug at https://github.com/pre-commit/pre-commit/issues
dbt_checkpoint...........................................................Passed
意図的に検証NGになるように修正してみます。 ここでは、カラムのDescritonをコメントアウトします。
sample/models/example/schema.yml
version: 2
models:
- name: my_first_dbt_model
description: "A starter dbt model"
columns:
- name: id
# description: "The primary key for this table"
tests:
- unique
- not_null
- name: my_second_dbt_model
description: "A starter dbt model"
columns:
- name: id
description: "The primary key for this table"
tests:
- unique
- not_null
Commitを試みると、検証でエラーになることが確認できます。
$ git commit -a -m "fix: column description commentout"
bug: pre-commit's script is installed in migration mode
run `pre-commit install -f --hook-type pre-commit` to fix this
Please report this bug at https://github.com/pre-commit/pre-commit/issues
dbt_checkpoint...........................................................Failed
- hook id: dbt_checkpoint
- exit code: 2
make: Entering directory '/home/takemikami/tmp/dbt-checkpoint-study/sample'
Executing cmd: `dbt parse`
03:01:47 Running with dbt=1.5.11
03:01:47 Registered adapter: sqlite=1.5.0
03:01:47 Performance info: /home/takemikami/tmp/dbt-checkpoint-study/sample/target/perf_info.json
Executing cmd: `dbt docs generate`
03:01:50 Running with dbt=1.5.11
03:01:50 Registered adapter: sqlite=1.5.0
03:01:50 Found 2 models, 4 tests, 0 snapshots, 0 analyses, 311 macros, 0 operations, 0 seed files, 0 sources, 0 exposures, 0 metrics, 0 groups
03:01:50
03:01:50 Concurrency: 1 threads (target='dev')
03:01:50
03:01:50 Building catalog
03:01:50 Catalog written to /home/takemikami/tmp/dbt-checkpoint-study/sample/target/catalog.json
models/example/my_first_dbt_model.sql: following columns are missing description:
- id
make: *** [Makefile:14: check_model_columns_have_desc] Error 123
make: Target 'check' not remade because of errors.
make: Leaving directory '/home/takemikami/tmp/dbt-checkpoint-study/sample'
補足
公式とは異なる手順で導入して理由ですが、
検証をすり抜けてcommitできてしまうケースがあるからです。
モデル(sql),スキーマ(yml)
↓
マニフェスト(manifest.json)
↓
dbt-checkponintによる自動検証
という流れで検証を行うルールの場合、
モデル(sql)の変更をhookに自動検証が行われるようです。
つまり、モデル(sql)と別commitでスキーマ(yml)が変更された時は自動検証されません。
pre-commitでは、
ファイル単位で完結する自動検証(flake8とか)はpass_filenames=true
複数ファイルの関連する自動検証(mypyとか)はpass_filenames=false
で動かす必要があるのですが、
dbt-checkpointは両方のパターン混在しているので、
確実に自動検証が動くようにpass_filenames=false側に倒して導入してみました。
以上。