以下の内容はhttps://nealle-dev.hatenablog.com/entry/2025/06/25/170835より取得しました。


データカタログを社内公開するためにdbtソース定義ファイルを作った話

はじめに

こんにちは、Analyticsチームの清水です。 ガーゴイルゲッコーというヤモリ(8歳)とサイベリアン(1歳4ヶ月)を飼っています。とってもかわいいです。

バナナを食べています(左)ビーズクッション占領猫(右)

前回のブログでは、dbtのデータカタログ機能を使ってみた話を書かせていただきました。 nealle-dev.hatenablog.com

その後、社内でよく参照されているトップ50テーブルのソース定義ファイルを作成し、無事にデータカタログを公開できました🙌

今回は、前回さらっと触れた「50テーブルのソース定義ファイルをどうやって迅速に作成したか」についてご紹介します。 同じようにデータカタログの整備を進めている方のご参考になれば幸いです。

ソース定義ファイルとは?

ソース定義ファイルは、テーブルやカラムに関する定義、説明、そしてデータ品質テストなどを記述するYAML形式のファイルです。以下に、生成AIに出力してもらった具体例を示します。

version: 2

sources:
  - name: ec_site # ソースのグループ名。任意の名前をつけられます。
    description: "ECサイトのプロダクションデータベース(レプリカ)"
    
    # 接続するデータベースやスキーマをここで指定します。
    # プロジェクト全体でdatabaseを統一している場合は省略可能です。
    # database: "your_database_name" 
    schema: raw
    
    # このソースグループに属するテーブルを定義します
    tables:
      - name: users # DB上の実際のテーブル名
        description: "サイトのユーザー情報を持つテーブル"

        # テーブルの鮮度(freshness)をチェックするための設定
        # loaded_at_field: "updated_at" # データがロードされた日時を示すカラム
        # freshness:
        #   warn_after: {count: 12, period: hour} # 12時間以上更新がなければ警告
        #   error_after: {count: 24, period: hour} # 24時間以上更新がなければエラー

        # カラムの定義
        columns:
          - name: user_id
            description: "ユーザーの一意なID"
            tests:
              - unique # このカラムの値は一意であるべき
              - not_null # このカラムの値はNULLであってはならない

          - name: user_name
            description: "ユーザー名"
            tests:
              - not_null

          - name: email
            description: "メールアドレス"
            tests:
              - unique
              - not_null
              # 正規表現に一致するかをチェックするdbt_utilsのテスト例
              # - dbt_utils.expression_is_true:
              #     expression: "regexp_contains(email, r'^[^@]+@[^@]+\\.[^@]{2,}$')"

          - name: created_at
            description: "アカウント作成日時"
            tests:
              - not_null

          - name: updated_at
            description: "最終更新日時"

この例のように、テーブル定義書レベルの情報であれば、DBやDWHから情報を取得して自動生成できそうです。
一方でdescriptionは自動生成できるものではない*1ので、ここをどうするかが重要です。

作成方法の詳細は後述ですが、ざっくり以下の流れとなっています。

  1. 自動生成機能によりyamlの雛形を作る
  2. 既存のデータベースドキュメントを構造化し論理カラム名や説明のコンテキストを作成(ここは一般的でなく弊社事情によるところが大きいため割愛します)
  3. コンテキストとテンプレート化したプロンプトをインプットにAI Agentにソース定義ファイルを完成させる

ソース定義ファイルはなぜ作る?

dbtにおいてソース定義ファイルを作成する目的は以下の通りに考えています。

  • 生のテーブルにドキュメント(説明)を付ける
  • データ品質テストを実行する
  • データの鮮度(Freshness)をチェックする
  • モデルから source() 関数で参照できるようにする

特にデータカタログ整備の観点からみると、「生のテーブルにドキュメント(説明)を付ける」が重要だと考えています。

実は最近、弊社のRedashでLoad Schema機能が使えなくなり、テーブルやカラムの一覧を確認できるだけでも、SQLを書く利用者にとっては価値のある状況でした。

RedashのLoad Schema

それはさておき、テーブルやカラムの説明をデータカタログで簡単に確認できるようにすることで、分析に必要なデータの有無を判断したり、生成AIへのインプットとして活用したりできます(説明の有無は、生成AIの出力精度に大きく影響します)。

