🚲

小規模データサイエンスチーム向け:SSOT実現へのステップ1 ─ dbt Core × SQLite実践編(サンプルデータ付き)

に公開

ステップ1:dbt Core × SQLite実践編(サンプルデータ付き)

🎯 目的

この章では、Macローカルでdbt Coreを動かして、SSOTの最初の感覚を掴むことを目的にします。
クラウド(Redshiftなど)を使わずに、SQLiteという軽量データベースを利用して、
dbtのモデル構成と「Data as Code」の概念を体験します。

使用するデータは、シカゴ市のシェアサイクル「Divvy」のオープンデータです。

出典: City of Chicago – Divvy Bicycle Sharing Data


💡 dbtとは? ─ SSOTとセマンティックレイヤーの核になるツール

dbt(data build tool) は、データ変換(Transform)をコードとして管理するためのツールです。
従来のETLプロセスの「T(Transform)」に特化し、SQLで定義したモデルをデータベース上に自動生成します。

単なる変換ツールにとどまらず、dbtはSSOT(Single Source of Truth)を技術的に実現する中心的な存在です。


🧱 基本コンセプト

dbtの設計思想を一言で言えば、

「データ分析の世界にソフトウェア開発の概念を持ち込む」

です。
これを支えるのが次の3本柱です。

  1. Data as Code(データをコードで管理)
    SQLモデルをGitで管理することで、レビュー・再現・履歴追跡が可能になります。

  2. Dependency Management(依存関係の自動解決)
    モデル間の関係を ref() で明示。実行順序やリネージ(血統)を自動で可視化できます。

  3. Testing & Documentation(品質と透明性の担保)
    カラム単位のテストや説明文を記述し、dbt docs で自動的にドキュメント化できます。


🏗️ dbtの役割:生データから“信頼できる真実”へ

dbtの典型的なデータフローは次のように整理されます。

Raw data (Divvy CSV)

stg_trips.sql        ← 整形・クレンジング

int_trips.sql        ← 中間モデル(結合・加工)

mart_rides_by_station.sql  ← 分析用モデル

BI / Dashboard

この流れの中で、dbtは
「各ステップの変換ロジックをすべて明示化」 し、
誰が・どのロジックで・どのデータを扱っているかを追跡可能にします。

これこそがSSOT(Single Source of Truth)=「唯一の信頼できるデータの出所」を成立させる要件です。


🔍 セマンティックレイヤーとの関係

近年、BIツールやAIアプリケーションで「セマンティックレイヤー」という概念が注目されています。
これは、“ビジネス的な意味を持つデータの辞書” です。

役割 担当技術
セマンティックレイヤー 売上、利用回数、アクティブユーザー、会員区分など dbt(モデル・schema.yml)
物理データ層 Redshift, BigQuery, Snowflake, SQLiteなど データベース
可視化レイヤー Tableau, Looker, Metabaseなど BIツール

dbtでは、schema.yml にカラム名・意味・テスト条件を定義することで、
データ変換+意味づけ(セマンティクス)の両方をコード化できます。

これにより:

  • 「BIツールごとに指標定義がずれる」
  • 「誰がどのSQLを使っているか不明」
    といった課題を根本から解消します。

つまりdbtは、SSOTを支える“技術的な骨格”であり、セマンティックレイヤーを形成する実装基盤でもあるのです。


☁️ CoreとCloudの違い

種類 概要 主な用途 金額の目安(1US$=150円換算)
dbt Core 無料のオープンソース版。CLI(コマンドライン)で動作。 ローカル実験・教育・小規模運用 無料
dbt Cloud GUI・スケジューラ・権限管理などを備えた商用版。 チーム開発・本番運用・自動化 Starter/Teamプラン:$100/アカウント/月(約15,000円)〜
・モデルビルド数の超過分:$0.01/成功モデルビルド(約1.5円)
・「Enterprise」プランはカスタム価格(要問い合わせ)

