
dbtとSnowflakeで本番運用を想定しロールとデータベースを作成して実際に動かしてみた
かわばたです。
dbtとSnowflakeで本番運用を想定しロールとデータベースを作成して実際に検証していきます。
本記事で行うこと
- Snowflakeでウェアハウス・データベース・ロールの作成
 - 各ユーザーに対する権限付与および権限の概要
 - RAW_DBに加工するデータをロード
 - dbtでプロジェクトの作成
- モデルの作成
 - 開発環境での動作確認
 - デプロイ
 
 
検証環境
- dbt Cloudのアカウント
 - Snowflakeのアカウント
※dbtはEnterprise版,SnowflakeはトライアルアカウントのEnterprise版で試しています。 
Snowflakeで行うこと
ウェアハウス・データベース・スキーマの構成
今回本番運用を想定して作成するにあたって、ベースとなる構成にしています。
【ウェアハウス】
- 本番用ウェアハウス
- dbt Cloud の Production Environment ジョブを実行するためのウェアハウス。
 
 - 開発用ウェアハウス
- dbt Cloud の Development Environment で開発者がモデルのテストや小規模なデータ処理を行うためのウェアハウス。
 
 - 分析用ウェアハウス
- 分析者がクエリを実行するためのウェアハウス。他プロセスとの競合を避けるために分離しています。
 
 
実際に作成したクエリ
-- ウェアハウス作成 dbt開発用
create warehouse KAWABATA_DBT_DEV_WH ;
-- ウェアハウス作成 マート参照用
create warehouse KAWABATA_DBT_PRD_WH;
-- ウェアハウス作成 分析者用
create warehouse KAWABATA_DBT_ANALYST_WH;
【データベース】
- RAWデータベース
- 目的:データソースからロードされた生のデータを格納します。
 
 - STAGINGデータベース
- 目的:RAWデータベースのデータをソースとして、カラム名・データ型の変更など、最小限の変換を行い格納します。
 
 - DWHデータベース
- 目的:STAGINGデータベースのモデルを複数組み合わせ、目的に基づいた変換、統合、集計を行います。 
OneBigTable(OBT)、ファクトテーブル、ディメンションテーブルなどがこのレイヤーで構築されます。 
 - 目的:STAGINGデータベースのモデルを複数組み合わせ、目的に基づいた変換、統合、集計を行います。 
 - MARTデータベース
- 目的:特定の分析目的やビジネスドメインに特化したデータマートを構築します。BIツールやデータアナリストが直接利用することを想定します。
 
 
各テーブルの種類について、下記に分かりやすかったドキュメントを記載します。
- OneBigTable
 
- ファクトテーブル
 
- ディメンションテーブル
 
実際に作成したクエリ
-- データベース作成:生データ格納用
create database KAWABATA_RAW_DB;
-- データベース作成:ステージング用
create database KAWABATA_STAGING_DB;
-- データベース作成:DWH用
create database KAWABATA_DWH_DB;
-- データベース作成:データマート用
create database KAWABATA_MART_DB;
【スキーマ】
- 本番用スキーマ
- dbt Cloud の Production Environment ジョブを実行するためのスキーマ。
 
 - 開発用スキーマ
- dbt Cloud の Development Environment で開発者がモデルのテストや小規模なデータ処理を行うためのスキーマ。こちらはdbtで生成するデフォルトのスキーマを使用します。
 
 
実際に作成したクエリ
-- -- スキーマ作成(本番用スキーマ)
create schema KAWABATA_STAGING_DB.PROD_SCHEMA;
create schema KAWABATA_DWH_DB.PROD_SCHEMA;
create schema KAWABATA_MART_DB.PROD_SCHEMA;
ロールについて
- 本番実行用ロール
- 目的:本番環境のデータ変換処理を、スケジュールに従って自動で実行する。
 - dbt Cloudの自動実行ジョブや、CI/CDパイプラインから使われるサービスアカウント用のロールです。人が直接使うことは想定しません。
 
 - 開発用ロール
- 目的:本番環境に影響を与えることなく、安全にdbtモデルの開発とテストを行う。
 - データエンジニアやアナリティクスエンジニアが、dbtモデルを開発・修正・テストするために使用するロールです。開発者ごとに個別のユーザーを作成します。
 
 - 分析者用ロール
