Table of Contents
dbtプロジェクトの設定について
dbtで処理を進めていくためには、dbtプロジェクトを作成・設定していきます。
下記のような形でdbtのディレクトリに「dbt_project.yml」を用意します。
dbt_training
├── dbt_project.yml
dbt_project.ymlの中身は、下記のようなフォーマットになっています。
name: 'dbt_training'
config-version: 2
version: '1.0.0'
profile: 'dbt_training_dw'
model-paths: ["models"]
analysis-paths: ["analysis"]
test-paths: ["tests"]
seed-paths: ["seeds"]
macro-paths: ["macros"]
snapshot-paths: ["snapshots"]
target-path: "target"
clean-targets: [target, dbt_packages]
models:
dbt_training:
materialized_dwh:
+materialized: table
hoge_project:
+database: fuga_database
dbtプロジェクトの定義ファイルで指定するタグについて
上記のymlファイルに定義するタグの役割はそれぞれ下記の通り。
基本情報
- name:
'dbt_training'
プロジェクト名。dbt run
などでこのプロジェクトを識別するために使われます。 - config-version:
2
dbt_project.yml
の構造バージョン。現在は2
が最新で推奨です。 - version:
'1.0.0'
プロジェクトのバージョン番号。パッケージとして利用する際に意味を持ちます。 - profile:
'dbt_training_dw'
profiles.yml
内の接続設定の名前。この名前でデータベース接続情報を読み込みます。
ディレクトリ構成関連
- model-paths:
["models"]
モデル(SQLやJinjaテンプレート)を格納するディレクトリ。ここに指定したディレクトリをdbtはモデルとしてスキャンしに行きます。 - analysis-paths:
["analysis"]
分析用のSQLファイルを置くディレクトリ(実行対象外)。 - test-paths:
["tests"]
テスト定義ファイルを置くディレクトリ。 - seed-paths:
["seeds"]
CSVなどのシードデータを置くディレクトリ。 - macro-paths:
["macros"]
再利用可能なJinjaマクロを置くディレクトリ。 - snapshot-paths:
["snapshots"]
スナップショット定義(履歴管理用)を置くディレクトリ。
結果的に、下記のようなディレクトリ構成を作成して開発を進めていきます。
モデルの作成について
実際にdbtのモデル作成について見ていきましょう。
dbt における「モデル」は、データ変換の単位となる SQL ファイルのことです。ざっくり言うと、次のような特徴があります。
SQL の SELECT 文ひとつ=ひとつのモデル
models/
フォルダ配下に置かれた .sql
ファイルで、基本的には「あるテーブルからこう変換して新しいテーブル(あるいはビュー)を作る」という SELECT 文を書きます。
依存関係は ref()
で明示
他のモデルを参照する場合は select … from {{ ref('other_model') }}
のように書くと、dbt が依存関係を自動で解析し、正しい順序で実行してくれます。
実際にモデルを作成してみましょう。modelsディレクトリの配下に下記のsql分を用意します。
models/employee_names.sql
select
"employee_id",
concat("first_name", ' ', "last_name") as full_name
from
"dbt_training"."raw"."employees"
下記のコマンドを実行して、dbtを動かしてみましょう。
dbt_training$ dbt run
dbtではモデルをデフォルトではビューとして構築していきます。dbtにおいて「モデルをどのような形式でDW上で構築するのか」をマテリアライゼーションと呼ぶ。
主なマテリアライゼーションの種類
マテリアライゼーションの種類はいくつかありますが、下記に見ていきます。
1. table
説明
モデルの結果を 物理テーブル として出力します。ビルド時に毎回 DROP → CREATE で上書きされるため、最新の全件データが常に保持されます。
メリット
- クエリ実行時のパフォーマンスが高い
- 他システムからの参照が容易
メリット
ビルドの時間がかかる
設定例
models:
my_project:
marts:
+materialized: table
2. view
説明
モデルを ビュー(仮想テーブル)として出力します。実体を持たず、参照時に毎回クエリが実行されます。
メリット
- 最新データを常に反映
- ストレージ不要
- ビルドが高速
デメリット
- 複雑なネストが多いと参照時のクエリが重くなる
設定例
models:
my_project:
staging:
+materialized: view
3.incremental
説明
モデルのうち 差分更新 が可能なものを、初回は全件テーブル、以降は指定条件(例えば日付の大きいレコードだけ)で INSERT/UPDATE する形式です。
メリット
- 応答性能向上:全件再ビルドを避け、更新部分のみ処理
- 大量データのパイプラインに最適
デメリット
- 差分ロジック(
unique_key
やis_incremental()
)の実装が必要 - データ不整合の監視が必要
設定例
{{ config(
materialized = 'incremental',
unique_key = 'id'
) }}
with source as (
select * from {{ ref('events') }}
{% if is_incremental() %}
where event_date > (select max(event_date) from {{ this }})
{% endif %}
)
select * from source