dbt Projects on Snowflakeの初期セットアップ~一般的な開発&本番実行手順のまとめ

dbt Projects on Snowflakeの初期セットアップ~一般的な開発&本番実行手順のまとめ

2025.11.07

さがらです。

dbt Projects on Snowflakeについて、リリース当初に試したときよりもセットアップが楽になった点などあるため、改めて初期セットアップ~一般的な開発&本番実行手順を本記事にてまとめてみます。

(先日公開されたこちらの公式ブログにてReduce Overhead with Support for Existing Tools: With dbt Projects on Snowflake (now generally available),と書いてあったため、一般提供の日は近いはず…! ※リリースノートにはまだ一般提供の記載がない状況です。)

前提条件

以下の前提で実施します。

  • Snowflake:AWS東京リージョン、Enterpriseエディション(有償アカウント)
  • リモートリポジトリ:FreeのGitHub

事前準備:パーソナルデータベースの有効化を確認

リリース当初はセカンダリロール周りの制限もありましたが、現在はパーソナルデータベースを有効化していればWorkspace及びdbt Projects on Snowflakeを利用することが可能です。

デフォルトで有効化されていますが、以下のクエリで有効化されているかを確認可能です。

-- アカウントレベル
SHOW PARAMETERS LIKE 'ENABLE_PERSONAL_DATABASE' IN ACCOUNT;

-- ユーザーレベル
SHOW PARAMETERS LIKE 'ENABLE_PERSONAL_DATABASE' IN USER <username>;

事前準備:セカンダリロールの有効化

2025/11/7時点では、セカンダリロールを有効化していないと、Workspaceからdbt Projectsをデプロイする際に下記のようにエラーが起きてしまいます。(Snowflake社のサポートにも問い合わせましたが、現時点での仕様ではセカンダリロールの有効化が必要とのことです。)

CREATE DBT PROJECT "PROD_DB"."DBT_PROJECTS"."DBT_PJ" FROM $$snow://workspace/USER$SAGARA_SATOSHI.PUBLIC."dbt_projects_on_snowflake_setup_test"/versions/live/dbt_projects_on_snowflake_setup_test$$ DEFAULT_TARGET = 'prod' EXTERNAL_ACCESS_INTEGRATIONS = ('DBT_GIT_EXT_ACCESS')

Error: SQL compilation error:
Uncaught exception of type 'STATEMENT_ERROR' on line 2 at position 26 : SQL compilation error:
Database 'USER$SAGARA_SATOSHI' does not exist or not authorized.

そのためセカンダリロールの有効化が必要なのですが、最小限の権限で設定すべきだと思います。(こちらのブログがとても参考になります。)

…と思っていたのですが、セカンダリロールを絞り込むセッションポリシーを適用していると何度試しても同じエラーとなってしまいました…(以下、試したことの例)

  • secondary role:全権限有効 ※セッションポリシーなし
    • dbt_prod_roleでデプロイ:成功
  • secondary role:セッションポリシーでは、publicのみ有効
    • dbt_prod_roleでデプロイ:失敗
  • secondary role:セッションポリシーでは、publicと、dbt project作った時に設定したdbt_dev_roleを有効
    • dbt_prod_roleでデプロイ:失敗
  • secondary role:セッションポリシーでは、publicと、Workspaceを作った時に使っていそうなデフォルトロールであったsysadminを有効
    • dbt_prod_roleでデプロイ:失敗
  • secondary role:セッションポリシーでは、publicと、accountadminを有効
    • dbt_prod_roleでデプロイ:失敗

そのため、セッションポリシーは特に設定せずに、セカンダリロールが有効化されていることを確認しましょう。

SELECT CURRENT_SECONDARY_ROLES();

2025-11-06_19h20_57

事前準備:dbtに必要なロール・ウェアハウス・データベースオブジェクトの作成

dbtに必要な必要なロール・ウェアハウス・データベースオブジェクトを作成します。

