📜

dbtモデルのdescriptionの一元管理

2024/08/26に公開

ユースケース

  • 異なるモデルで、同じdescriptionを使うような場合
  • それぞれ別のスキーマ定義をしていると、もしdescriptionが変更された場合、すべてのスキーマ定義を変更する必要がある

対処方法

schema.ymlに直接descriptionをベタ書きせず、markdownファイルにdocsブロックを切り出して参照する。

環境

以下の検証は、dbt-coreの1.8.4で行っています

dbtプロジェクトが1つの場合

以下のようなモデルを例に考えます。

以下のようなフォルダ構成とします。

<dbtプロジェクトディレクトリ>/
  ├ models/
    ├<各種モデルファイル>
    ├docs.md
    ├source.yml
    ├schema.yml
  ...
  • 公式によると、「デフォルトでは、dbtはdocsブロックをすべてのリソースパス(model-paths、seed-paths、analysis-paths、macro-paths、snapshot-pathsの複合リスト)のmdファイルが検索対象」のようです

  • それぞれのファイルの記載内容は、以下のように記述します

    • docsで使用するタグ名は、重複しなければ、何でもよいです
    • テーブルの場合は、"table__<テーブル名>"、カラムの場合は、"column__<テーブル名>__<カラム名>"としています
stg_customers.sql
with source as (
    select * from {{ source('dev', 'raw_customers') }}

),

renamed as (

    select
        id as customer_id,
        first_name,
        last_name

    from source

)

select * from renamed
docs.md
{% docs table__raw_customers %}
顧客テーブル
{% enddocs %}
{% docs column__raw_customers__id %}
顧客テーブルの主キー
{% enddocs %}
{% docs column__raw_customers__first_name %}
顧客名
{% enddocs %}
{% docs column__raw_customers__last_name %}
顧客姓
{% enddocs %}
source.yml
version: 2

sources:
  - name: dev
    schema: landing
    tables:
      - name: raw_customers
        description: '{{ doc("table__raw_customers") }}'
        columns:
          - name: id
            description: '{{ doc("column__raw_customers__id") }}'
          - name: first_name
            description: '{{ doc("column__raw_customers__first_name") }}'
          - name: last_name
            description: '{{ doc("column__raw_customers__last_name") }}'
schema.yml
version: 2

models:
  - name: stg_customers
    description: '{{ doc("table__raw_customers") }}'
    columns:
      - name: customer_id
        description: '{{ doc("column__raw_customers__id") }}をリネームしたもの'  # タグ + 追加文字のような形でも使える
      - name: first_name
        description: '{{ doc("column__raw_customers__first_name") }}'
      - name: last_name
        description: '{{ doc("column__raw_customers__last_name") }}'

dbtプロジェクトが複数に分かれている場合

  • 蓄積のみを行うプロジェクト、加工を行うプロジェクトのように用途ごとにdbtプロジェクトを分けているケース

  • 本体のdbtプロジェクトとは別に、マークダウンを保持するためのdbtプロジェクトを作成する

  • そのプロジェクトをパッケージとして、本体のプロジェクトのpackages.ymlに記載して使用する

  • 以下のようなフォルダ構成とします

<本体のdbtプロジェクトディレクトリ>/
  ├packages.yml
  ├ models/
    ├<各種モデルファイル>
    ├source.yml
    ├schema.yml
  ...

<description切り出し用dbtプロジェクトディレクトリ>/
  ├ models/
    ├docs.md
  ...
  • 参照したい本体ののプロジェクトには、以下のようなpackages.ymlを配置する
packages.yml
packages:
  - local: ../description_project  ## 相対パスでdescriptionを配置するプロジェクトを指定

dbt docs上での反映を確認

  • いずれの方法でも、dbt docsでmdファイルからのdescriptionが見れることを確認

追記

(2024/08/30)
1.6以降で使用できる、project dependencies(いわゆるマルチプロジェクト?)でも行けるかと思っが、こちらはdbt Cloudの Enterprise版のみで使える模様。
https://docs.getdbt.com/docs/collaborate/govern/project-dependencies#prerequisites

Discussion