dbt exposuresでダッシュボードにどのテーブルが使われているか可視化してみた

## はじめに
こんにちは、株式会社ビットキーのData Analyticsチームの生田です。

私は今年（2023年）の7月に今のチームにジョインし、アナリティクスエンジニアとしてのキャリアをスタートしました。
<br>
この半年間で、dbt[^1]でクエリをガシガシ書いてテーブルをたくさん作ったり、そのテーブルを基にダッシュボードを作るなど、充実したアナリティクスエンジニアライフを過ごしてきたわけですが、

テーブルをたくさん作ったことで、
> **どのテーブルがどのダッシュボードに使われているかわからない**

という課題がでてきました。
<br>
今回は、テーブルを量産していった結果「このテーブルって何に使われてたっけ？」という課題を、dbtの**exposures**という機能で解決したことについてまとめました。



[^1]:dbtとは、SQLのみを用いてデータを処理・変換し、テーブル（データウェアハウスやデータマートなど）を構築することができるツールです。


## dbt exposuresを使うとこんな事ができます！
dbtでは、「〇〇テーブルは▲▲テーブルから抽出されている」などのテーブル間の依存関係を見ることができます。

ここに**exposures**機能を追加することで、テーブル間の関係だけでなく、テーブルがどのアウトプットに使われているかを可視化する事ができます。

具体的には、下図のようなリネージュをdbtで見れるようになります。

![Untitled (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516499/f7461d89-aaea-d959-43a3-7b7f2d257ff4.png)


以降でやり方を説明していきます。



## dbtのexposuresを実装していく

ということで、dbtのexposures機能を実装していきます。

工程はこの２つ。かなり簡単でした。

1. ymlファイルにダッシュボードとテーブルの依存関係を書き込む
2. コマンドを叩いて実行

### 1. ymlファイルにダッシュボードとテーブルの依存関係を書き込む

やることは単純で、ymlファイルに下記サンプルクエリのように`exposures:`を追加し、ダッシュボードなどの名前やリンク、使用されているテーブルを指定するだけです。

- **[dbt公式](https://docs.getdbt.com/docs/build/exposures)のサンプルクエリ**
    
    ```jsx
    version: 2
    
    exposures:
    
      - name: weekly_jaffle_metrics
        label: Jaffles by the Week              # optional, new in dbt Core v1.3
        type: dashboard                         # required
        maturity: high                          # optional
        url: https://bi.tool/dashboards/1       # optional
        description: >                          # optional
          Did someone say "exponential growth"?
    
        depends_on:                             # expected
          - ref('fct_orders')
          - ref('dim_customers')
          - source('gsheets', 'goals')
          - metric('count_orders')
    
        owner:
          name: Callum McData
          email: data@jaffleshop.com
    ```
    

exposuresの設定に必要なパラメータは以下の３つです。




- **name**
    - スネークケースでダッシュボード名などのexposureの名前を記入します。
- **type**
    - exposureのタイプを`dashboard`, `notebook`, `analysis`, `ml`, `application`の中から１つ選びます。
- **owner**
    - exposureのオーナー情報のうち`name`か`email`のどちらかを記入します。
    （もちろん両方でもいいですし、追加情報も記載できます）

<br>

使用されているテーブルは`depends_on`パラメータで指定します。
ref関数を使うことで、ダッシュボードやテーブル間の依存関係を可視化させることができます。

>詳細については[公式ドキュメント](https://docs.getdbt.com/docs/build/exposures)をご参照ください。

<br>

実際に書き込んでみたのが下図です。

![Untitled (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516499/cf635d58-51fa-c30a-2729-e3110f2b72c8.png)


`depends_on`部分のテーブルたちはGSSのconcatenate関数などを使って作りました。
（力技は面倒だしヒューマンエラーが怖かった。。）


### 2. コマンドを叩いて実行

ymlファイルに書き込んだ設定を実装します。

[dbt公式](https://docs.getdbt.com/docs/build/exposures#referencing-exposures)では、下記のようにnameに設定したダッシュボードごとにdbt runするコマンドが書かれていました。
```
dbt run -s +exposure:weekly_jaffle_report
```

ただ、複数のダッシュボードやアウトプットがある場合は、`dbt docs generate`を実行すればすべて実装されるので、こっちの方が楽かなと思います。

## dbt Docsで確認

それではdbt Docsで確認していきます。

![dbt_docs_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516499/98d6970f-eb06-6d18-af01-5af9ca9c1b98.png)


画面左側のOverViewにExposuresが作られています。

`type: dashboard`と設定したので、Dashboardフォルダ内に各ダッシュボードに関するドキュメントが格納されています。

### ダッシュボードに使われているテーブルを確認
Dashboardフォルダ内のファイルをクリックすると詳細を見ることができます。
![Untitled (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516499/b7a301c5-5998-d512-726d-d723465c2354.png)

:::note info
各コンポーネントの説明

①`label`を指定した際のタグが表示されます。
　・今回は何も指定してないので、untaggedと表示されています。

②`description`で記述した説明文が表示されます。


③`depends_on`で指定したテーブルが並んでいます。
　・ リンクを踏んでそれぞれのテーブルの詳細ページに飛ぶことができます。

④`url`で設定したリンクに飛ぶことができるボタンです。

⑤ダッシュボードとテーブルの依存関係をリネージュを見ることができます。
:::

### テーブルがどのダッシュボードに使われているのかを確認

さて、これでダッシュボードにどのテーブルが使われているかはわかりましたが、
逆にテーブルがどのダッシュボードに使われているのかを見ていきます。

上図③にリスト表示されているテーブルをクリックし、テーブルの詳細ページでリネージュを表示します。
![Untitled (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516499/a6f7be97-9735-84bc-ff91-5642f0969048.png)

リネージュを見るだけで、そのテーブル（紫）がどのように作られて、**どのダッシュボード（オレンジ）に使われているのか**を見ることができるようになりました！

<br>
さらにここからは、<br>
「このテーブルの修正やその元データの変更は、表示されている２つのダッシュボードに影響するので注意が必要だ」
というインサイトを得ることができます。

## おわりに

今回はdbtの **exposures** 機能を実装し、テーブルとダッシュボードの依存関係を把握しやすくしました。

これによって、プロセス全体をより効果的に管理できるようになりますし、エラーや変更点の追跡も容易になるので、あわやのヒューマンエラーも起きにくくなるのかなと思います。

<br>
ただ一点注意すべきだと思ったのは、exposuresの運用についてです。

今回`depends_on`には、**いまダッシュボードに使用されているテーブル**たちを書き込んだわけですが、遠くない未来でダッシュボードの内容が変わっていく可能性は十分あります。

今のところ最も可能性があるのが、使用するテーブルが増えるというケースです。

<br>

ここで満足して、半年後にdbt Docsを見たら
- 使っているのにダッシュボードに紐づいてない
- 今のダッシュボードに使われてないテーブルがある
- そもそもなくなっているダッシュボードを参照している

というような状況になっていることは想像に難くありません。
ダッシュボードを複数人で運用しているのでなおさらです。

なので今回の試みが陳腐化しないように、運用ルールを決めて定期的にチェックするなどの施策を講じていこうと思います。

## 参考

https://docs.getdbt.com/docs/build/exposures

https://dev.classmethod.jp/articles/dbt-exposures/