model groupsは、dbtプロジェクト内のリソース(models・snapshots・seeds・sourcesなど)に論理的な「所属」を与える仕組みです。access(public/protected/private)と併用することで、どこから参照できるかを静的に検証し、意図しない依存関係をCI段階で防げます。
本稿はdbt Coreのモデル・ガバナンス機能(groupsとaccess)を前提に、ドメイン境界の引き方、実装手順、移行、試験で問われやすいポイントをコンパクトにまとめます。公式ドキュメントに基づく安定的な挙動に絞って解説します。
groupは、プロジェクト内の論理的な境界(例: finance, marketing, sales)を表現する一級のメタデータです。リソースにgroupを割り当て、accessレベルを組み合わせることで、参照可否をコンパイル時に検証できます。これにより「どのチームの公開APIか」「どこが実装詳細か」を明文化できます。
試験観点では、groupsは境界、accessは境界をまたぐ参照制御、と押さえてください。特にprivate/protected/publicの違いと、group未設定時にprivateの効力が期待通りにならない点は取りこぼしがちです。
| Accessレベル | 参照できる範囲 | 代表的な用途 |
|---|---|---|
| private | 同一group内のみ | 実装詳細・中間モデル(破壊的変更を許容) |
| protected | 同一パッケージ内(groupをまたいで可) | 社内向け安定API(ドメイン内で再利用) |
| public | パッケージをまたいで可 | 組織横断の安定API(長期互換性を重視) |
group境界と参照の可否(→は許可、xは禁止)
Package: analytics
[Group: finance] [Group: marketing]
fin_base_customers (private) mkt_enriched_orders (protected)
^ ^
| |
| (allowed) | (allowed within package)
fin_kpi (protected) <------------------- mkt_rollups (protected)
^
|
external_pkg.model x (publicでないので禁止)
凡例:
- private: 同一group内のみ参照可
- protected: 同一パッケージ内は参照可、他パッケージ不可
- public: 他パッケージからも参照可最小のgroup定義とモデル側設定(YAML/SQL)
# groups/finance.yml
version: 2
groups:
- name: finance
owner:
name: Finance Analytics
email: [email protected]
description: 財務ドメインの分析資産
# models/finance/fin_base_customers.sql
-- このモデルはfinanceグループの内部実装(private)
{{
config(
group='finance',
access='private'
)
}}
select * from {{ ref('stg_customers') }}
推奨は「ドメインでgroupを切る」方式です。レイヤ(staging/intermediate/mart)とgroup(finance/marketingなど)は直交概念と捉えます。レイヤはディレクトリ・命名・タグで区別し、グループは「属するドメイン」を表現します。
スキーマ(データベースのschema)分割とgroupは目的が異なります。スキーマは実体の配置・権限管理、groupは論理的な依存境界です。SnowflakeやDatabricksなど物理実装に関わらず、groupはdbt内で一貫して機能します。
dbt_project.ymlでディレクトリ単位にgroup/アクセスを既定化
# dbt_project.yml(一例)
models:
analytics:
finance:
+group: finance
+access: private # デフォルトはprivate、公開が必要なものだけモデル側で昇格
marketing:
+group: marketing
+access: private
marts:
+materialized: table
dbtはrefの解決時に、参照先リソースのaccessとgroupを見て可否を判定します。不許可な参照はパース/ビルド時に即エラーとなり、実行前に失敗させられます。これにより境界違反の混入をCIで防止できます。
注意点として、group未設定のモデルにprivateを付けても「同一group内のみ」の制約が効きづらくなります。privateを使うなら、必ず全モデルにgroupを割り当てる方針に統一してください。
境界違反の例(marketing→finance privateへの参照)
# models/marketing/mkt_rollups.sql
{{
config(group='marketing', access='protected')
}}
-- NG: financeグループでprivateなモデルを参照
select *
from {{ ref('fin_base_customers') }}
-- 実行時イメージ(概略):
-- AccessError: Model 'fin_base_customers' is private to group 'finance' and cannot be referenced from group 'marketing'.段階的移行が安全です。まずgroupだけ定義してモデルに割り当て、CIで漏れを検出。次にaccessをprotectedで一律適用し、最後に内部実装をprivateへ落とし、公開が必要なものだけprotected/publicに昇格します。
依存の棚卸しにはdbt DAGやmanifest.jsonの解析が有効です。境界をまたぐ参照は、公開面(protected/public)に付け替えるか、ドメインの所在を見直します。
一律既定と段階的昇格の例
# dbt_project.yml(パッケージ既定)
models:
analytics:
+access: protected
# 内部実装(private)
{{ config(group='finance', access='private') }}
# 公開面(protected→必要ならpublicに昇格)
{{ config(group='finance', access='protected') }}
他パッケージから参照される可能性のあるモデルはpublicにします。protectedは同一パッケージ内の合意済みAPIとして運用し、パッケージをまたぐ場合はpublicの明示を求めます。
seedsやsnapshotsにもgroup/accessを付与できます。物理層(Snowflake/Databricks等)の権限は別途RDB/プラットフォーム側で管理し、dbtの論理境界と併用してください。
他パッケージからの参照(publicのみ許可)
-- package_b/models/use_finance.sql(package_bから参照)
select * from {{ ref('analytics', 'fin_published_kpi') }}
-- 参照先はanalyticsパッケージ側でpublicに設定
-- models/finance/fin_published_kpi.sql
{{ config(group='finance', access='public') }}
groupsは「境界の定義」、accessは「参照制御」。privateは同一group限定、protectedは同一パッケージ、publicはパッケージ横断、という順序で開放度が上がる点を確実に暗記してください。
group未設定のモデルにprivateを付けても期待する境界(同一group限定)が表現できない点、macrosはアクセス制御対象外、は誤りやすいポイントです。
要点おさらい(コメント付きYAML)
# 代表パターン
# internal/private(同一groupのみ)
{{ config(group='marketing', access='private') }}
# domain API/protected(同一パッケージ内の公開)
{{ config(group='marketing', access='protected') }}
# org-wide/public(他パッケージからも)
{{ config(group='marketing', access='public') }}
Analytics Engineer
問題 1
同一パッケージ内にfinanceとmarketingのgroupがあり、marketing側からfinanceの内部実装モデルを参照できないようにしたい。適切な設定はどれか?
正解: A
privateは同一group内のみ参照可。finance側をgroup='finance'かつaccess='private'にすると、marketing(別group)からのrefはビルド時にエラーになります。protectedは同一パッケージ内なら参照可なので要件を満たしません。
groupを定義しないとどうなりますか?
group未設定のままprivateを使うと「同一group限定」の境界が表せません。実務では全モデルにgroupを割り当てる方針に統一するのがおすすめです。
macrosにもaccessは適用されますか?
いいえ。accessはrefで解決されるリソース(models/snapshots/seeds/sourcesなど)に対する参照制御です。macrosは別の再利用メカニズムで、アクセス制御の対象外です。
パッケージをまたいだ参照を許可したい場合は?
参照される側のモデルをaccess='public'にします。protectedは同一パッケージ内のみ有効で、他パッケージからは参照できません。後方互換性と変更通知の運用も合わせて設計してください。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
dbt Model の基礎: SQL で定義する変換の最小単位
Analytics Engineer 向けに、dbt Model の定義、マテリアライゼーション、依存関係、インクリメン...
dbt Analytics Engineer 試験ガイド: 出題範囲・配点・申込の実務視点
dbt Analytics Engineer 認定の出題範囲、配点の考え方、申込から受験までの流れを、公式ドキュメントの...
dbt Cloud と dbt Core の違いと選び方:Analytics Engineer 試験に効く要点
dbt Cloud と dbt Core の機能差を、実務と資格対策の両面から整理。スケジューリング、IDE、RBAC、...
dbt プロジェクト構造ガイド: models / seeds / macros の実務レイアウト
Analytics Engineer 向けに、dbt プロジェクトのディレクトリ構造と命名規約、dbt_project....
dbt_project.yml の読み方:主要設定と命名を最短で掴む
dbt_project.yml の必須キー、命名解決(database.schema.identifier)、設定優先度...