- 目的:dbtによって整備された信頼できるデータマートを使って、分析やレポーティングを行う。
 - データアナリストやビジネスユーザーが、BIツール(Tableau, Lookerなど)やSQLクライアントから、完成したデータを参照するために使用するロールです。
 
 
上記目的に沿って実際にかわばたが作成した権限が下記になります。
実際のクエリ
【開発用】
-------------------------------------------------
-- 権限(ロール)開発
-------------------------------------------------
--SECURITYADMINの権限使用。
USE ROLE SECURITYADMIN;
--ロール作成 dbt開発用
CREATE ROLE IF NOT EXISTS KAWABATA_DBT_DEV_ROLE;
--SYSADMIN配下に権限
GRANT ROLE KAWABATA_DBT_DEV_ROLE TO ROLE SYSADMIN;
-- ウェアハウスへの利用権限を付与
GRANT USAGE ON WAREHOUSE KAWABATA_DBT_DEV_WH TO ROLE KAWABATA_DBT_DEV_ROLE;
-----------------------------------------------------------------------------------
-- 開発者が作業するデータベースに対する `USAGE` 権限。また、開発用スキーマを作成するために、これらのデータベースに対する `CREATE SCHEMA` 権限。
-----------------------------------------------------------------------------------
--データベースに対する `USAGE` 権限付与
GRANT USAGE ON DATABASE KAWABATA_STAGING_DB TO ROLE KAWABATA_DBT_DEV_ROLE;
GRANT USAGE ON DATABASE KAWABATA_DWH_DB TO ROLE KAWABATA_DBT_DEV_ROLE;
GRANT USAGE ON DATABASE KAWABATA_MART_DB TO ROLE KAWABATA_DBT_DEV_ROLE;
--これらのデータベースに対する `CREATE SCHEMA` 権限。
GRANT CREATE SCHEMA ON DATABASE KAWABATA_STAGING_DB TO ROLE KAWABATA_DBT_DEV_ROLE;
GRANT CREATE SCHEMA ON DATABASE KAWABATA_DWH_DB TO ROLE KAWABATA_DBT_DEV_ROLE;
GRANT CREATE SCHEMA ON DATABASE KAWABATA_MART_DB TO ROLE KAWABATA_DBT_DEV_ROLE;
-----------------------------------------------------------------------------------
--自身が所有する開発用スキーマ (例: `DBT_YOURNAME`) に対する `USAGE` および全てのオブジェクト作成権限 (`CREATE TABLE`, `CREATE VIEW` など)。
-----------------------------------------------------------------------------------
-- 現時点でスキーマ作成していないので`USAGE`権限付与しない→ON FUTURE句が必要
-- 全てのオブジェクト作成権限 (`CREATE TABLE`, `CREATE VIEW` など)
-- これは現在のスキーマに対する権限付与なので、将来作成されるスキーマに対してはON FUTURE句が必要
-- ここではすべてのスキーマに対して権限付与している。
GRANT ALL ON ALL SCHEMAS IN DATABASE KAWABATA_STAGING_DB TO ROLE KAWABATA_DBT_DEV_ROLE;
GRANT ALL ON ALL SCHEMAS IN DATABASE KAWABATA_DWH_DB TO ROLE KAWABATA_DBT_DEV_ROLE;
GRANT ALL ON ALL SCHEMAS IN DATABASE KAWABATA_MART_DB TO ROLE KAWABATA_DBT_DEV_ROLE;
--FUTURE
GRANT ALL ON FUTURE SCHEMAS IN DATABASE KAWABATA_STAGING_DB TO ROLE KAWABATA_DBT_DEV_ROLE;
GRANT ALL ON FUTURE SCHEMAS IN DATABASE KAWABATA_DWH_DB TO ROLE KAWABATA_DBT_DEV_ROLE;
GRANT ALL ON FUTURE SCHEMAS IN DATABASE KAWABATA_MART_DB TO ROLE KAWABATA_DBT_DEV_ROLE;
-----------------------------------------------------------------------------------
--本番用データベース (`STAGING_DB`, `DWH_DB`, `MART_DB`) の本番スキーマに対する `USAGE` 権限、およびそのスキーマ内のテーブル/ビューに対する `SELECT` 権限 (本番データの参照のため)。
-----------------------------------------------------------------------------------
--本番用スキーマを仮でPROD_SCHEMAとしている~`USAGE` 権限付与~
GRANT USAGE ON SCHEMA KAWABATA_STAGING_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_DEV_ROLE;
GRANT USAGE ON SCHEMA KAWABATA_DWH_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_DEV_ROLE;
GRANT USAGE ON SCHEMA KAWABATA_MART_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_DEV_ROLE;
--テーブルへの`SELECT` 権限(現在作成されているスキーマ内のすべてのテーブル)
GRANT SELECT ON ALL TABLES IN SCHEMA KAWABATA_STAGING_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_DEV_ROLE;
GRANT SELECT ON ALL TABLES IN SCHEMA KAWABATA_DWH_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_DEV_ROLE;
GRANT SELECT ON ALL TABLES IN SCHEMA KAWABATA_MART_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_DEV_ROLE;
--FUTURE
GRANT SELECT ON FUTURE TABLES IN SCHEMA KAWABATA_STAGING_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_DEV_ROLE;
GRANT SELECT ON FUTURE TABLES IN SCHEMA KAWABATA_DWH_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_DEV_ROLE;
GRANT SELECT ON FUTURE TABLES IN SCHEMA KAWABATA_MART_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_DEV_ROLE;
--ビューへの`SELECT` 権限(現在作成されているスキーマ内のすべてのテーブル)
GRANT SELECT ON ALL VIEWS IN SCHEMA KAWABATA_STAGING_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_DEV_ROLE;
GRANT SELECT ON ALL VIEWS IN SCHEMA KAWABATA_DWH_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_DEV_ROLE;
GRANT SELECT ON ALL VIEWS IN SCHEMA KAWABATA_MART_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_DEV_ROLE;
--FUTURE
GRANT SELECT ON FUTURE VIEWS IN SCHEMA KAWABATA_STAGING_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_DEV_ROLE;
GRANT SELECT ON FUTURE VIEWS IN SCHEMA KAWABATA_DWH_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_DEV_ROLE;
GRANT SELECT ON FUTURE VIEWS IN SCHEMA KAWABATA_MART_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_DEV_ROLE;
-----------------------------------------------------------------------------------
--ソースデータベース (`RAW_DB`) およびそのスキーマに対する `USAGE` 権限、ならびにスキーマ内のテーブル/ビューに対する `SELECT` 権限。
-----------------------------------------------------------------------------------
--データベースの`USAGE` 権限。
GRANT USAGE ON DATABASE KAWABATA_RAW_DB TO ROLE KAWABATA_DBT_DEV_ROLE;
--スキーマの`USAGE` 権限。一旦すべてのスキーマを権限対象にしているが、個別に設定も可能
GRANT USAGE ON ALL SCHEMAS IN DATABASE KAWABATA_RAW_DB TO ROLE KAWABATA_DBT_DEV_ROLE;
-- スキーマ内のテーブル/ビューに対する `SELECT` 権限。(すべてのスキーマに対して権限付与しているが個別に設定可能)
GRANT SELECT ON ALL TABLES IN DATABASE KAWABATA_RAW_DB TO ROLE KAWABATA_DBT_DEV_ROLE;
GRANT SELECT ON ALL VIEWS IN DATABASE KAWABATA_RAW_DB TO ROLE KAWABATA_DBT_DEV_ROLE;
-----------------------------------------------------------------------------------
--開発用ウェアハウス (`DBT_DEV_WH`) に対する `USAGE`, `OPERATE` 権限。
-----------------------------------------------------------------------------------
--`USAGE`, `OPERATE` 権限。
GRANT USAGE ON WAREHOUSE KAWABATA_DBT_DEV_WH TO ROLE KAWABATA_DBT_DEV_ROLE;
GRANT OPERATE ON WAREHOUSE KAWABATA_DBT_DEV_WH TO ROLE KAWABATA_DBT_DEV_ROLE;
【本番用】
-------------------------------------------------
-- 権限(ロール)本番用
-----------------------------------------------------------------------------------
--ロール作成 本番実行用
CREATE ROLE IF NOT EXISTS KAWABATA_DBT_PRD_ROLE;
--SYSADMIN配下に権限
GRANT ROLE KAWABATA_DBT_PRD_ROLE TO ROLE SYSADMIN;
-- ウェアハウスへの利用権限を付与
GRANT USAGE ON WAREHOUSE KAWABATA_DBT_PRD_WH TO ROLE KAWABATA_DBT_PRD_ROLE;
-----------------------------------------------------------------------------------
--本番用データベース (`STAGING_DB`, `DWH_DB`, `MART_DB`) に対する `USAGE` 権限。
--データベースに対する `USAGE` 権限付与
-----------------------------------------------------------------------------------
GRANT USAGE ON DATABASE KAWABATA_STAGING_DB TO ROLE KAWABATA_DBT_PRD_ROLE;
GRANT USAGE ON DATABASE KAWABATA_DWH_DB TO ROLE KAWABATA_DBT_PRD_ROLE;
GRANT USAGE ON DATABASE KAWABATA_MART_DB TO ROLE KAWABATA_DBT_PRD_ROLE;
-----------------------------------------------------------------------------------
--これらのデータベース内の本番用スキーマに対する `USAGE`, `CREATE TABLE`, `CREATE VIEW`, `CREATE FUNCTION` 
-----------------------------------------------------------------------------------
--本番用スキーマを仮でPROD_SCHEMAとしている~`USAGE` 権限付与~
GRANT USAGE ON SCHEMA KAWABATA_STAGING_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_PRD_ROLE;
GRANT USAGE ON SCHEMA KAWABATA_DWH_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_PRD_ROLE;
GRANT USAGE ON SCHEMA KAWABATA_MART_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_PRD_ROLE;
--本番用スキーマを仮でPROD_SCHEMAとしている~`CREATE TABLE`, `CREATE VIEW`, `CREATE FUNCTION` 権限付与~
GRANT CREATE TABLE, CREATE VIEW, CREATE FUNCTION ON SCHEMA KAWABATA_STAGING_DB.PROD_SCHEMA  TO ROLE KAWABATA_DBT_PRD_ROLE;
GRANT CREATE TABLE, CREATE VIEW, CREATE FUNCTION ON SCHEMA KAWABATA_DWH_DB.PROD_SCHEMA  TO ROLE KAWABATA_DBT_PRD_ROLE;
GRANT CREATE TABLE, CREATE VIEW, CREATE FUNCTION ON SCHEMA KAWABATA_MART_DB.PROD_SCHEMA  TO ROLE KAWABATA_DBT_PRD_ROLE;
-----------------------------------------------------------------------------------
--既存のテーブル/ビューに対する `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `TRUNCATE` 権限 (dbtの操作に必要なもの)。
-----------------------------------------------------------------------------------
--テーブルに対する
GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE ON ALL TABLES IN SCHEMA KAWABATA_STAGING_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_PRD_ROLE;
GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE ON ALL TABLES IN SCHEMA KAWABATA_DWH_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_PRD_ROLE;
GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE ON ALL TABLES IN SCHEMA KAWABATA_MART_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_PRD_ROLE;
--FUTURE
GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE ON FUTURE TABLES IN SCHEMA KAWABATA_STAGING_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_PRD_ROLE;
GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE ON FUTURE TABLES IN SCHEMA KAWABATA_DWH_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_PRD_ROLE;
GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE ON FUTURE TABLES IN SCHEMA KAWABATA_MART_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_PRD_ROLE;
-----------------------------------------------------------------------------------
--ビューに対する(INSERT, UPDATE, DELETE, TRUNCATEはビューに対して直接付与できない)
-----------------------------------------------------------------------------------
GRANT SELECT ON ALL VIEWS IN SCHEMA KAWABATA_STAGING_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_PRD_ROLE;
GRANT SELECT ON ALL VIEWS IN SCHEMA KAWABATA_DWH_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_PRD_ROLE;
GRANT SELECT ON ALL VIEWS IN SCHEMA KAWABATA_MART_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_PRD_ROLE;
--FUTURE
GRANT SELECT ON FUTURE VIEWS IN SCHEMA KAWABATA_STAGING_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_PRD_ROLE;
GRANT SELECT ON FUTURE VIEWS IN SCHEMA KAWABATA_DWH_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_PRD_ROLE;
GRANT SELECT ON FUTURE VIEWS IN SCHEMA KAWABATA_MART_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_PRD_ROLE;
-----------------------------------------------------------------------------------
--ソースデータベース (`RAW_DB`) に対する `USAGE` 権限
--ソースデータベース内のソーススキーマに対する `USAGE` 権限、およびそのスキーマ内のテーブル/ビューに対する `SELECT` 権限
-----------------------------------------------------------------------------------
--データベースの`USAGE` 権限。
GRANT USAGE ON DATABASE KAWABATA_RAW_DB TO ROLE KAWABATA_DBT_PRD_ROLE;
--スキーマの`USAGE` 権限。一旦すべてのスキーマを権限対象にしているが、個別に設定も可能
GRANT USAGE ON ALL SCHEMAS IN DATABASE KAWABATA_RAW_DB TO ROLE KAWABATA_DBT_PRD_ROLE;
-- スキーマ内のテーブル/ビューに対する `SELECT` 権限。(すべてのスキーマに対して権限付与しているが個別に設定可能)
GRANT SELECT ON ALL TABLES IN DATABASE KAWABATA_RAW_DB TO ROLE KAWABATA_DBT_PRD_ROLE;
GRANT SELECT ON ALL VIEWS IN DATABASE KAWABATA_RAW_DB TO ROLE KAWABATA_DBT_PRD_ROLE;
-----------------------------------------------------------------------------------
--本番用ウェアハウス (`DBT_PROD_WH`) に対する `USAGE`, `OPERATE` 権限。
-----------------------------------------------------------------------------------
GRANT USAGE ON WAREHOUSE KAWABATA_DBT_PRD_WH TO ROLE KAWABATA_DBT_PRD_ROLE;
GRANT OPERATE ON WAREHOUSE KAWABATA_DBT_PRD_WH TO ROLE KAWABATA_DBT_PRD_ROLE;
【分析者用】
-----------------------------------------------------------------------------------
--ANALYST_ROLE (分析者用ロール):
-----------------------------------------------------------------------------------
--ロール作成 分析者用ロール
CREATE ROLE IF NOT EXISTS KAWABATA_DBT_ANALYST_ROLE;
--SYSADMIN配下に権限
GRANT ROLE KAWABATA_DBT_ANALYST_ROLE TO ROLE SYSADMIN;
-- ウェアハウスへの利用権限を付与
GRANT USAGE ON WAREHOUSE KAWABATA_DBT_ANALYST_WH TO ROLE KAWABATA_DBT_ANALYST_ROLE;
--BIツールや分析者が MART_DB の本番スキーマに対して USAGE 権限、およびそのスキーマ内のテーブル/ビューに対する SELECT 権限を持つロール。
--データベースの`USAGE` 権限。
GRANT USAGE ON DATABASE KAWABATA_MART_DB TO ROLE KAWABATA_DBT_ANALYST_ROLE;
--スキーマの`USAGE` 権限。
GRANT USAGE ON SCHEMA KAWABATA_MART_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_ANALYST_ROLE;
--スキーマ内のテーブル/ビューに対する SELECT 権限を持つロール。
GRANT SELECT ON ALL TABLES IN SCHEMA KAWABATA_MART_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_ANALYST_ROLE;
GRANT SELECT ON ALL VIEWS IN SCHEMA KAWABATA_MART_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_ANALYST_ROLE;
--FUTURE
GRANT SELECT ON FUTURE TABLES IN SCHEMA KAWABATA_MART_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_ANALYST_ROLE;
GRANT SELECT ON FUTURE VIEWS IN SCHEMA KAWABATA_MART_DB.PROD_SCHEMA TO ROLE KAWABATA_DBT_ANALYST_ROLE;
--分析用ウェアハウス (ANALYST_WH) に対する USAGE, OPERATE 権限。
GRANT USAGE ON WAREHOUSE KAWABATA_DBT_ANALYST_WH TO ROLE KAWABATA_DBT_ANALYST_ROLE;
GRANT OPERATE ON WAREHOUSE KAWABATA_DBT_ANALYST_WH TO ROLE KAWABATA_DBT_ANALYST_ROLE;
下記のように権限を作成することが出来ました。

作成した権限を各ユーザーに対して付与する必要があります。
-----------------------------------------------
--ユーザーに権限付与
-----------------------------------------------
-- 開発ユーザーに開発権限を付与
GRANT ROLE KAWABATA_DBT_DEV_ROLE TO USER DEV_KAWABATA;
-- 本番実行用アカウントに本番権限を付与
GRANT ROLE KAWABATA_DBT_PRD_ROLE TO USER PROD_KAWABATA;
-- 分析者・BI連携用アカウントに分析者用ロールを付与
GRANT ROLE KAWABATA_DBT_ANALYST_ROLE TO USER ANALYST_KAWABATA;
【公式ドキュメント】
【余談】
ユーザーの作成は下記のようにGUIで作成する方法とSQLクエリで作成する方法があります。

-- 一般ユーザ作成.
create user user1
  password = 'user1'
  login_name = 'user1'
  email = 'user1@gmail.com'
  display_name = 'user1'
  must_change_password = true;
【公式ドキュメント】
RAW_DBに加工するデータをロード
生成AIで作成したダミーデータをRAWデータベースに格納します。
テーブル格納方法については様々な方法がありますが、下記に代表的な方法を記載したものになりますので、ご参考までに参照ください。
【使用するデータ】
顧客データ 25行
| user_id | user_name | created_at | 
|---|---|---|
| 101 | 田中 太郎 | 2024-01-15 | 
| 102 | 鈴木 花子 | 2024-02-20 | 
| 103 | 佐藤 次郎 | 2024-03-10 | 
| 104 | 高橋 三郎 | 2024-04-05 | 
| 105 | 伊藤 四郎 | 2024-05-21 | 
| ~~~ | ~~~ | ~~~ | 
製品データ 25行
| product_id | product_name | price | 
|---|---|---|
| 201 | リンゴ | 150 | 
| 202 | バナナ | 100 | 
| 203 | オレンジ | 120 | 
| 204 | 牛乳 | 250 | 
| 205 | パン | 180 | 
| ~~~ | ~~~ | ~~~ | 
注文データ 100行
| order_id | user_id | product_id | quantity | order_date | status | 
|---|---|---|---|---|---|
| 3001 | 101 | 201 | 5 | 2024-06-01 | completed | 
| 3002 | 102 | 204 | 1 | 2024-06-01 | completed | 
| 3003 | 101 | 205 | 2 | 2024-06-02 | shipped | 
| 3004 | 103 | 202 | 10 | 2024-06-03 | completed | 
| 3005 | 104 | 203 | 3 | 2024-06-05 | shipped | 
| 3006 | 102 | 201 | 2 | 2024-06-05 | pending | 
| 3007 | 105 | 205 | 1 | 2024-06-08 | completed | 
| 3008 | 101 | 204 | 1 | 2024-06-10 | pending | 
| ~~~ | ~~~ | ~~~ | ~~~ | ~~~ | ~~~ | 
dbtで行うこと
プロジェクトの作成
Snowflake側の作業が完了したので、dbtでプロジェクトを作成して、モデルを作成していきます。
詳細なプロジェクトを作成方法の手順は下記ブログの4で紹介しているので是非ご覧ください。
Connection settingsは下記のように設定しました。
ここで設定しているDatabaseはデフォルトのデータベースを設定しています。この後のdbt_project.ymlで詳細なデータベースの格納先を指定していきます。

Development credentialsは下記のように、Snowflake側で開発権限を与えたユーザーとしています。

ここで重要な部分は赤枠の個所で、スキーマ名をユニークにする必要があります。開発者が同じスキーマを利用すると変更が重なり反映されない部分が出てくる懸念があります。
dbt_project.ymlとモデルの作成
早速モデルの開発を行っていきます。
dbt_project.ymlについて、下記のように設定しました。
ポイントはモデル配下にSnowflakeで設定した各種データベースを指定しています。
name: 'snowflake_dbt_project'
version: '1.9.0' # dbt プロジェクトのバージョン
config-version: 2
# このプロファイルは dbt Cloud の接続設定を参照します
profile: 'default' # 通常 dbt Cloud ではこのままでOK
# 各パスの配置を任意に設定できます。今回はデフォルトのまま。
model-paths: ["models"]
analysis-paths: ["analyses"]
test-paths: ["tests"]
seed-paths: ["seeds"]
macro-paths: ["macros"]
snapshot-paths: ["snapshots"]
models:
  snowflake_dbt_project: # プロジェクト名。この下にモデルパスごとの設定を記述
    +materialized: view # models/ 直下など、意図しない場所にモデルが置かれた場合のデフォルト
    staging: # models/staging/ ディレクトリ以下
      +database: KAWABATA_STAGING_DB 
      +materialized: view   # staging レイヤーのデフォルトマテリアライゼーション
    dwh: # models/dwh/ ディレクトリ以下
      +database: KAWABATA_DWH_DB   
      +materialized: table # dwh レイヤーのデフォルトマテリアライゼーション
    mart: # models/mart/ ディレクトリ以下
      +database: KAWABATA_MART_DB    
      +materialized: table  # mart レイヤーの最終マートのデフォルトマテリアライゼーション
models配下の構成は下記のとおりです。順に詳細を記載していきます。

【staging層】
staging_schema.yml- sourcesの定義とテストの定義をしています。※sourcesの定義を別のymlファイルにすることも可能です。
 - sourcesには、Snowflakeで生のデータを格納しているデータベースとスキーマを指定しています。
 
version: 2
sources:
  - name: public
    database: KAWABATA_RAW_DB
    schema: PUBLIC
    tables:
      - name: ORDER_ID
      - name: PRODUCT
      - name: USER_ID
models:
  - name: ORDERS
    description: Primary key
    columns:
      - name: ORDER_ID
        tests:
          - unique
          - not_null
  - name: PRODUCT
    columns:
      - name: PRODUCT_ID
        description: Primary key
        tests:
          - unique
          - not_null
  - name: USERS
    columns:
      - name: USER_ID
        description: Primary key
        tests:
          - unique
          - not_null
- ORDERS.sql
- ここでは型変換やカラム名の統一などを行います。
 
 
with source as (
    -- sourceから呼び出すことで、Lineageに表記されどのデータを利用しているか可読性が上がります。
    select * from {{ source('public', 'ORDER_ID') }}
),
cast_orders as (
select
	ORDER_ID,
	USER_ID,
	PRODUCT_ID,
	-- quantity列をVARCHARからINTEGER(数値)に変換します。
    CAST(quantity AS INTEGER) AS quantity,
    -- order_date列をVARCHARからDATE(日付)に変換します。
    CAST(order_date AS DATE) AS order_date,
	STATUS
from
	source
)
select * from cast_orders
- PRODUCT.sql
- 同様に型変換やカラム名の統一などを行います。
 
 
with source as (
    select * from {{ source('public', 'PRODUCT') }}
),
cast_PRODUCT as (
select
	PRODUCT_ID,
	PRODUCT_NAME,
    -- PRICE列をVARCHARからINTEGER(数値)に変換します。
    CAST(PRICE AS INTEGER) AS PRICE
from
	source
)
select * from cast_PRODUCT
- USERS.sql
- 同様に型変換やカラム名の統一などを行います。
 
 
with source as (
    select * from {{ source('public', 'USER_ID') }}
),
cast_USER_ID as (
select
	USER_ID,
	USER_NAME,
    -- CREATED_AT列をVARCHARからDATE(日付)に変換します。
    CAST(CREATED_AT AS DATE) AS CREATED_AT
from
	source
)
select * from cast_USER_ID
- source関数の公式ドキュメント
 
【dwh層】
- dwh_schema.yml
- テストを定義しています。
 
 
version: 2
models:
  - name: intermediate_mart
    columns:
      - name: ORDER_ID
        description: Primary key
        tests:
          - unique
          - not_null
- intermediate_mart.sql
staging層で作成したデータをjoinし1つのマートにしています。- ref関数を使用することで、作成したモデルを参照することが出来ます。
 
 
SELECT
    -- 注文テーブルからの情報を選択
    o.ORDER_ID,      
    o.ORDER_DATE,   
    o.STATUS,        
    -- ユーザーテーブルからの情報を選択
    u.USER_ID,      
    u.USER_NAME,     
    -- 商品テーブルからの情報を選択
    p.PRODUCT_ID,    
    p.PRODUCT_NAME,  
    p.PRICE,         
    -- 注文テーブルからの数量を選択
    o.QUANTITY,     
    -- 売上金額を計算 (単価 * 数量)
    (p.PRICE * o.QUANTITY) AS TOTAL_PRICE
FROM
    -- 主軸となるordersテーブル
    {{ ref('ORDERS') }} AS o
LEFT JOIN
    -- usersテーブルをuser_idで結合
    {{ ref('USERS') }} AS u ON o.user_id = u.user_id
LEFT JOIN
    -- productsテーブルをproduct_idで結合
     {{ ref('PRODUCT') }} AS p ON o.product_id = p.product_id
- ref関数の公式ドキュメント
 
【mart層】
- mart_schema.yml
- テストを定義しています。
 
 
version: 2
models:
  - name: product_price_summary
    columns:
      - name: PRODUCT_ID
        description: Primary key
        tests:
          - unique
          - not_null
  - name: users_price_summary
    columns:
      - name: USER_ID
        description: Primary key
        tests:
          - unique
          - not_null
- users_price_summary.sql
- BI連携・分析用のマートを作成します。
USER_ID単位でTOTAL_PRICEを算出しています。 
 - BI連携・分析用のマートを作成します。
 
SELECT
    -- ユーザーテーブルからの情報を選択
    USER_ID,      
    USER_NAME,      
    SUM(TOTAL_PRICE) as TOTAL_PRICE
FROM
    -- intermediate_mart
    {{ ref('intermediate_mart') }} 
GROUP BY
    USER_ID,      
    USER_NAME
ORDER BY
    USER_ID ASC
- product_price_summary.sql
- BI連携・分析用のマートを作成します。ここでは
PRODUCT_ID単位でTOTAL_PRICEを算出しています。 
 - BI連携・分析用のマートを作成します。ここでは
 
SELECT
    -- 商品テーブルからの情報を選択
    PRODUCT_ID,    
    PRODUCT_NAME,  
    SUM(TOTAL_PRICE) as TOTAL_PRICE
FROM
    -- intermediate_mart
    {{ ref('intermediate_mart') }} 
GROUP BY
    PRODUCT_ID,
    PRODUCT_NAME
ORDER BY
    PRODUCT_ID ASC
これでモデルの作成が完了しました。
product_price_summary.sqlのLineageは下記のようになりました。

このモデルはどのソース/モデルを使用しているのか、一目で分かるのは良いですね!
実際に動かします
開発環境で実際にdbt runを実行しました。
下記の通り、実行自体は成功しました。

Snowflake側を確認しましょう。

赤枠のとおり、作成したいデータベースのスキーマ内にテーブルまたはビューが作成できていました。
dbt testも実行してみます。
今回のテストはデータが簡易なため、汎用テストのNot Null、Uniqueのみ行っています。

【躓きポイント】
ymlファイルのmodelsで指定するnameは、対応する.sqlのファイル名と大文字・小文字を一致させる必要がありました。一致していないと、dbtがモデルとして認識しませんでした。
Snowflakeではオブジェクト名の大文字・小文字は区別されないためSQLの実行自体は通りますが、dbtではファイル名とモデル名が厳密に比較されるため、この違いがエラーの原因となります。
※dbtでは、ファイル名やモデル名を小文字で統一することが推奨されています。

デプロイ
OrchestrationのEnvironmentsからデプロイ用の環境を作成します。

jobを作成し、実行してみると成功が確認できました。

Snowflake側も確認します。本番用のユーザーでログインした場合が下記です。

想定通り、PROD_SCHEMAにデータが格納されました。
分析者用のアカウントでも確認してみます。

ありました!!
実際にワークシートで出力することが出来たので想定通りの挙動でした。
おわりに
簡単ではありますが、一連の開発の流れを確認することが出来ました。
Snowflakeとdbtについて、まだまだ使用できていない機能があるので実際に試してみて発信していきます。
参考になれば幸いです。








