[dbt] 作成するデータモデルに関するドキュメントを生成する

文書は(書くのが)面倒だが役に立つ
2021.01.14

大阪オフィスの玉井です。

dbtはSQLだけで柔軟なデータ変換を作ることが出来ますが、作成したデータモデルに関するドキュメントを(結構キレイめな感じで)生成することができます。

ドキュメンテーションの重要性

システム開発の世界において、ドキュメンテーションがいかに重要か、というのを疑う人は少ないと思います。アジャイル開発でもドキュメントは重要です。最近では、ツールを駆使して、ドキュメンテーションをCI/CDに組み込んでいるプロジェクトもあるかと思います。

dbtはこの考えを取り込んでいます。作成するデータモデルに対するドキュメントを簡単に作成することができるようになっています。生成したドキュメントは、Webブラウザで閲覧することが可能です。

やってみた

環境

  • macOS Catalina 10.15.7
  • dbt CLI 0.18.1

基本はdbt docs

先に言ってしまうと、dbt docs generateというコマンドを使用すれば、そのdbtプロジェクトに関するドキュメントが生成されます。

ただ、場合によっては、作成したデータモデルに関する説明とか、特定のカラムに対して特別な説明を書きたい、みたいな要件が出てくると思います。

ですので、今回はそこもやって上でドキュメントを生成したいと思います。

YAMLファイルにdescriptionを追加する

一番手っ取り早いのは、modelsディレクトリ下にあるYAMLファイル(テストを記述したファイル)に対して、descriptionというパラメータを定義する方法です。その名の通り、モデルに対して「説明」を書くことが出来ます。カラム単位でも書けます。

例えば下記のような形です。

models:
    - name: stg_customers
      description: "顧客テーブルをステージング化したもの"
      columns: 
        - name: customer_id
          tests:
            - unique
            - not_null
    - name: stg_orders
      description: "注文データをステージング化したもの"
      columns: 
        - name: order_id
          tests:
            - unique
            - not_null

ここのdescriptionに定義した文章が、後々生成するドキュメントに反映されます。ちなみに、私が検証したところ、2バイト文字(日本語など)は、ダブルコーテーションで囲まないと反映されませんでした(英文だったら囲み無しでいけた)。

もう少し凝ったドキュメントをMarkdownで別出し

先程の方法は簡単ですが、単にテキストをだらだら書く方法なので、込み入った説明文を書くのには不向きです。そういうときは、別途Markdownでドキュメントを書いて、それをYAMLファイルから参照する形をとります。

YAMLファイルと同じ階層に、Markdownファイルを用意します。ポイントは最初と最後の行です。

{% docs order_status %}

それぞれの値の意味: 

| status         | definition                                       |
|----------------|--------------------------------------------------|
| placed         | 注文されたが、まだ未出荷                             |
| shipped        | 出荷されたが、まだ未配達                             |
| completed      | 商品が配達された                                    |
| return pending | 顧客が返品希望                                     |
| returned       | 返品された                                         |

{% enddocs %}

そして、YAMLファイルに、このMarkdownファイルを参照させます。文章を見れば分かると思いますが、これは注文データのstatusというカラムに関する説明ですので、そこに定義します。

...

    - name: stg_orders
      description: 注文データをステージング化したもの
      columns: 
        - name: order_id
          tests:
            - unique
            - not_null
        - name: status
          description: '{{ doc("order_status") }}'
          tests:
            - accepted_values:
                values:
                  - completed
                  - shipped
                  - returned
                  - placed
                  - return_pending

...

Markdown側で「ここからここまでをdocsの対象にしますよ」と定義して、その時の定義名をYAMLファイルに参照先として記述する形です。

ドキュメントを生成する(そして閲覧する)

準備が整ったところで、実際にドキュメントを生成してみます、まずはdbt docs generateを実行します。

$ dbt docs generate
Running with dbt=0.18.1
Found 5 models, 7 tests, 0 snapshots, 0 analyses, 155 macros, 0 operations, 0 seed files, 0 sources

12:26:29 | Concurrency: 4 threads (target='learn')
12:26:29 |
12:26:29 | Done.
12:26:29 | Building catalog
12:26:35 | Catalog written to /Users/tamai.rei/<プロジェクト名>/target/catalog.json

ドキュメントが生成されたので、それをローカルで参照します。dbt docs serveでドキュメントを起動します。

$ dbt docs serve
Running with dbt=0.18.1
Serving docs at 0.0.0.0:8080
To access from your browser, navigate to:  http://localhost:8080
Press Ctrl+C to exit.

この時点で、自動でWebブラウザに飛ばされます。そして、dbtプロジェクトのドキュメントを閲覧することができます。

dbtプロジェクトの全体像が反映されていますね。

顧客データに付与したdescriptionも反映されています。

Markdownで作成した、statusカラムに関する部分です。

ドキュメントいろいろ

テストもドキュメント化されます。コンパイル後のテストクエリも参照できます。

DAGも見れます。dbtはデータ変換処理をモジュール化しながら開発していくのが特徴ですが、「このモデルは、どのモデルから生成されているのか」が一目でわかるので便利です。

おわりに

苦労して作ったデータマートって、後から見返した時、「あれ、このカラムってどっから持ってきたんだっけ…」とか「この値ってどうやって計算して算出してるんだ…」ってなりがちですよね。dbtはそこらへんをチョロっと書いておけば、後はキレイなドキュメントが生成されるので便利です。こちらもコマンドで生成されるので、CI/CDにも組み込めると思います。