💬 補足説明

  • $100/アカウント/月 は、例えば5アカウントのチームだと月額およそ $500(約7万5,000円) になります。
  • 各プランには「月15,000モデルビルド」までが含まれ、それを超えると超過分 × $0.01(約1.5円) の追加課金が発生します。
  • 大規模チームや高度な権限管理・SAML対応が必要な場合は「Enterpriseプラン」(個別見積もり)となります。
  • 為替レートや契約内容によって金額は変動します。

💡 所感:
dbt Cloudはチームでの運用を考えると非常に便利ですが、
アカウント数×月額+モデル数課金 という料金体系のため、
「思ったより高い」と感じるケースもあります。
一方で、dbt Coreは完全無料でCI/CDやスケジューラを自前で整える必要がありますが、
小規模チームでのSSOT実現には十分な選択肢です。

この記事では、最も軽量なdbt Core × SQLite構成で、SSOTの“第一歩”を体験します。


💬 まとめ:

dbtは「データ変換ツール」ではなく、「データチームの共通言語」そのもの。

SSOT=全員が同じ真実を見られる状態

その実現において、dbtはセマンティックレイヤーを内包する“唯一の実行可能な真実” をつくるツールなのです。


🧰 環境準備

1. Pythonを確認

dbtはPython上で動作します。
Macではすでにインストールされている場合が多いですが、以下で確認します。

python3 --version

結果例:

Python 3.10.14

もし入っていない場合は、Homebrew
を使ってインストールします。

brew install python

2. dbt-coreとSQLiteアダプタをインストール

SQLiteはローカルDBです。
これをdbtで操作するために、対応アダプタを一緒に入れます。

pip install dbt-core dbt-sqlite

確認:

dbt --version

出力例:

Core:
  - installed: 1.10.13
  - latest:    1.10.13 - Up to date!

Plugins:
  - sqlite: 1.10.0 - Up to date!

🪜 dbtプロジェクトを作ってみよう

1. 作業フォルダを作成

mkdir ~/dbt_divvy
cd ~/dbt_divvy

2. dbt init コマンドを実行

dbt init my_first_project

質問が出てきますが、すべてEnterでOKです。

Which database would you like to use?
[1] sqlite

アダプタはsqliteを選びます。

3. フォルダ構成の確認

my_first_project/
├ dbt_project.yml
├ models/
│   └ example/
│       ├ my_first_dbt_model.sql
│       ├ my_second_dbt_model.sql
│       └ schema.yml
└ README.md

これがdbtの基本構成です。

  • models/:SQLモデル(変換定義)

  • schema.yml:カラム定義やテスト

  • dbt_project.yml:設定ファイル


🚲 米国シェアサイクルのオープンデータを取得

今回は練習として、アメリカ・シカゴ市のシェアサイクル「Divvy」 のオープンデータを使います。
Divvyは、シカゴ市が運営する公共シェアサイクルサービスで、利用履歴データ(年月ごと)を誰でもダウンロード可能にしています。
学習・分析・可視化の題材として非常に人気があり、dbtのようなデータモデリングの練習にも最適です。

出典: City of Chicago – Divvy Bicycle Sharing Data

シンプルにするために、ここでは1か月分だけを使います(例:2025年7月分)。
data というフォルダを作成し、その中にDivvyのデータをダウンロードします。

wget https://divvy-tripdata.s3.amazonaws.com/202507-divvy-tripdata.zip
unzip 202507-divvy-tripdata.zip

もし wget が入っていない場合は、以下でインストールします。

brew install wget

解凍後、CSVファイル名を確認します。

202507-divvy-tripdata.csv

📥 SQLiteにインポート

dbt は dbt_project.yml を中心に動くので、
その同じディレクトリ(プロジェクトルート)でSQLiteを扱うことにします。

