
dbt Cloud の Seed で作成されるテーブルを開発環境でのみ Source として扱う
はじめに
dbt Cloud を使用する際、環境分離の制約で本番環境のデータを開発環境で利用できない場面があるとします。Seed を使うと、CSV ファイルから DWH 側のテーブルとして作成できます。また、Seed により作成されたテーブルはソースとして使用することも可能です。
開発環境以外では、本番環境相当のデータを使用できるとして、開発環境でのみ Seed を実行し、他環境と同じソースとして使用してみましたので、試した内容を記事としました。
前提条件
以下の環境で検証しています。
- DWH:Snowflake
- 環境:Snowflake アカウントレベルで分離
- PROD:
- 本番環境
target.name
:prdschema
:prd
- STG:
- 統合テスト環境。複数の開発者が作成したモデルをマージし、品質保証を行う環境
target.name
:stgschema
:stg
- DEV:
- 各ユーザーが新しいデータを開発する、個人の開発環境
target.name
:devschema
:デフォルト(dbt_<ユーザー名>
)- 本番環境のデータは使用できない設定と仮定
- PROD:
- データベース構成
- 各環境(アカウント)で dbt による開発結果を出力する単一のデータベースを用意
- 例:<env>_db
- 各環境(アカウント)で dbt による開発結果を出力する単一のデータベースを用意
- ブランチ戦略
main
ブランチと同期されたstg
ブランチを作成stg
ブランチからfeature/xx
ブランチを派生させ、開発を行う- 開発完了後、
feature/xx
からstg
へブランチにマージする - STG 環境でテストが完了したら、
stg
ブランチの変更をmain
ブランチにマージする
- ジョブ構成
- 本番環境へのデプロイジョブ
main
ブランチの変更を本番環境へ反映するdbt build
を実行
- STG 環境へのデプロイジョブ
stg
ブランチの変更を STG 環境へ反映する- カスタムブランチとして
stg
を指定する dbt build
を実行
- 本番環境へのデプロイジョブ
試してみる
事前準備
Snowflake 側で3つのアカウントを用意し、各環境で環境を表す変数名を変更し、以下を実行しました。今回の設定上、開発環境アカウントではデータロード以降の内容(テーブル作成・データロード)は実行しないようにします。
これにより、dbt Cloud の出力先となるデータベースと生データ用のスキーマが作成されます。ステージング、本番環境では、本番と同様のデータがraw
スキーマにロードされている設定となります。
サンプルデータは Quickstart で提供される jaffle_shop のデータを使用しました。
--変数を定義
--環境名: prd, stg, dev
SET env_name = '<env>';
--データベースを作成
SET db_name = concat($env_name,'_db');
create database if not exists identifier($db_name);
--スキーマを作成
use database identifier($db_name);
--raw
create schema raw;
--ウェアハウスを作成
create warehouse if not exists transforming;
/*==========
以降の内容は開発環境では実行しない
==========*/
--データロード
use schema raw;
--customers
create table customers
( id integer,
first_name varchar,
last_name varchar
);
copy into customers (id, first_name, last_name)
from 's3://dbt-tutorial-public/jaffle_shop_customers.csv'
file_format = (
type = 'CSV'
field_delimiter = ','
skip_header = 1
);
--orders
create table orders
( id integer,
user_id integer,
order_date date,
status varchar,
_etl_loaded_at timestamp default current_timestamp
);
copy into orders (id, user_id, order_date, status)
from 's3://dbt-tutorial-public/jaffle_shop_orders.csv'
file_format = (
type = 'CSV'
field_delimiter = ','
skip_header = 1
);
--データを確認
select * from customers;
select * from orders;
最終的には、以下のパイプラインを作成するとします。この際、開発環境でのみ seed で作成されるテーブルをソースとして参照させます。
Seed を環境ごとに有効化または無効化する
Seed に関する設定項目は以下に記載があります。
この内、General configurations 内に記載がある enabled プロパティを使用します。これにより、特定のリソースの有効化または無効化を制御できます。
ここでは dbt_project.yml
内で以下のように設定しました。
seeds:
+enabled: "{{ target.name == 'dev' }}"
jaffle_shop:
+database: "{{ env_var('DBT_DATABASE') }}"
+schema: raw
ポイントは以下の通りです。
target.name
- 前提条件として開発環境の
target.name
はdev
としているので、開発環境で Seed が有効化される設定です。その他の環境では無効化されます
- 前提条件として開発環境の
- 出力先データベース
- 今回の設定では各環境(アカウント)で dbt による開発結果を出力する単一のデータベースを用意しているため、こちらを出力先としています
- 出力先スキーマ
- seed により出力されるテーブルを開発環境ではソースとして扱いたいので、他環境と同様に生データであることがわかる名称(
raw
)としています - カスタムスキーマ マクロは特に設定していないので、開発環境での実行時は、ユーザーごとに異なる
dbt_<ユーザー名>_raw
({{ default_schema }}_{{ custom_schema_name | trim }}
)の名称からなるスキーマに出力されます
- seed により出力されるテーブルを開発環境ではソースとして扱いたいので、他環境と同様に生データであることがわかる名称(
Seed により作成されるテーブルをソースに指定
Seed を実行後に作成されるテーブルもソースに指定可能です。ここでは models ディレクトリ内に YAML ファイルを作成し、以下のように設定しました。
version: 2
sources:
- name: jaffle_shop
description: This is a replica of the Postgres database used by our app
database: "{{ env_var('DBT_DATABASE') }}"
schema: "{{ 'raw' if target.name == 'prd' or target.name == 'stg' else target.schema ~ '_raw' }}"
tables:
- name: customers
description: One record per customer.
- name: orders
description: One record per order. Includes cancelled and deleted orders.
開発環境以外では本番環境相当のデータを使用できる設定なので、raw レイヤーとなるスキーマが指定されます。開発環境ではtarget.schema ~ '_raw'
により、開発者ごとのdbt_<ユーザー名>_raw
({{ default_schema }}_{{ custom_schema_name | trim }}
)の名称からなるスキーマがこのソーススキーマとして使用されます。
開発環境で実行
seeds/jaffle_shop
ディレクトリ内に以下の CSV ファイルを配置しました。
ここでは簡単に他環境と同じデータからレコードを絞った形で配置しています。
ID,FIRST_NAME,LAST_NAME
1,Michael,P.
2,Shawn,M.
3,Kathleen,P.
4,Jimmy,C.
5,Katherine,R.
ID,USER_ID,ORDER_DATE,STATUS,_ETL_LOADED_AT
1,1,2018-01-01,returned,2025-09-10 15:27:29.140
2,3,2018-01-02,completed,2025-09-10 15:27:29.140
3,94,2018-01-04,completed,2025-09-10 15:27:29.140
4,50,2018-01-05,completed,2025-09-10 15:27:29.140
5,64,2018-01-05,completed,2025-09-10 15:27:29.140
6,54,2018-01-07,completed,2025-09-10 15:27:29.140
7,88,2018-01-09,completed,2025-09-10 15:27:29.140
8,2,2018-01-11,returned,2025-09-10 15:27:29.140
9,53,2018-01-12,completed,2025-09-10 15:27:29.140
10,7,2018-01-14,completed,2025-09-10 15:27:29.140
この状態から、開発環境でdbt seed
を実行してみます。
下図は、生データから次の加工段階のビューとなるモデル作成時のログですが、ソースで指定のデータベース スキーマ(dbt_<ユーザー名>_raw
)から作成されていることが確認できます。
Snowflake 側で確認すると、開発環境アカウントのデフォルトスキーマで各種モデルが作成されています。最終的なマートテーブルを見ると、ここでは seed により作成されたテーブルを使用しているので、レコード数が限られています。
ステージング環境へのデプロイジョブを実行
変更をstgブランチにマージ後、ステージング環境へのデプロイジョブを実行します。
事前準備で、ステージング環境では本番環境相当のデータをロードしているため、最終的なマートテーブルを確認すると開発環境よりもレコード数が多いことが確認できます。
ジョブのログを確認すると、ソースの YAML ファイルで指定した通り、環境ごとのデータベース内のraw
スキーマが参照されています。
ジョブではdbt build
を実行することとしていますが、今回の設定上、開発環境以外では seed のリソースは作成されません。
本番環境へのデプロイジョブを実行
変更を main ブランチへマージ後、同様に本番環境へのデプロイジョブを実行します。
最終的なマートテーブルは、開発環境よりもレコード数が多いことが確認できます。
ジョブのログを確認すると、こちらもソースの YAML ファイルで指定した通り、環境ごとのデータベース内のraw
スキーマが参照されています。
ステージング環境と同様に、今回の設定上、開発環境以外では seed のリソースは作成されません。
本番環境で Seed を有効化してみる
試しにdbt_project.yml
を以下のように変更し、本番環境で seed のリソースを有効化してみます。
seeds:
+enabled: "{{ target.name == 'dev' or target.name == 'prod' }}"
jaffle_shop:
+database: "{{ env_var('DBT_DATABASE') }}"
+schema: raw
本番環境へのデプロイジョブを実行すると、下図のように seed のリソースが作成されます。スキーマ名は{{ default_schema }}_{{ custom_schema_name | trim }}
となります(前提条件より、デフォルトスキーマはprd
)。
注意点として、ソースの場合、実行順は考慮されないようです(ソースとして seed で作成されるテーブルを参照する場合、事前に seed の実行が必要)。
さいごに
Seed で作成されるテーブルを開発環境でのみソースに指定してみました。
ここでは設定しませんでしたが、seed によって作成されるテーブルカラムのデータ型も指定可能です。
こちらの内容が何かの参考になれば幸いです。