ETLのTransformを担う「dbt」のプロジェクトの設定とモデル作成について見ていきましょう

dbt

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_keyis_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

最新情報をチェックしよう!