が として強い理由は `schema.yml` の description + `dbt docs generate` で lineage グラフ + 説明が web で見えること。「このテーブルって何?」問い合わせは、これがあるだけで激減します。
schema.yml の充実
version: 2
models: - name: fct_orders description: | 確定済みの注文 (キャンセル・返金後の最終状態)。
**粒度**: 1 行 = 1 注文 **更新**: 毎時 00 分に incremental **下流**: BI ダッシュ ("売上 - 月次"), マーケ施策効果計測
過去事象: - 2027-08: 返金処理を別行に分離 (revenue_amount を導入) config: meta: owner: "team:commerce@hukuhuku.co.jp" sla_hours: 6 published: true # Bot に公開するか contains_pii: false columns: - name: order_id description: | 注文の一意識別子。UUID 形式 (例: 'a1b2c3...')。 冪等な操作のキーとして使う。 tests: - unique - not_null
- name: customer_id description: "顧客 ID (dim_customers への FK)。匿名注文は 0" tests: - not_null - relationships: to: ref('dim_customers') field: customer_id
- name: amount_jpy description: | 注文金額 (JPY、税込)。 負の値は禁止 (キャンセル分は別行で revenue_amount をマイナス計上)。 tests: - dbt_expectations.expect_column_values_to_be_between: min_value: 0
- name: ordered_at description: "注文時刻 (UTC、ISO 8601)"doc block で長い説明を再利用
{% docs customer_id_desc %}顧客 ID。dim_customers.customer_id への外部キー。- 匿名注文: 0- テストアカウント: -1- マイグレーション中の暫定値: -2 (2027/01 までに完了予定){% enddocs %}
{% docs amount_jpy_desc %}注文金額 (JPY、税込)。返品・キャンセル分は別行で減算。※ 米ドル等の場合は ordered_at 時点のレートで JPY 換算済み。{% enddocs %}columns: - name: customer_id description: "{{ doc('customer_id_desc') }}" - name: amount_jpy description: "{{ doc('amount_jpy_desc') }}"dbt docs の生成と公開
dbt docs generate # target/ にメタデータ HTML 生成dbt docs serve # localhost:8080 で確認dbt docs serve --no-browser --port 8888 # ブラウザ自動起動なし生成された HTML を社内に公開するには、`target/` ディレクトリを GCS / S3 / Vercel に上げる。dbt Cloud なら自動で web 公開される。
CI で description 必須化
メタデータは「強制しないと書かれない」。CI で description 必須をチェックする workflow を入れると、PR 時に「説明書いてないよ」と弾かれる。最初に痛い思いをするが、3 ヶ月後には全員が当たり前に書くようになる。
name: dbt metadata coverageon: [pull_request]
jobs: meta-coverage: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: pip install dbt-bigquery==1.8.* - run: dbt deps && dbt parse - name: Check column descriptions on published models run: | python -c " import json m = json.load(open('target/manifest.json')) missing = [] for n, node in m['nodes'].items(): if node['resource_type'] != 'model': continue if not node.get('config', {}).get('meta', {}).get('published'): continue for c, cfg in node['columns'].items(): if not cfg.get('description'): missing.append(f\"{node['name']}.{c}\") if missing: print('Missing descriptions:', missing) exit(1) "exposures: ダッシュ参照を宣言
model がどの BI ダッシュ・どの パイプラインで使われているかを `exposures` として宣言すると、lineage に下流アプリが描かれる。「この model 削除しても大丈夫?」の判断材料に。
exposures: - name: weekly_revenue_dashboard type: dashboard url: https://lookerstudio.google.com/... owner: email: bi-team@hukuhuku.co.jp description: "週次経営会議で使う売上ダッシュ" depends_on: - ref('fct_revenue_daily') - ref('dim_customers')
- name: churn_prediction_model type: ml description: "解約予兆 ML モデル (週次で再学習)" depends_on: - ref('fct_user_events') - ref('dim_customers')次の話
EP.08 では Jinja マクロで を再利用する技術を扱います。
この記事の感想を教えてください
あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。