dbt+Dockerを使ってみる【インフラエンジニアへの道4日目】

## dbtを使ってみよう
今回は、Dockerを使ってdbtとPostgreSQLの環境を構築し、データパイプラインの基盤作成をやってみます。
dbtはデータエンジニアリング領域では人気のあるツールで、ETLのT（Transform）部分をシンプルに管理できるのが特徴です。dbtを使うことで、SQLベースでデータモデルの作成やテストを行い、データの品質を保ちながら効率的に処理を進めることができます。

## 作業環境
* Windows11/WSLを利用
* Docker Desktopを使用

## 環境構築
### 1. 作業用ディレクトリを用意します。
以下のような構成を目指します。
```
dbt_docker_tutorial/
├── docker-compose.yml
└── dbt/
　   ├── profiles.yml
 　  └── my_dbt_project/
```

### 2. yamlファイルを作成する
* postgresはローカル用のPostgreSQL
* dbtは公式のdbt-postgresイメージを使います。
* sleep infinityにしたのは後で中に入って手動でdbtコマンドを使うためです。
```yaml:docker-compose.yml
version: "3.9"

services:
  postgres:
    image: postgres:13
    container_name: dbt_postgres
    environment:
      POSTGRES_USER: dbt_user
      POSTGRES_PASSWORD: dbt_pass
      POSTGRES_DB: dbt_db
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data

  dbt:
    image: ghcr.io/dbt-labs/dbt-postgres:1.7.4
    container_name: dbt_runner
    depends_on:
      - postgres
    volumes:
      - ./dbt:/root/.dbt
      - ./dbt/my_dbt_project:/usr/app
    working_dir: /usr/app
    entrypoint: ["/bin/bash", "-c", "sleep infinity"]

volumes:
  pgdata:
```

### 3. コンテナを立ち上げる
`PostgreSQL` と `dbt` の環境をDockerで起動します。
```sh
docker compose up -d
```
| コマンド | 意味 |
|:-:|:-:|
| `docker-compose`  | `docker-compose.yml`に書かれた複数のサービス（コンテナ）をまとめて操作する  |
| `up`  | コンテナを起動する（必要なイメージを自動でダウンロードする）  |
| `-d`   | detachedモード。（バックグラウンドで起動）コンソールにログを出さない。  |

起動確認します。
```sh
docker ps
```
無事に起動しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3734886/62500a29-d496-4a5e-94d5-9199277a0a7b.png)

### 4. `dbt_runner`コンテナに入ってプロジェクトを作成する
```sh
docker exec -it dbt_runner /bin/bash
```
dbtプロジェクトを作成する
```sh
dbt init my_dbt_project
```
その後、データベースの設定を求められるので、 `docker-compose.yml`に記載した通りに入力していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3734886/1fa74f3a-a306-415b-96be-02b57c3d186d.png)
DB設定が完了したら、そのまま接続確認を行います。
```sh
dbt debug
```
All checks passed！と表示されれば正しく設定できています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3734886/de0eb579-1c2d-4775-a96b-2214de9570d4.png)

### 5.最初のモデルを作成する
`models`ディレクトリ内に新しいSQLファイルを作成して最初のデータモデルを定義します。
```sql:my_first_model.sql
select * from {{ ref('staging_base') }}
```
このままだとテーブルがないことでエラーになるため、仮のデータを渡すように変更します。
```sql:staging_base.sql
-- 仮のデータを返すだけのモデル
select 1 as id, 'hello' as message
```
dbtコンテナの中に入り、実行してみます。
```sh
docker exec -it dbt_runner /bin/bash
dbt run
```
実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3734886/8685fccb-aaeb-43be-87f8-17d43095561e.png)
* `my_first_dbt_model`:dbtコンテナを作ったときにexampleディレクトリにもとから入っていたもの
* `my_second_dbt_model`：↑と同じく。
* `my_first_model`：今回自分で作成したもの
* `staging_base`:今回自分で作成したもの

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3734886/41133c48-665b-4983-a92f-16a424181b1e.png)
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3734886/41434578-1598-411b-bd2d-5624d3dc2e10.png)

`models`ディレクトリ内にあるsqlファイルが全て実行されたことが確認できました。
#### 6.作られた内容を確認する
先程はdbt_runnerという名前のdbtのコンテナ内にいたので、`exit`コマンドで退出します。
```sh
# PostgreSQLコンテナに入る
docker compose exec postgres bash
# データベースにアクセスする
psql -U dbt_user -d dbt_db
```

```sql
\dt dbt.*
select * from dbt.staging_base;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3734886/45b21f36-571c-4d27-87ed-0c60cba08304.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3734886/0ad3e21d-4186-426d-8e62-6273aebb6e91.png)

## まとめ
今回は、Dockerを使用してPostgreSQLとdbtを連携させ、データ基盤の構築をやってみました。以下の手順を通じて、必要なツールと環境の準備ができ、dbtプロジェクトの作成方法や初期設定も理解できたかと思います。
* Docker ComposeでDBTとPostgreSQLの環境を作成
* dbtのプロジェクトを立ち上げ、データベースとの接続確認
* 最初のデータモデルを作成し、実行
* 実行結果を確認し、dbtによって生成されたテーブルをPostgreSQLで確認

これで、dbtを活用したデータパイプラインの環境が整いました。
次回は、実際にdbtでデータパイプラインを作成したり、テストを行ったりしてみようと思います。