はじめに
これまでSnowflakeは使っていましたが、dbtは触ったことがありませんでした。
データモデリングやテスト、依存関係管理を体系的に行えるツールとして名前は知っていたものの、触ったことがなかったのでSnowflake公式のチュートリアルを実際にやってみたので、学んだことをメモとしてまとめます。
sourceの考え方(既存テーブルの扱い)
既存テーブルは sources.yml に定義する。
sources:
- name: tb_101
database: MY_DB
schema: RAW
tables:
- name: ORDER_DETAIL
モデルを作成する際は source() 関数で参照する。
SELECT *
FROM {{ source('tb_101', 'ORDER_DETAIL') }}
ポイント
- 物理テーブルを直接書かない
- メタデータを一元管理できる
- テストやドキュメント生成と統合される
profileの考え方
profileは接続定義。
イメージとしては「接続プロファイル」に近い。
outputs:
dev:
type: snowflake
database: DEV_DB
schema: DEV_SCHEMA
prod:
type: snowflake
database: PROD_DB
schema: PROD_SCHEMA
できること
- 環境ごとに出力先DB/SCHEMAを変更可能
- dev / prod を簡単に切り替え可能
compileとは何か?
論理SQLを物理SQLに変換すること。
dbt compileで
Jinjaテンプレート付きSQLを
ターゲットのDB(Snowflake等)で実行可能な物理SQLに変換する。
この段階ではターゲットにSQLは実行されない。
例:
SELECT *
FROM {{ source('tb_101', 'ORDER_DETAIL') }}
↓
SELECT *
FROM MY_DB.RAW.ORDER_DETAIL
生成物は
target/compiled/models/...
配下に作られる
runとは何か?
dbt run
compileを内部で実行。
その後、実際にSQLを投げて、テーブルやビューを作成する。
つまり
run = compile + 実行
compiledフォルダとrunフォルダの違い
dbt runを実行すると target/ 配下の以下二つのサブフォルダに生成物が作られる。(dbt compileをした場合はcompiledフォルダのみ生成)
- target/compiled
- target/run
① target/compiled
Jinja展開後のSQL
例:
SELECT *
FROM MY_DB.RAW.ORDER_DETAIL
特徴:
- モデル本体のSQL
- CREATE TABLEなどはまだ付いていない
- Snowflakeにはまだ実行されていない
② target/run
実際にSnowflakeへ送られる最終SQL
例:
CREATE OR REPLACE TABLE DEV_DB.DEV_SCHEMA.MY_MODEL AS
SELECT *
FROM MY_DB.RAW.ORDER_DETAIL
incrementalモデルの場合は
MERGE INTO ...
などが生成される。
特徴:
- CREATE文が付く
- フックやトランザクション制御が含まれる
- Snowflakeに送信された最終SQL
runとbuildの違い
- dbt run
- モデルのみ実行
- dbt build
- モデル
- テスト
- スナップショット
- シード(ファイル→テーブル生成)
をまとめて実行
テストの仕組み
自動テスト生成
sources.ymlのdata_tests項目にテストしたい内容を指定
tables:
- name: ORDER_DETAIL
data_tests:
- not_null:
column_name: ORDER_ID
これだけでcompile時に自動的にテストが生成される。
手動テスト
/tests 配下にSQLを書く。
重要なルール:
- 1件でもレコードを返したらエラー
- 0件ならパス
例:
SELECT *
FROM {{ ref('my_model') }}
WHERE order_id IS NULL
セマンティックビューも作れる
Snowflakeのセマンティックレイヤーと連携可能。
BI連携や指標管理まで見据えられる構造になっている。
まとめ
dbtは
- データモデリングツール
- テストフレームワーク
- コンパイルエンジン
- メタデータ管理基盤
を統合したデータ開発フレームワーク。
この記事が何かの参考になれば幸いです。