特にロールについては、以下の権限があれば問題はない認識です。

  • 開発用ロール

    • 任意の開発用ウェアハウスを起動/利用し、クエリ実行ができる
    • 生データソースのスキーマから既存のテーブル/ビュー/動的テーブル(Dynamic Table)を読み取ることができる
    • 生データソース内で将来作成されるテーブル/ビュー/動的テーブルに対しても読み取りアクセスを持つ
    • 開発スキーマ内でテーブル/ビュー/マテリアライズドビュー/動的テーブルを作成し、作成したオブジェクトに対する読み書きおよび削除が可能
  • 本番用ロール

    • 本番用ウェアハウスを起動/利用し、クエリ実行ができる
    • 生データソースのスキーマから既存および将来のテーブル/ビュー/動的テーブルを読み取ることができる
    • 本番スキーマ内でテーブル/ビュー/マテリアライズドビュー/動的テーブルを作成し、作成したオブジェクトに対する読み書きおよび削除が可能
    • dbt Projectをスキーマオブジェクトとしてデプロイするスキーマに対して、dbt Projectの作成、タスクの作成、およびタスクの実行ができる

今回は以下のクエリで作成しました。

ロール・ウェアハウス・データベースオブジェクトの作成で実行したクエリ

USE ROLE ACCOUNTADMIN;

-- 1. warehouses 作成と権限付与
CREATE WAREHOUSE IF NOT EXISTS dbt_dev_wh
  WITH
    WAREHOUSE_SIZE = XSMALL
    AUTO_SUSPEND = 60
    AUTO_RESUME = TRUE
    INITIALLY_SUSPENDED = TRUE;

CREATE WAREHOUSE IF NOT EXISTS dbt_prod_wh
  WITH
    WAREHOUSE_SIZE = XSMALL
    AUTO_SUSPEND = 60
    AUTO_RESUME = TRUE
    INITIALLY_SUSPENDED = TRUE;

-- 2. 基本データベースとスキーマ作成

CREATE DATABASE raw_db;
CREATE SCHEMA raw_db.jaffle_shop;
CREATE SCHEMA raw_db.stripe;

CREATE DATABASE dev_db;
CREATE SCHEMA dev_db.dbt_ssagara;

CREATE DATABASE prod_db;
CREATE SCHEMA prod_db.jaffle_shop_staging;
CREATE SCHEMA prod_db.jaffle_shop_mart;
CREATE SCHEMA prod_db.dbt_projects; -- dbt Projectのデプロイとタスク作成用

-- 3. テーブル作成とデータロード

CREATE TABLE raw_db.jaffle_shop.customers (
  id INTEGER,
  first_name VARCHAR,
  last_name VARCHAR
);

COPY INTO raw_db.jaffle_shop.customers (id, first_name, last_name)
FROM 's3://dbt-tutorial-public/jaffle_shop_customers.csv'
FILE_FORMAT = (
  TYPE = 'CSV',
  FIELD_DELIMITER = ',',
  SKIP_HEADER = 1
);

CREATE TABLE raw_db.jaffle_shop.orders (
  id INTEGER,
  user_id INTEGER,
  order_date DATE,
  status VARCHAR,
  _etl_loaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

COPY INTO raw_db.jaffle_shop.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
);

