dbtを触ってみた

# 何ができるか
BigQueryなどのデータウェアハウスやデータベースのデータに対して、いわゆるELT処理のTを構築管理することができるソフトウェアorサービスです。
使い方は、クラウドサービスの `dbt cloud` かローカルに構築して使う `dbt CLI` の2通りあるようです。

dbt cloud の画面はこんな感じです。

![Screen Shot 2021-03-30 at 11.20.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54176/11ab99cb-f5da-d08a-5e20-bbd36675bca6.png)

こちらの記事は基本クラウドを使う前提で書いています。

# DB側の準備 (BigQuery)
BigQueryに対して使う場合、BigQuery側にデータを配置し、サービスアカウントをdbtのために発行するだけです。サービスアカウントに付与するロールは、以下のとおりです。([参照元](https://console.cloud.google.com/billing/01E831-B87FB9-013E37/reports;timeRange=CUSTOM_RANGE;from=2022-02-01;to=2022-02-18?organizationId=433637338589))

- BigQuery Data Editor
- BigQuery User

# パイプラインの構築
## SQLファイルの作成で変換処理を書く
dbtでは、SQLを記述したファイルを作成し、それを関連づけることでパイプラインを構築します。SQLは次のようなファイルに本当に単にBigQueryの画面で書くSQLそのものをファイルにします。

![Screen Shot 2021-03-30 at 11.21.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54176/a4cfb642-ae48-5299-2273-e8a653fc14b7.png)

`preview data` をクリックすると実際にクエリがBigQueryに発行され、下部に結果が表示されます。(ここBigQueryの費用が発生するので大きなテーブルの場合など注意ですね。)

で、この結果をどういう形で出力するかを指定することができます。ビューとかテーブルとして実体化するなどを選択します。それは、別の設定ファイル `dbt_project.yml` に書くか、先のSQLファイルに書きます。SQLに書いた場合、当然そのSQL処理で生成される出力のみに対して指定は有効になります。一方、`dbt_project.yml` には、フォルダのレベルでより広く出力の設定を適用することができます。

### SQLファイルに書く場合
次のようにSQLファイルの冒頭などに書きます。BigQueryの場合、テーブルとして実体化する際のパーティションの指定などができます。

![Screen Shot 2021-03-30 at 11.22.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54176/b678e847-d11a-3315-a90d-e0e3c604733f.png)

### dbt_project.yml に書く場合
`dbt_project.yml` に書く場合は、次のようにyaml形式で、モデルの下のフォルダなどを指定して、そのフォルダに存在するファイル全てに適用させる形で指定します。

![Screen Shot 2021-03-30 at 10.49.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54176/f0d9ac54-2540-36bd-89ee-13ceab1d828d.png)

# ファイルとフォルダ
dbtは、デフォルトで次のようなファイルやフォルダが生成されます。変換処理を定義するSQLファイルは `models` に記載します。`models` 配下に階層的にフォルダを作成することもできます。ここでは、dwh層のデータをつくるという想定で `dwh` フォルダを `models` の下に作り、そこに変換処理のクエリが書かれたSQLファイルを格納しています。

![Screen Shot 2021-03-30 at 10.18.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54176/f9db239d-ef13-f73a-6b8a-e5f67afb884a.png)

また、これらのファイルやフォルダは、Githubと連携します。これすごい良いところですね。開発フローが運用できるし、ファイルの管理も楽になります。

## クエリの出力を別のクエリで参照する
例えば、2つのテーブルを結合する処理をする場合に、可読性やパフォーマンス向上のために複雑なクエリをファイルに分割したり、分割したクエリそれぞれで結果をテーブルに出力したりすることがあると思います。その場合、SQLファイルの中で次のようにして別のクエリ結果を引用することができます。 `{{ ref('lineitem') }}` や `{{ ref('orders_with_customer') }}` の部分がそれにあたります。こうすることで別ファイルでクエリを記述している処理を参照できます。

![Screen Shot 2021-03-30 at 10.52.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54176/99fc2f22-520c-5e16-3b5f-64fd65e0f0a7.png)

これにより、パイプラインとしては、`lineitem` と `orders_with_customer` の処理が終了した後に、上のSQLの処理が実行されるフローとなります。このようにして、処理の依存関係を定義していきます。

# 実行とEnvironment
## 開発環境での実行
処理の記述が終わったら、まずは開発環境で実行して想定通りの処理か確認することができます。dbtには、Development と Production それぞれの環境を用意できます。

画面左下の `dbt run` をクリックしてEnterすると処理が実行されます。処理が終わると次のように結果が表示されます。

![Screen Shot 2021-03-30 at 11.11.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54176/6a4649c1-c21e-2d37-3614-7b173cce6c56.png)

実際に、BiqQueryのコンソール画面上でテーブルができている様子が確認できます。

![Screen Shot 2021-03-30 at 12.15.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54176/cf265cd4-f69a-4100-2f7e-720a53d4b384.png)

# 本番へのデプロイと実行
開発で正常に動くことが確認できたら本番へ反映します。画面の左上に `Commit` ボタンがあると思いますが、これをクリックしてコミットメッセージを入れます。今度は、同じボタンが `merge to master` となるのでこれを続けて押します。ちなみに、開発する際に初めにmasterとは別のブランチを作っています。

![Screen Shot 2021-03-30 at 12.17.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54176/71bba371-d8c6-16ed-f83d-89c3194bfdc0.png)

次にメニューから `Jobs` を選び、続けて `New Job` をクリックします。ジョブ名や定期実行の感覚などを設定し、`Save` をクリックします。これで指定した感覚でジョブが定期実行されるようになり、BigQuery上にある元テーブルのデータが更新を反映することができます。`Run now` をクリックして即時実行することもできます。ジョブが実行されると次のようにジョブの実行結果がリストされます。

![Screen Shot 2021-03-30 at 12.28.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54176/99d1cb98-cf68-84c9-41cf-8dd0b4e6c95d.png)