dbt platform で dbt-snowflake の table_tag config を試してみる
はじめに
dbt-snowflake のtable_tag configを使用すると、dbt が作成するテーブルやビューに対して Snowflake のオブジェクトタグを付与することが可能です。
こちらの機能を試してみた内容を本記事でまとめます。
table_tag config
本機能については以下に記載があります。
dbt で作成するモデル(table / view / dynamic table)に対して、Snowflake のオブジェクトタグを configから指定できる機能となります。これにより、データガバナンス・コスト管理・データ分類などに使用するタグを、dbt のコードベースから一元的に管理できます。
設定箇所として、以下の3パターンに対応しています。
- モデルの SQL ファイル内の
{{ config() }}ブロック - Properties YAML(
schema.yml等)のconfig:配下 dbt_project.ymlの+table_tag:(ディレクトリ単位での一括適用)
優先順位は dbt の標準ルールに従い、SQL config > Properties YAML > dbt_project.ymlの順となります。
試してみる
前提条件
以下の環境を使用しています。
- dbt
- dbt platform
- 開発環境、デプロイメント環境いずれも Fusion Stable リリーストラック
サンプルデータとして、公式のクイックスタートから利用できるjaffle_shopのデータを使用しています。
検証開始時点で、以下のリネージが構成されています。

models ディレクトリとdbt_project.ymlは以下の構成としました。
models
├── customers.sql
└── staging
├── stg_customers.sql
└── stg_orders.sql
models:
my_new_project:
+materialized: table
staging:
+materialized: view
Snowflake 側でタグを作成
table_tag configで指定するタグは、あらかじめ Snowflake 側で作成されている必要があります。検証用のタグとタグ管理用のスキーマを作成します。
USE ROLE SYSADMIN;
CREATE DATABASE IF NOT EXISTS MANAGE_DB;
CREATE SCHEMA IF NOT EXISTS MANAGE_DB.TAGS;
-- タグを作成
CREATE TAG IF NOT EXISTS MANAGE_DB.TAGS.MY_TEST_TAG;
>SHOW TAGS IN SCHEMA MANAGE_DB.TAGS;
+-------------------------------+-------------+---------------+-------------+----------+
| created_on | name | database_name | schema_name | owner |
|-------------------------------+-------------+---------------+-------------+----------|
| 2026-05-07 15:50:20.146 -0700 | MY_TEST_TAG | MANAGE_DB | TAGS | SYSADMIN |
+-------------------------------+-------------+---------------+-------------+----------+
続けて、dbt の実行ロールに対してタグのAPPLY権限を付与します。
USE ROLE SECURITYADMIN;
GRANT USAGE ON DATABASE MANAGE_DB TO ROLE <DBT_ROLE>;
GRANT USAGE ON SCHEMA MANAGE_DB.TAGS TO ROLE <DBT_ROLE>;
GRANT APPLY ON TAG MANAGE_DB.TAGS.MY_TEST_TAG TO ROLE <DBT_ROLE>;
Properties YAMLでの設定
ここではまず、モデルの Properties YAML(schema.ymlを用意)での指定を試してみます。
models/schema.ymlにconfig:配下でtable_tagを追加します。
models:
- name: stg_customers
config:
table_tag: "MANAGE_DB.TAGS.MY_TEST_TAG = 'test_value'"
columns:
- name: customer_id
data_tests:
- unique
- not_null
dbt run --select stg_customersを実行後、TAG_REFERENCESで確認します。
>SELECT *
FROM TABLE(
ANALYTICS.INFORMATION_SCHEMA.TAG_REFERENCES(
'ANALYTICS.DBT_TYASUHARA.STG_CUSTOMERS',
'TABLE'
)
);
+--------------+------------+-------------+------------+-------+-----------------+---------------+---------------+--------+-------------+--------------+
| TAG_DATABASE | TAG_SCHEMA | TAG_NAME | TAG_VALUE | LEVEL | OBJECT_DATABASE | OBJECT_SCHEMA | OBJECT_NAME | DOMAIN | COLUMN_NAME | APPLY_METHOD |
|--------------+------------+-------------+------------+-------+-----------------+---------------+---------------+--------+-------------+--------------|
| MANAGE_DB | TAGS | MY_TEST_TAG | test_value | TABLE | ANALYTICS | DBT_TYASUHARA | STG_CUSTOMERS | TABLE | NULL | MANUAL |
+--------------+------------+-------------+------------+-------+-----------------+---------------+---------------+--------+-------------+--------------+
TAG_VALUEが YAML 側で指定したtest_valueになっており、Properties YAML 経由で正しく適用されていることが確認できました。
参考までに、dbt が生成した DDL は以下のとおりで、WITH TAG (...)句がオブジェクト作成時点で付与されています。
create or replace view ANALYTICS.DBT_TYASUHARA.STG_CUSTOMERS(
CUSTOMER_ID,
FIRST_NAME,
LAST_NAME
) WITH TAG (MANAGE_DB.TAGS.MY_TEST_TAG='test_value')
as (
SELECT
id AS customer_id,
first_name,
last_name
FROM raw.jaffle_shop.customers
)
/* {"app": "dbt", "dbt_version": "2.0.0", "node_id": "model.my_new_project.stg_customers", "profile_name": "user", "target_name": "dev"} */;
Snowsight からも、テーブルのタグ情報として確認できます。