my_first_project/
├── dbt_project.yml      ← dbtがこのファイルを起点に動く
├── models/
├── data/                ← CSVがここにある
└── divvy.db             ← ここにSQLite DBを作る(推奨)

SQLiteを使って、CSVをローカルDBに取り込みます。

sqlite3 divvy.db

SQLiteコンソールが開いたら、次を実行:

.mode csv
.import data/202507-divvy-tripdata.csv trips

確認:

SELECT COUNT(*) FROM trips;

結果例:

763432

→ 約76万件のレコードが入れば成功です!

この divvy.db を dbt のプロファイルで参照します。

ちなみに、SQLiteコンソールを終了するには、以下のいずれかの方法を使います。

.quit
.exit

注意: ピリオド(.)を忘れずに入力してください。ピリオドがないと、SQL文として認識されてしまい、終了できません。


🧩 dbtでモデルを作る

1. プロファイル設定(SQLite接続)

~/.dbt/profiles.yml を作成します。

ちなみに~/.dbt/profiles.yml は ホームディレクトリ(~) に置く設定ファイルです。
つまり、どこのフォルダで作ってもOK。
(dbtが自動的に ~/.dbt/ を探しにいくからです)

mkdir -p ~/.dbt
vi ~/.dbt/profiles.yml

すでに記載している内容は消していいので、
以下を入力して Enter:

:%d

:%d は「全行削除(delete all)」のコマンドです。

中身が全部消えたら、
i を押して挿入モード(INSERT) に切り替えます。

以下を記述します。

my_first_project:   # ← dbt_project.yml の name と一致させる
  target: dev
  outputs:
    dev:
      type: sqlite
      threads: 1
      database: "database"   # 任意文字列だが必須
      schema: "main"
      schemas_and_paths:
        main: "~/WorkStation/dbt_ssot/my_first_project/divvy.db"
      schema_directory: "~/WorkStation/dbt_ssot/my_first_project"

以下を入力して保存してviを終了します。

:wq

:wq = 「書き込み+終了」

保存できたか確認するには:

cat ~/.dbt/profiles.yml
と打てば、中身が正しく反映されているのが見えるはずです。