これにより、SQLが得意ではない利用者でも、Analyticsチームに依頼することなく、生成AIを使って自らSQLを作成できる、そんな世界を実現できる可能性があります。 (現に公開したデータカタログとGeminiを使って自分で分析クエリを作成できた、という嬉しい声も届いています🙌)

このような意義から、私たちはソース定義ファイルを量産することにしました。

yamlの生成

ここからが本題です。データソース(弊社の場合データ基盤であるBigQuery)にアクセスしてソース定義ファイルに雛形を生成します。

ソース定義ファイルの生成にはcodegenというパッケージを利用します。(もちろんモデル定義の生成も可能) 利用までの流れを以下に示します。

  1. dbtプロジェクト配下にあるpackages.ymlに以下を追記します。(なければ作成)

     packages:
       - package: dbt-labs/codegen
         version: 0.13.1
    
  2. dbt depsを実行し、宣言したパッケージをインストールします。

  3. generate_sourceコマンドを実行します。

dbt -q run-operation generate_source --args '{"schema_name": "<データセット名>", "table_names": ["<テーブル名>"], "generate_columns": true, "include_data_types": true}'

generate_source(or generate_model_yaml)の他のオプションなど詳細は以下を参照ください。

github.com

Tips:qオプション(--quiet)をつけるとyamlだけが出力されますので、そのままリダイレクトさせることで直接yamlファイルを生成することができます。

ここまでの手順では前述のサンプルをベースに表現すると、以下のようなyamlファイルが生成された状態になります。

version: 2

sources:
  - name: ec_site 
    description: ""
    
    schema: raw
    
    tables:
      - name: users
        description: ""

        columns:
          - name: user_id
            description: ""

          - name: user_name
            description: ""

          - name: email
            description: ""

          - name: created_at
            description: ""

          - name: updated_at
            description: ""

テーブル説明・カラム説明の追加

ここまでできれば、あとはテーブル説明やカラム説明をyamlに追記するだけですね。

説明についてはソースコードから生成されたドキュメントが構造化されていない状態でConfluenceにありまして、これをAPIで取得しHTMLをパースしてかなり強引に構造化するPythonスクリプトを作りました。その結果をインプットとします。 具体的には、下記のような内容です。(値の説明にはカテゴリカルな値を持つカラムの場合、それぞれの値ごとの説明が入ります。)

モデル,クラス,テーブル,物理カラム,論理カラム,値の説明
./apps/ec/models.py,EcUsers,users,user_id,ユーザーの一意なID,
./apps/ec/models.py,EcUsers,users,user_name,更新日時,ユーザー名
./apps/ec/models.py,EcUsers,users,email,メールアドレス,
./apps/ec/models.py,EcUsers,users,created_at,アカウント作成日時,
./apps/ec/models.py,EcUsers,users,updated_at,最終更新日時,

あとは、下記のようなテンプレのプロンプトを作成して、コンテキストに前述の構造化したドキュメントを設定し、AI Agentに依頼すれば完了です。

やってほしいこと

このあと対象指定するdbtのソース定義yamlにテーブル説明およびカラム説明を追記してください。

追記対象

foo/var.yml

カラム説明

コンテキストにあるoutput.csvからfoo/var.ymlにある情報をもとに探索してください。 説明改行が含まれている場合はdescriptionにも反映してください。

おわりに

今回は、ソース定義ファイルを作成する方法の一例をご紹介しました。 もちろん同様の方法でモデルの定義ファイルも量産可能です。

最終的にはテーブルやカラムの追加や変更を完全に自動で追従できる姿が理想ですが、 まずはクイックに使ってもらえるデータカタログを公開しようということで、暫定的には良い方法なのかなと思います。

今後もデータマートやデータカタログを継続的に改善し、また皆様に共有できればと思います! お読みいただき、ありがとうございました。

*1:DBやDWHに既にテーブル説明やカラム説明のフィールドが埋まっていれば問題ありません。弊社のデータ基盤だとそういったメタデータが入っていない状態でした。




以上の内容はhttps://nealle-dev.hatenablog.com/entry/2025/06/25/170835より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14