dbt_project.ymlでのディレクトリレベル一括設定
次に、dbt_project.ymlからディレクトリ単位でtable_tagを一括適用してみます。あわせて、Properties YAML 側の設定とディレクトリ設定が共存した場合の優先順位も確認します。
dbt_project.ymlのstaging:配下に+table_tagを追加します。
models:
my_new_project:
+materialized: table
staging:
+materialized: view
+table_tag: "MANAGE_DB.TAGS.MY_TEST_TAG = 'dir_value'"
stg_customersは先の Properties YAML でのtest_valueをそのまま残し、stg_ordersは個別設定なしの状態で実行します。
dbt run --select "stg_customers stg_orders"
両モデルのタグを確認します。
>SELECT 'stg_customers (view)' AS object, TAG_NAME, TAG_VALUE, APPLY_METHOD
FROM TABLE(ANALYTICS.INFORMATION_SCHEMA.TAG_REFERENCES('ANALYTICS.DBT_TYASUHARA.STG_CUSTOMERS', 'TABLE'))
UNION ALL
SELECT 'stg_orders (view)' AS object, TAG_NAME, TAG_VALUE, APPLY_METHOD
FROM TABLE(ANALYTICS.INFORMATION_SCHEMA.TAG_REFERENCES('ANALYTICS.DBT_TYASUHARA.STG_ORDERS', 'TABLE'));
+-----------------------+-------------+------------+--------------+
| OBJECT | TAG_NAME | TAG_VALUE | APPLY_METHOD |
|-----------------------+-------------+------------+--------------|
| stg_customers (view) | MY_TEST_TAG | test_value | MANUAL |
| stg_orders (view) | MY_TEST_TAG | dir_value | MANUAL |
+-----------------------+-------------+------------+--------------+
確認できた点は以下のとおりです。
stg_orders(個別設定なし):dbt_project.ymlのディレクトリ設定dir_valueを継承stg_customers(Properties YAML でtest_value設定済み):ディレクトリ設定を上書きしてtest_valueを維持
優先順位がProperties YAML > dbt_project.ymlの順で機能していることが確認できました。
なお、ここで個別設定(stg_customersのconfig:ブロック)を削除し再実行すると、stg_customersもディレクトリ設定のdir_valueを継承するようになり、両モデルが一律のタグ値となります。
複数タグの併用
table_tagでも、Snowflake のALTER TABLE ... SET TAG tag1=v1, tag2=v2構文と同様にカンマ区切りで複数タグを指定することが可能です。
事前準備として、もう1つタグを作成します。
USE ROLE SYSADMIN;
CREATE TAG IF NOT EXISTS MANAGE_DB.TAGS.MY_TEST_TAG_2;
USE ROLE SECURITYADMIN;
GRANT APPLY ON TAG MANAGE_DB.TAGS.MY_TEST_TAG_2 TO ROLE DEV_DBT_ROLE;
models/schema.ymlのtable_tagをカンマ区切りに変更します。
models:
- name: stg_customers
config:
table_tag: "MANAGE_DB.TAGS.MY_TEST_TAG = 'multi_v1', MANAGE_DB.TAGS.MY_TEST_TAG_2 = 'multi_v2'"
dbt run --select stg_customersを実行後、TAG_REFERENCESで確認します。
>SELECT OBJECT_NAME, TAG_NAME, TAG_VALUE
FROM TABLE(
ANALYTICS.INFORMATION_SCHEMA.TAG_REFERENCES(
'ANALYTICS.DBT_TYASUHARA.STG_CUSTOMERS',
'TABLE'
)
);
+---------------+---------------+-----------+
| OBJECT_NAME | TAG_NAME | TAG_VALUE |
|---------------+---------------+-----------|
| STG_CUSTOMERS | MY_TEST_TAG | multi_v1 |
| STG_CUSTOMERS | MY_TEST_TAG_2 | multi_v2 |
+---------------+---------------+-----------+
両タグが正しく付与されていることが確認できました。