✅ 接続確認(dbt debug

ここまでできたら、一度接続テストをしてみましょう。
dbt は ~/.dbt/profiles.ymldbt_project.yml の両方が正しく設定されていないと動きません。
次のコマンドでチェックします。

dbt debug

出力例:

Running with dbt=1.10.13
Using profiles.yml file at /Users/keijiyamada/.dbt/profiles.yml
Using dbt_project.yml file at /Users/keijiyamada/WorkStation/dbt_ssot/my_first_project/dbt_project.yml
adapter type: sqlite
adapter version: 1.10.0
Connection test: [OK connection ok]
All checks passed!

もしエラーが出た場合は、profiles.yml のインデントやパス(~/ が展開されているか)を確認してください。
特に SQLite 用アダプタでは、databaseschemas_and_paths の両方が必要です。

💡 Tip:
dbt debug は、環境構築の「健康診断コマンド」です。
All checks passed! が出れば、dbtがあなたのSQLiteに正しく接続できています。

2. モデルを作成

models/ フォルダ内に stg_trips.sql を作成します。

-- models/stg_trips.sql
select
  ride_id,
  rideable_type,
  started_at,
  ended_at,
  start_station_name,
  end_station_name,
  member_casual
from trips
where started_at is not null

3. 実行!

👉 「dbt_project.yml があるディレクトリ」= プロジェクトのルート、ここでは my_first_project に移動してから
以下を実行します。

dbt run

出力例:

$ dbt run
13:09:57  Running with dbt=1.10.13
13:09:57  Registered adapter: sqlite=1.10.0
13:09:57  Unable to do partial parsing because saved manifest not found. Starting full parse.
13:10:00  Found 3 models, 4 data tests, 416 macros
13:10:00  
13:10:00  Concurrency: 1 threads (target='dev')
13:10:00  
13:10:00  1 of 3 START sql table model main.my_first_dbt_model ........................... [RUN]
13:10:00  1 of 3 OK created sql table model main.my_first_dbt_model ...................... [OK in 0.07s]
13:10:00  2 of 3 START sql view model main.stg_trips ..................................... [RUN]
13:10:00  2 of 3 OK created sql view model main.stg_trips ................................ [OK in 0.04s]
13:10:00  3 of 3 START sql view model main.my_second_dbt_model ........................... [RUN]
13:10:00  3 of 3 OK created sql view model main.my_second_dbt_model ...................... [OK in 0.03s]
13:10:00  
13:10:00  Finished running 1 table model, 2 view models in 0 hours 0 minutes and 0.36 seconds (0.36s).
13:10:00  
13:10:00  Completed successfully
13:10:00  
13:10:00  Done. PASS=3 WARN=0 ERROR=0 SKIP=0 NO-OP=0 TOTAL=3

✅ SQLiteの中に stg_trips テーブルが作成されました!

📝 補足:初期サンプルモデルについて

dbt init コマンドでプロジェクトを作成すると、models/example/ フォルダの中に
my_first_dbt_model.sqlmy_second_dbt_model.sqlschema.yml の3ファイルが自動で生成されます。

これらは dbtが正しく動くかを確認するためのサンプルモデル で、本番の分析には不要です。
残しておいても動作には問題ありませんが、初心者の方は混乱しやすいので削除しておくのがおすすめです。

rm -rf models/example

削除後は、models/ フォルダの中に自分で作成したモデル(たとえば stg_trips.sql)だけが残ります。
これで dbt run を実行すると、自分のモデルだけがビルド対象になります。

dbt run

出力例:

1 of 1 OK created view model main.stg_trips

これで、SQLite上に stg_trips モデルが正しく作成されていればOKです 🎉


📖 dbt Docs を表示してみよう

モデルが作成できたら、dbt の強力な機能「ドキュメント生成」を試してみましょう。
これはプロジェクト全体の構造を自動で可視化するツールです。

dbt docs generate
dbt docs serve

出力例:

$ dbt docs generate
13:19:01  Running with dbt=1.10.13
13:19:01  Registered adapter: sqlite=1.10.0
13:19:01  Found 3 models, 4 data tests, 416 macros
13:19:01
13:19:01  Concurrency: 1 threads (target='dev')
13:19:01
13:19:02  Building catalog
13:19:02  Catalog written to ~/WorkStation/dbt_ssot/my_first_project/target/catalog.json

$ dbt docs serve
13:19:12  Running with dbt=1.10.13
Serving docs at 8080
To access from your browser, navigate to: http://localhost:8080

Press Ctrl+C to exit.

実行後、ブラウザで
http://localhost:8080
にアクセスします。

⚠️ 注意
open target/index.html で直接開くと、manifest.json が読み込めずエラーになります。
必ず上記のように dbt docs serve でHTTPサーバを立ててください。


✅ 成功例

「Welcome!」と書かれた画面が表示されていれば成功です 🎉
左側のサイドバーには models フォルダの中身が一覧で表示されます。


💡 補足説明

  • Project タブ
    → dbtプロジェクトのフォルダ構造(models/ 内など)をツリー表示します。

  • Database タブ
    → SQLite 内のテーブル・ビュー構成をデータベース視点で表示します。

  • Graph Exploration
    → 右下の青いグラフアイコンをクリックすると、
    モデル間の依存関係(リネージ)が可視化されます。
    ref() 関数でつないだモデル同士が線で結ばれて表示されます。


これで、dbt + SQLite 環境でのドキュメント可視化が完成しました。
この画面こそが、まさに

「SSOT(Single Source of Truth)を“見える化”した姿」
です 👏

#dbt #sqlite #ssot #dataascode #divvy

Discussion