dbt (CLI) × BigQuery 〜Docker 環境構築から GitHub Pages 公開まで〜

# 概要
この記事では、dbt (CLI) を Docker でさくっと試す方法を書きました
dbt コマンドによって、BigQuery 上でデータセット、テーブル、ビューを作成します
OAuth 認証のためサービスアカウントの発行は不要です

dbt の解説はすでにいくつもあるので、この記事では書きません

# サンプルリポジトリ
こちらにサンプルリポジトリを用意しています

```
git clone https://github.com/mida-hub/dbt-sample.git
```

# ディレクトリ構成
以降の記事は README.md の内容を書いています

```
.
├── README.md
├── dbt_projects
│   └── sample_project
├── Dockerfile
├── docker-compose.yml
├── docs (dbt で生成したドキュメントを GitHub Pages で公開する)
└── profiles.yml (dbt 初期設定で使う)
```

# 設定
## Dockerfile
下記リポジトリを参考にしました

参考: [dbt-core docker](https://github.com/dbt-labs/dbt-core/tree/main/docker)


```Dockerfile
FROM python:3.9.12-slim-bullseye

ARG dbt_bigquery_ref=dbt-bigquery@v1.0.0

# System setup
RUN apt-get update \
  && apt-get dist-upgrade -y \
  && apt-get install -y --no-install-recommends \
    git \
    ssh-client \
    software-properties-common \
    make \
    build-essential \
    ca-certificates \
    libpq-dev \
    vim \
  && apt-get clean \
  && rm -rf \
    /var/lib/apt/lists/* \
    /tmp/* \
    /var/tmp/*

# Env vars
ENV PYTHONIOENCODING=utf-8
ENV LANG=C.UTF-8

# Update python
RUN python -m pip install --upgrade pip setuptools wheel --no-cache-dir

# dbt-bigquery
RUN python -m pip install --no-cache-dir "git+https://github.com/dbt-labs/${dbt_bigquery_ref}#egg=dbt-bigquery"

COPY profiles.yml /root/.dbt/profiles.yml

WORKDIR /usr/app/dbt/
VOLUME /usr/app
ENTRYPOINT tail -f /dev/null

```

## docker-compose.yml

- ローカルマシンの config を参照することで、コンテナはローカルマシンと同一の権限で BigQuery に対して処理を実行できます
- dbt コマンドで生成したドキュメントを参照するためにポートを設定しています

```docker-compose.yml
version: "3"
services:
  dbt:
    container_name: local
    build: .
    volumes:
      - ~/.config/gcloud:/root/.config/gcloud
      - ./dbt_projects:/usr/app/dbt
    ports:
      - 8080:8080


```

## profiles.yml
project をあなたの GCP project に設定してください
docker を build したときにコンテナ内に配置されます

```profiles.yml
sample_project:
  outputs:
    dev:
      dataset: lake
      fixed_retries: 1
      location: US
      method: oauth
      priority: interactive
      project: your-project
      threads: 3
      timeout_seconds: 300
      type: bigquery
  target: dev
```

## dbt_project.yml
dbt コマンドによって、BigQuery 上に、下記のデータセットが作成されます

- lake
- warehouse
- mart

dbt は単一スキーマ(BigQuery ではデータセット)上でのデータ加工が想定されています
BigQuery との階層構造と一致していないのでカスタムしています

ただし、カスタムスキーマを使用したときに、tests 配下に配置する test はデフォルトスキーマを向いてしまいます
そのためこのサンプルでは、test を models 配下に配置しています
（もし、やり方をご存じの方は教えてください）

```dbt_project.yml
models:
  sample_project:
    warehouse:
      +schema: warehouse
    mart:
      +schema: mart
```

```macros/get_custom_schema.sql
{% macro generate_schema_name(custom_schema_name, node) -%}
  {%- set default_schema = target.schema -%}
  {%- if custome_schema_name is none or custom_schema_name == None -%}
    {{ default_schema }}
  {%- else -%}
    {{ custom_schema_name | trim }}
  {%- endif -%}
{%- endmacro %}
```

参考: [dbt + BigQueryで出力するデータセットを変更する](https://qiita.com/munaita_/items/29a23815240e37c8ee31)

# 認証
```
$ gcloud auth login
$ gcloud auth application-default login
```

# docker-compose
```
$ docker-compose up -d
$ docker exec -it local /bin/bash
```

# dbt コマンド
チュートリアルは下記を参考にさせて頂きました
素材となる csv や、コードも下記を元にしています

参考: [BigQueryとdbt Cloudで始めるデータパイプライン入門](https://zenn.dev/dbt_tokyo/books/537de43829f3a0)


## dbt seed
```
$ cd sample_project

# seeds 配下の csv を BigQuery に登録する
$ dbt seed
```

## dbt run
```
# models 配下の sql を実行する
$ dbt run
```

## dbt test
```
# models 配下の test を実行する ※ tests パスは意図的に削除しています
$ dbt test
```

## dbt docs generate & dbt docs serve
```
# models / tests / lineage などをドキュメント化します
$ dbt docs generate

# ドキュメントを公開するために webserver を起動します
$ dbt docs serve --port 8080
```

http://localhost:8080/ にアクセスすると下記のドキュメントが確認できます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273970/43dc5202-7e2d-67d8-5e33-8f37f255a7ba.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273970/f0e4acae-49ef-8c86-0230-388693a5fd13.png)

# GitHub Pages
dbt (CLI) を使用するときに困るのはドキュメントをどうやって公開するかだと思います
GitHub Pages にファイルを配置することでドキュメントを公開できます
企業組織内の有料リポジトリの場合は、Private が選択できるので、会社の人だけが参照できるドキュメントになります

## docs
リポジトリに docs ディレクトリを作成し、必要ファイルを配置します

```
$ mkdir docs
$ cp dbt_projects/sample_project/target/catalog.json docs
$ cp dbt_projects/sample_project/target/index.html docs
$ cp dbt_projects/sample_project/target/manifest.json docs
$ cp dbt_projects/sample_project/target/run_results.json docs
```

## 公開
あとは GitHub から docs 配下をソースとすることで公開できます

https://mida-hub.github.io/dbt-sample/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273970/f82422e5-710a-75dc-2707-e702d58e3809.png)