CREATE TABLE raw_db.stripe.payment (
  id INTEGER,
  orderid INTEGER,
  paymentmethod VARCHAR,
  status VARCHAR,
  amount INTEGER,
  created DATE,
  _batched_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

COPY INTO raw_db.stripe.payment (id, orderid, paymentmethod, status, amount, created)
FROM 's3://dbt-tutorial-public/stripe_payments.csv'
FILE_FORMAT = (
  TYPE = 'CSV',
  FIELD_DELIMITER = ',',
  SKIP_HEADER = 1
);

-- 4. ロール作成し、SYSADMINの子ロールに

USE ROLE SECURITYADMIN;
CREATE ROLE dbt_dev_role;
CREATE ROLE dbt_prod_role;

GRANT ROLE dbt_dev_role TO ROLE SYSADMIN;
GRANT ROLE dbt_prod_role TO ROLE SYSADMIN;

-- 5. 権限付与

-- 5A. warehouses の使用権限
GRANT USAGE,OPERATE ON WAREHOUSE dbt_dev_wh TO ROLE dbt_dev_role;
GRANT USAGE,OPERATE ON WAREHOUSE dbt_prod_wh TO ROLE dbt_prod_role;

-- 5B. raw_db に対する read 権限 + Future Objects(dev_role)

GRANT USAGE ON DATABASE raw_db TO ROLE dbt_dev_role;
GRANT USAGE ON SCHEMA raw_db.jaffle_shop TO ROLE dbt_dev_role;
GRANT USAGE ON SCHEMA raw_db.stripe TO ROLE dbt_dev_role;

GRANT SELECT ON ALL TABLES IN SCHEMA raw_db.jaffle_shop TO ROLE dbt_dev_role;
GRANT SELECT ON ALL TABLES IN SCHEMA raw_db.stripe TO ROLE dbt_dev_role;

GRANT SELECT ON FUTURE TABLES IN SCHEMA raw_db.jaffle_shop TO ROLE dbt_dev_role;
GRANT SELECT ON FUTURE TABLES IN SCHEMA raw_db.stripe TO ROLE dbt_dev_role;

GRANT SELECT ON ALL VIEWS IN SCHEMA raw_db.jaffle_shop TO ROLE dbt_dev_role;
GRANT SELECT ON ALL VIEWS IN SCHEMA raw_db.stripe TO ROLE dbt_dev_role;

GRANT SELECT ON FUTURE VIEWS IN SCHEMA raw_db.jaffle_shop TO ROLE dbt_dev_role;
GRANT SELECT ON FUTURE VIEWS IN SCHEMA raw_db.stripe TO ROLE dbt_dev_role;

GRANT SELECT ON ALL DYNAMIC TABLES IN SCHEMA raw_db.jaffle_shop TO ROLE dbt_dev_role;
GRANT SELECT ON ALL DYNAMIC TABLES IN SCHEMA raw_db.stripe TO ROLE dbt_dev_role;

GRANT SELECT ON FUTURE DYNAMIC TABLES IN SCHEMA raw_db.jaffle_shop TO ROLE dbt_dev_role;
GRANT SELECT ON FUTURE DYNAMIC TABLES IN SCHEMA raw_db.stripe TO ROLE dbt_dev_role;

-- 5C. raw_db に対する read 権限 + Future Objects(prod_role)

GRANT USAGE ON DATABASE raw_db TO ROLE dbt_prod_role;
GRANT USAGE ON SCHEMA raw_db.jaffle_shop TO ROLE dbt_prod_role;
GRANT USAGE ON SCHEMA raw_db.stripe TO ROLE dbt_prod_role;

GRANT SELECT ON ALL TABLES IN SCHEMA raw_db.jaffle_shop TO ROLE dbt_prod_role;
GRANT SELECT ON ALL TABLES IN SCHEMA raw_db.stripe TO ROLE dbt_prod_role;

GRANT SELECT ON FUTURE TABLES IN SCHEMA raw_db.jaffle_shop TO ROLE dbt_prod_role;
GRANT SELECT ON FUTURE TABLES IN SCHEMA raw_db.stripe TO ROLE dbt_prod_role;

GRANT SELECT ON ALL VIEWS IN SCHEMA raw_db.jaffle_shop TO ROLE dbt_prod_role;
GRANT SELECT ON ALL VIEWS IN SCHEMA raw_db.stripe TO ROLE dbt_prod_role;

GRANT SELECT ON FUTURE VIEWS IN SCHEMA raw_db.jaffle_shop TO ROLE dbt_prod_role;
GRANT SELECT ON FUTURE VIEWS IN SCHEMA raw_db.stripe TO ROLE dbt_prod_role;

GRANT SELECT ON ALL DYNAMIC TABLES IN SCHEMA raw_db.jaffle_shop TO ROLE dbt_prod_role;
GRANT SELECT ON ALL DYNAMIC TABLES IN SCHEMA raw_db.stripe TO ROLE dbt_prod_role;

GRANT SELECT ON FUTURE DYNAMIC TABLES IN SCHEMA raw_db.jaffle_shop TO ROLE dbt_prod_role;
GRANT SELECT ON FUTURE DYNAMIC TABLES IN SCHEMA raw_db.stripe TO ROLE dbt_prod_role;

-- 6D. dev_db.dbt_ssagaraに対する権限(dev_role のみ、作成・書き込み等)

GRANT USAGE ON DATABASE dev_db TO ROLE dbt_dev_role;
GRANT USAGE ON SCHEMA dev_db.dbt_ssagara TO ROLE dbt_dev_role;

GRANT CREATE TABLE ON SCHEMA dev_db.dbt_ssagara TO ROLE dbt_dev_role;
GRANT CREATE VIEW ON SCHEMA dev_db.dbt_ssagara TO ROLE dbt_dev_role;
GRANT CREATE MATERIALIZED VIEW ON SCHEMA dev_db.dbt_ssagara TO ROLE dbt_dev_role;
GRANT CREATE DYNAMIC TABLE ON SCHEMA dev_db.dbt_ssagara TO ROLE dbt_dev_role;

GRANT OWNERSHIP ON ALL TABLES IN SCHEMA dev_db.dbt_ssagara TO ROLE dbt_dev_role;
GRANT OWNERSHIP ON ALL VIEWS IN SCHEMA dev_db.dbt_ssagara TO ROLE dbt_dev_role;
GRANT OWNERSHIP ON ALL DYNAMIC TABLES IN SCHEMA dev_db.dbt_ssagara TO ROLE dbt_dev_role;

-- 6E. prod_db.jaffle_shopに対する権限(prod_role のみ、作成・書き込み)

GRANT USAGE ON DATABASE prod_db TO ROLE dbt_prod_role;
GRANT USAGE ON SCHEMA prod_db.jaffle_shop_staging TO ROLE dbt_prod_role;
GRANT USAGE ON SCHEMA prod_db.jaffle_shop_mart TO ROLE dbt_prod_role;

GRANT CREATE TABLE ON SCHEMA prod_db.jaffle_shop_staging TO ROLE dbt_prod_role;
GRANT CREATE VIEW ON SCHEMA prod_db.jaffle_shop_staging TO ROLE dbt_prod_role;
GRANT CREATE MATERIALIZED VIEW ON SCHEMA prod_db.jaffle_shop_staging TO ROLE dbt_prod_role;
GRANT CREATE DYNAMIC TABLE ON SCHEMA prod_db.jaffle_shop_staging TO ROLE dbt_prod_role;

GRANT OWNERSHIP ON ALL TABLES IN SCHEMA prod_db.jaffle_shop_staging TO ROLE dbt_prod_role;
GRANT OWNERSHIP ON ALL VIEWS IN SCHEMA prod_db.jaffle_shop_staging TO ROLE dbt_prod_role;
GRANT OWNERSHIP ON ALL DYNAMIC TABLES IN SCHEMA prod_db.jaffle_shop_staging TO ROLE dbt_prod_role;

GRANT CREATE TABLE ON SCHEMA prod_db.jaffle_shop_mart TO ROLE dbt_prod_role;
GRANT CREATE VIEW ON SCHEMA prod_db.jaffle_shop_mart TO ROLE dbt_prod_role;
GRANT CREATE MATERIALIZED VIEW ON SCHEMA prod_db.jaffle_shop_mart TO ROLE dbt_prod_role;
GRANT CREATE DYNAMIC TABLE ON SCHEMA prod_db.jaffle_shop_mart TO ROLE dbt_prod_role;

GRANT OWNERSHIP ON ALL TABLES IN SCHEMA prod_db.jaffle_shop_mart TO ROLE dbt_prod_role;
GRANT OWNERSHIP ON ALL VIEWS IN SCHEMA prod_db.jaffle_shop_mart TO ROLE dbt_prod_role;
GRANT OWNERSHIP ON ALL DYNAMIC TABLES IN SCHEMA prod_db.jaffle_shop_mart TO ROLE dbt_prod_role;

-- 6F. prod_db.dbt_projectsに対する権限(タスク、dbt project関係)

GRANT USAGE ON SCHEMA prod_db.dbt_projects TO ROLE dbt_prod_role;

GRANT CREATE TASK ON SCHEMA prod_db.dbt_projects TO ROLE dbt_prod_role;
GRANT EXECUTE TASK ON ACCOUNT TO ROLE dbt_prod_role;
GRANT EXECUTE MANAGED TASK ON ACCOUNT TO ROLE dbt_prod_role;

GRANT CREATE DBT PROJECT ON SCHEMA prod_db.dbt_projects TO ROLE dbt_prod_role;

事前準備:GitHub関係のAPI Integrationやネットワークルールなどを定義

今回はリモートリポジトリにGitHubを利用するため、以下を定義します。(各Integrationに対して、dbtで使用するロールにUSAGE権限が必要となりますのでご注意ください。)

  • OAuth2認証のためのAPI Integration定義
  • dbtやGitHubからパッケージを取得するためのNetwork RuleとExternal Access Integrationの作成
    • External Access Integrationはトライアルアカウントでは設定不可のため、ご注意ください。
  • 任意:GitHub Actionsに関するSnowflake-managed network rulesの定義とアカウントレベルでの適用
    • ご利用中のSnowflakeアカウントでIP制限をしており、GitHub Actionsの利用予定がある場合は設定してください
USE ROLE ACCOUNTADMIN;

-- セキュリティ用データベースとスキーマを作成

CREATE DATABASE IF NOT EXISTS security_db;
CREATE SCHEMA IF NOT EXISTS security_db.network_rules;

-- OAuth2認証用 API Integrationの定義と権限付与

CREATE OR REPLACE API INTEGRATION oauth2_api_integration
  API_PROVIDER = git_https_api
  API_ALLOWED_PREFIXES = (
    'https://github.com/<対象のGitHubアカウント名>/'
  )
  API_USER_AUTHENTICATION = (TYPE = SNOWFLAKE_GITHUB_APP)
  ENABLED = TRUE;

GRANT USAGE ON INTEGRATION oauth2_api_integration TO ROLE dbt_dev_role;
GRANT USAGE ON INTEGRATION oauth2_api_integration TO ROLE dbt_prod_role;

-- GitHub / dbt パッケージ取得等用Network Ruleを作成し、External Access Integrationの定義と権限付与
USE SCHEMA security_db.network_rules;

CREATE OR REPLACE NETWORK RULE dbt_pkg_network_rule
  MODE = egress
  TYPE = host_port
  VALUE_LIST = (
    'hub.getdbt.com',
    'codeload.github.com'
  );

CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION dbt_git_ext_access
  ALLOWED_NETWORK_RULES = (security_db.network_rules.dbt_pkg_network_rule)
  ENABLED = TRUE;

GRANT USAGE ON INTEGRATION dbt_git_ext_access TO ROLE dbt_dev_role;
GRANT USAGE ON INTEGRATION dbt_git_ext_access TO ROLE dbt_prod_role;

-- 任意:SnowflakeアカウントでIP制限を行っている場合
-- GitHub Actionsに関するManaged network rule を含むネットワークポリシーの作成し、アカウントに対してネットワークポリシーを適用
CREATE OR REPLACE NETWORK POLICY accountlevel_network_policy
  ALLOWED_NETWORK_RULE_LIST = (
    'SNOWFLAKE.NETWORK_SECURITY.GITHUBACTIONS_GLOBAL',
    '<その他、アカウントレベルで許可するIP一覧を登録したnetwork rule名>'
  );

ALTER ACCOUNT SET NETWORK_POLICY = accountlevel_network_policy;

事前準備:GitHubでREADMEだけ用意したリポジトリを作成

GitHubで、READMEだけ用意したリポジトリを作成します。(READMEが必要なのは、空のリポジトリだとdbt Projectのセットアップができないためです。)

2025-11-05_18h36_16

Workspaceでdbt Projctをセットアップ

続いて、Workspaceでdbt Projects on Snowflakeをセットアップしていきます。

GitHubのリポジトリと連携してWorkspaceを作成

左のメニューのProjectsからWorkspaceを押します。

2025-11-05_18h32_14

Workspaceの画面の左上のWorkspace名を押して、From Git repositoryを押します。

2025-11-05_18h38_56

表示された画面で作成したリポジトリのURLをRepository URLに貼り付けます。API Integrationは、作成したOAuth2認証用のAPI Integrationを指定します。

その後、Sign inを押してOAuth認証を行います。

2025-11-05_18h41_20

下図のようなポップアップが表示されるため、順番に沿って進めていきます。

2025-11-05_18h42_24

2025-11-05_18h47_27

うまく認証を終えると、下図のように表示されます。(私の場合はもう一度Sign inを押して再認証する必要がありました。)

続けてリポジトリにSnowflakeのAppを入れるため、Configureを押します。

2025-11-05_18h54_01

表示されたSnowflakeのAppのインストール画面で、適切なリポジトリだけを選択し、Installを押します。

2025-11-05_18h55_46

無事にインストールが行われると、GitHub上で下図のように表示されると思います。

2025-11-05_18h58_39

このあとでSnowflakeの画面にもどり、右下のCreateを押します。

2025-11-05_19h00_49

これで、GitHubリポジトリと連携したWorkspace設定は完了です!

2025-11-05_19h04_36

dbt Projectをセットアップ

次に、dbt Projectをセットアップしていきます。

Workspaceの画面の左上でAdd newを押して、dbt Projectを押します。

2025-11-05_19h05_44

表示されたポップアップで、Project Nameは任意のものを設定し、ロール・ウェアハウス・データベース・スキーマはすべて開発用のものを選択し、Createを押します。

2025-11-05_19h07_25

下図のようにdbt関係のフォルダとファイルが作成されます。(以前と異なり、リポジトリのルート階層にdbt関係のmodelsなどのフォルダが作成されるのではなく、ルート階層に指定したProject Nameでフォルダが作られる仕様となっていました。)

2025-11-05_19h14_38

dbt自体の各種設定

ここからは、dbt自体の各種設定に移ります。

本番用のprofileの設定

まず、dbt Projects on Snowflakeではdbt Coreを使用しているため、接続情報の管理はprofiles.ymlで行います。ファイルの内容を見ると、下図のようにdbt Projectのセットアップ時に指定したロールやデータベースが入っていると思います。

2025-11-06_06h34_11

こちらについて、下記のように本番用のtargetを追加します。(余談ですが、databaseやschemaに入力した値は、デフォルトの出力先として扱われます。後述するカスタムスキーマ関係の設定により、出力先は柔軟に変更可能です。)

2025-11-06_07h00_42

正しく本番用のtargetが追加できていれば、上部のProfileから選択できるようになります。

2025-11-06_06h38_52

推奨設定:generate_schema_nameマクロを変更

これは個人的な推奨設定なのですが、dbtで出力先のスキーマをカスタムしたい場合に使用するgenerate_schema_nameマクロを設定することをおすすめしています。この理由は以下のブログをご覧ください。

https://dev.classmethod.jp/articles/dbt-rewriting-the-generate-schema-name-macro/

上記のブログに書いてあるマクロをそのまま実装すると、下図のようになります。

2025-11-06_06h42_13

modelsフォルダ内で必要なサブフォルダを作成&dbt_project.ymlの変更

dbtではmodelsフォルダ内で.sqlファイルを書いていきますが、この際にmodels内でサブフォルダを設けることで、フォルダ単位でMaterializationをどうするか、出力先のデータベース・スキーマをどうするか、といった設定を変更できます。

今回は取り急ぎ、stagingフォルダとmartフォルダを追加してみます。

2025-11-06_06h50_42

続いて、各フォルダに対する設定をまとめて変更するにはdbt_project.ymlで変更します。modelsの中で、下図のように変更してあげればOKです。(注意点として、このようにフォルダごとに出力先を変更することをdbtではカスタムスキーマと呼んでいますが、このカスタムスキーマを設定する場合は基本的に上述の”generate_schema_nameマクロを変更”を行うようにしてください。)

この設定では、generate_schema_nameマクロの設定と併せて、以下のような挙動となります。

  • stagingフォルダ配下:viewで生成し、出力先のスキーマは、targetがdevのときはdbt_ssagara、targetがprodのときはJAFFLE_SHOP_STAGING
  • martフォルダ配下:tableで生成し、出力先のスキーマは、targetがdevのときはdbt_ssagara、targetがprodのときはJAFFLE_SHOP_MART

2025-11-06_07h08_48

dbtの開発

開発用ブランチを切る

まず、開発用のブランチを切ります。

Workspaceの画面で左上のChangesを押して、mainを押し、+ Newを押します。

2025-11-06_07h53_38

ブランチ名を入れて、Createを押します。

2025-11-06_07h54_21

これでブランチが切られた状態となります。

2025-11-06_07h55_48

source用の.ymlファイルの開発

まず、dbtで使用する加工元のデータを定義するため、source用の.ymlファイルを開発します。

https://docs.getdbt.com/docs/build/sources

下図のように定義しました。

2025-11-06_07h14_25

.sqlファイルの開発

dbtでは各.sqlファイルを開発していくことで、その.sqlファイルの内容がdbt buildなどのコマンド実行時にCTAS文などに置き換わり、Snowflakeに対して実行されます。

https://docs.getdbt.com/docs/build/sql-models

下図のように定義しました。

  • stagingフォルダの.sqlファイルの例
    • 先に作成したsourceを参照しているのがポイントです。

2025-11-06_07h17_38

  • martフォルダの.sqlファイルの例
    • refを用いて、stagingフォルダの.sqlを参照しているのがポイントです。

2025-11-06_07h19_11

.ymlファイルの開発

次に、.sqlファイルによって作られるテーブル・ビューに対してdescriptionやtestを追加するため、定義用の.ymlファイルを作成します。

※先程のsourceも同様ですが、この.ymlファイルは複数ファイルあっても問題ないため、各.sqlファイルごとに対応する.ymlファイルを作成しても問題ありません。

https://docs.getdbt.com/docs/build/documentation

下図のように定義しました。

2025-11-06_07h24_45

任意:外部パッケージの追加

dbtでは多くのサードパーティパッケージが提供されており、マクロやテストを追加できることはもちろん、特定のデータセットに対する.sqlファイルもパッケージからインポートすることができます。

https://hub.getdbt.com/

今回はdbtの公式パッケージでもあるdbt_utilsを入れてみます。

dbt Projectのルート階層でpackages.ymlを追加し、下図のように定義しました。

2025-11-06_07h30_18

このあと、dbt depsを実行して、対象のパッケージをインポートします。External Access Integrationの指定も行った上で、実行します。

2025-11-06_07h33_00

無事に成功すれば、下図のようにログが表示され、dbt_packagesフォルダ内にインポートしたdbt_utilsが追加されていることがわかります。

2025-11-06_07h34_30

また、これはおまけなのですが、私が開発したときは.gitignoredbt_packagesフォルダが追加されていなかったため、追加しておきます。

2025-11-06_08h00_54

dbt compileを実行

このタイミングでdbt compileを実行してみると、refやsourceなどのJinja関数がコンパイルされた実行可能な.sqlファイルや、このdbt Projectに関するArtifactが生成されます。

2025-11-06_07h38_56

また、dbt compileを行うことで各.sqlファイルの実行順序を表すDAGも生成してくれます。

2025-11-06_07h39_57

開発環境に対して実際にテーブル・ビューを生成しテスト

これで一連の開発は終了となるため、開発環境に対して実際にテーブル・ビューを生成しテストしてみます。

Profiledevであることを確認した上で、dbt buildを実行します。

2025-11-06_07h41_21

無事に成功すると、下図のようなログが表示されます。

2025-11-06_07h42_00

この上で、targetのdevで指定したスキーマを見てみると、無事にテーブルとビューが作られていることがわかります!

2025-11-06_07h44_43

開発した内容をmainブランチに反映

無事に開発を行えたので、開発した内容をmainブランチに反映させます。

左上のChangesから、Pushを押して任意のコミットメッセージを入れて、Pushを押します。

2025-11-06_07h56_56

プルリクエストを発行するため、「…」からOpen repo pageを押します。

2025-11-06_07h57_49

あとは、mainブランチへのプルリクエストを発行してマージさせます。

2025-11-06_07h58_31

2025-11-06_08h02_27

スキーマオブジェクトとしてdbt Projectをデプロイ

mainブランチとしての開発を終えたため、実際にタスクとして定期実行するためにスキーマオブジェクトとしてdbt Projectをデプロイします。

Workspace右上のConnectを押し、Deploy dbt Projectを押します。

2025-11-06_08h06_14

表示された画面で、下図のように設定します。本番用のロールやデータベースに加えてdbt Project用のスキーマを指定した上で、Default TargetprodRun dbt deptにもチェックを入れて使用するExternal Access Integrationを設定します。

この上で、Deployを押します。

2025-11-06_08h09_52

下図のようにログが表示されたら、成功です!

2025-11-06_19h22_25

スキーマにデプロイしたdbt Projectを確認すると、下図のように見ることが出来ます。(いつの間にかリネージも見れるようになっている…!)

2025-11-07_07h44_56

参考:GitHub Actionsを設定することでこの処理を自動化できます

このデプロイ作業ですが、正直面倒であり作業ミスにもつながるため、GitHub Actionsで自動化することを推奨しています。

以下のブログで検証していますので、詳細はこちらからご確認ください。

https://dev.classmethod.jp/articles/dbt-projects-on-snowflake-deploy-from-github-actions/

タスクを設定・実行

続いて、デプロイしたスキーマオブジェクトのdbt Projectを用いて、定期実行するためのタスクを定義します。

今回はSQLで定義するため、以下のクエリで定義しました。

USE ROLE dbt_prod_role;
CREATE OR ALTER TASK prod_db.dbt_projects.execute_dbt
  WAREHOUSE = dbt_prod_wh
  SCHEDULE = 'USING CRON 0 9 1 1 * Asia/Tokyo'
AS
EXECUTE DBT PROJECT prod_db.dbt_projects.dbt_pj;

手動で実行するには、以下のクエリで実行可能です。

EXECUTE TASK prod_db.dbt_projects.execute_dbt;

実行後、本番用のデータベースを見てみると、dbt_project.ymlで指定したスキーマに合わせて、テーブルとビューが作成されることがわかります!

2025-11-07_08h00_16

作成したタスクの確認

作成したタスクの定義はSnowsightで対象のdbt Projectの画面からも確認可能です。

2025-11-07_08h03_01

2025-11-07_08h03_25

参考:Snowsightからタスクを作成

また、タスクの定義はSnowsightからGUIベースでも行うことが可能です。

2025-11-07_07h47_56

2025-11-07_07h49_07

参考:ログ・監視

これは参考情報ですが、dbt Projects on Snowflakeに関するログや監視は、イベントテーブルを定義することで可能です。

こちらについては下記のブログでまとめていますので、ぜひご覧ください。

https://dev.classmethod.jp/articles/dbt-projects-on-snowflake-monitoring-202507/

最後に

dbt Projects on Snowflakeの初期セットアップ~一般的な開発&本番実行手順についてまとめてみました。

どなたかの参考になると幸いです!

この記事をシェアする

FacebookHatena blogX

関連記事