post-hookの使用
table_tag config以外に、post-hookからALTER TABLE/VIEW ... SET TAGを実行することでもタグを付与できます。条件分岐を含むより柔軟なタグ管理を行いたい場合は、こちらも選択肢となり得ます。
dbt_project.ymlのプロジェクトレベルに+post-hookを追加します。Snowflake のALTER文はオブジェクト型ごとに構文が異なるため、config.get('materialized')で TABLE / VIEW を分岐します。
models:
my_new_project:
+materialized: table
+post-hook:
- "ALTER {{ 'VIEW' if config.get('materialized') == 'view' else 'TABLE' }} {{ this }} SET TAG MANAGE_DB.TAGS.MY_TEST_TAG = 'post_hook_value'"
staging:
+materialized: view
事前にこれまでのtable_tag設定(モデル個別 / ディレクトリレベルとも)はすべて削除しておきます。dbt run実行後、複数モデルのタグを確認します。
SELECT 'customers (table)' AS object, TAG_NAME, TAG_VALUE, APPLY_METHOD
FROM TABLE(ANALYTICS.INFORMATION_SCHEMA.TAG_REFERENCES('ANALYTICS.DBT_TYASUHARA.CUSTOMERS', 'TABLE'))
UNION ALL
SELECT 'stg_customers (view)' AS object, TAG_NAME, TAG_VALUE, APPLY_METHOD
FROM TABLE(ANALYTICS.INFORMATION_SCHEMA.TAG_REFERENCES('ANALYTICS.DBT_TYASUHARA.STG_CUSTOMERS', 'TABLE'))
UNION ALL
SELECT 'stg_orders (view)' AS object, TAG_NAME, TAG_VALUE, APPLY_METHOD
FROM TABLE(ANALYTICS.INFORMATION_SCHEMA.TAG_REFERENCES('ANALYTICS.DBT_TYASUHARA.STG_ORDERS', 'TABLE'));
+----------------------+-------------+-----------------+--------------+
| OBJECT | TAG_NAME | TAG_VALUE | APPLY_METHOD |
|----------------------+-------------+-----------------+--------------|
| customers (table) | MY_TEST_TAG | post_hook_value | MANUAL |
| stg_customers (view) | MY_TEST_TAG | post_hook_value | MANUAL |
| stg_orders (view) | MY_TEST_TAG | post_hook_value | MANUAL |
+----------------------+-------------+-----------------+--------------+
table / view の両マテリアライゼーションに対して、dbt_project.yml1箇所の設定で均一にタグを適用できることが確認できました。
デプロイメント環境での実行
ここまでは開発環境での実行でした。続けて、デプロイメント環境(dbt platform のジョブ)で同じ内容を実行した際の挙動を確認します。
dbt-fusion のデプロイメント環境では State-aware Orchestration を有効化できます。これは前回ビルド時の状態と差分のあるモデルのみをリビルド対象とする機能で、無駄な再実行を抑える効果がある一方、table_tagをどこに記述するかによって変更検知の挙動が異なる点に注意が必要でした。
Properties YAML / dbt_project.ymlの値だけを変更した場合
Properties YAML やdbt_project.ymlのtable_tagの値だけを変更した状態で State-aware Orchestration を有効化したジョブを実行したところ、対象モデルが変更として検知されず、Snowflake 側のタグは更新されませんでした。
参考までに、データソース側を変更した場合(例:raw.jaffle_shop.customersへ1行追加)は、モデルが変更として再実行されるためタグも反映されます。
INSERT INTO raw.jaffle_shop.customers (id, first_name, last_name)
VALUES (9999, 'Taro', 'Yamada');


モデル SQL の{{ config() }}で値を変更した場合
一方、モデル SQL ファイル内の{{ config(table_tag=...) }}で値を変更した場合は、データソース側の変更がなくてもモデルの変更として検知され、タグも更新されました。
{{ config(
table_tag="MANAGE_DB.TAGS.MY_TEST_TAG = 'orders_value'"
) }}
select
id as order_id,
user_id as customer_id,
order_date,
status
from {{ source('jaffle_shop', 'orders') }}


まとめると、モデル SQL ファイル内の{{ config() }}はコンパイル後の SQL に影響するため変更として検知される一方、外部 YAML での設定変更はモデル定義の差分として認識されず、State-aware Orchestration ではスキップされる挙動となっていました。
これらの機能を使用する場合、少なくとも以下の観点で考慮が必要と思います。
- タグ値の変更を即座に Snowflake へ反映したい場合:モデル SQL ファイルの
{{ config() }}で記述する - YAML 集中管理を優先しつつ、反映が次回データ更新時まで遅れることを許容する場合:Properties YAML /
dbt_project.ymlで記述する
さいごに
簡単ではありますが、dbt-snowflake のtable_tag configを試してみました。
こちらの内容がどなたかの参考になれば幸いです。









