Apache Airflow、Snowflake、dbtによるデータエンジニアリングをやってみた

## 背景と目的
Snowflake社が提供している学習コンテンツで良さそうなテーマを見つけて取り組んでみたところ、エラーが出過ぎて困ったので、備忘録的に遭遇したエラーとその解消方法を整理していきたいと思います。

[Apache Airflow、Snowflake、dbtによるデータエンジニアリング](https://quickstarts.snowflake.com/guide/data_engineering_with_apache_airflow_ja/index.html?index=..%2F..index#0)

### 動作環境
Windows Subsystem For Linux環境（WSL）で構築しました。
UbuntuOSを採用しています。

``` cmd
>wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-20.04    Running         2
```

DockerおよびDocker composeのバージョンは以下の通りです。

``` sh
$ docker --version
Docker version 27.2.1, build 9e34c9b

$ docker-compose -v
docker-compose version 1.29.2, build 40524192
```

## 遭遇したエラーと解消法
各章のナンバリングはチュートリアル中の実行順番号と同一です。

### 2: 環境設定
#### *エラー内容：Error: unknown command "init" for "dbt"*
> DBTプロジェクトの場合は、dbt init dbtを実行します。

上記記載がありますが、この段階ではdbt-coreをインストールしていないため、
記載のdbtコマンドは実行できません。


#### 解決策
pipがインストールされている環境であれば、下記コマンドによりdbt-coreのインストールが可能です。
``` sh
pip install dbt-core
```

### 3: DBTプロジェクトの設定
#### *エラー内容： Required version of dbt for 'dbt_utils': ['>=0.18.0', '<0.20.0']*

> 最後のステップは、db_utilsのdbtモジュールをインストールすることです。
> ```sh 
> dbt deps 
> ```

この章の設定項目として上記コマンドを実行するように記載があります。
その際に遭遇したエラーになります。

#### 解決策
原因は下記のサイトの通り、dbtパッケージとdbtバージョンの依存関係の不一致となります。

https://github.com/Snowflake-Labs/sfquickstarts/issues/1382

dbt関連のライブラリは`Dockerfile`内でインストールするように設計し直しました。
詳細は後述します。

``` Dockerfile
RUN pip install --upgrade pip && \
    pip install dbt-core==1.7.3 && \
    pip install dbt-snowflake==1.7.3
    ...
```

package.ymlの内容も変更しました。
``` yml
packages:
  - package: dbt-labs/dbt_utils
    version: 1.1.1
```

### 7: Airflowのdocker-composeファイルの実行
#### *エラー内容：Unsupported config option for services.airflow-cli: 'profiles'*

> docker-compose upを実行しhttp://localhost:8080/に移動しましょう。

満を持してコンテナを起動しようとした際に発生したエラー。
下記サイトによるとdocker-composeのバージョンが古かったのが原因でした。

#### 解決策
下記サイトの方法に従い、docker-composeのバージョンを更新。自前の環境が1.27系だったため本エラーに遭遇。1.29以上が求められるそうです。

https://hakanu.net/docker/2021/09/19/resolving-invalid-docker-compose-yaml-error-during-using-airflow-with-docker/


#### *エラー内容：You are running pip as root. Please use 'airflow' user to run pip!*
![{DA90A46A-6894-4DFB-8937-99592BA31EED}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3833399/53de917c-24ab-1fb6-2646-d84928de8047.png)
チュートリアルでは、`.env`ファイルにdbtをバージョン固定で記載しています。
この`.env`ファイルはdockerコンテナが起動するタイミングに読みこまれ実行されますが、その際に発生するエラーとなります。

#### 解決策
`.env`でdbtをインストールする設計ではなく、dbtをインストールしたコンテナを`Dockerfile`から作り直すことで対処しました。
rootユーザで実行するコマンド、airflowユーザで実行するコマンドを分けて実行させます。
また、`Required version of dbt for 'dbt_utils': ['>=0.18.0', '<0.20.0']`の対応と併せてバージョンは固定してインストールしています。

``` docker
FROM apache/airflow:2.10.0

USER root
RUN echo 'airflow ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
RUN apt update -y && apt upgrade -y
RUN apt-get install git -y
RUN  apt-get install vim -y
RUN apt-get install --no-install-recommends -y -q \
    git libpq-dev python3-dev build-essential && \ 
    apt-get clean

USER airflow

RUN pip install --upgrade pip && \
    pip install dbt-core==1.7.3 && \
    pip install airflow-dbt && \
    pip install dbt-snowflake==1.7.3 && \
    pip install python-certifi-win32

ENV PYTHONIOENCODING=utf-8
ENV LANG C.UTF-8
```


#### *エラー内容: The auth_backends setting in [api] has had airflow.api.auth.backend.session added in the running config, which is needed by the UI. Please update your config before Apache Airflow 3.0.*

チュートリアル中にインストールするdocker-compose.ymlを利用すると発生するエラーのようです。


#### 解決策
下記サイトに従い、最新のairflowを構築するdocker-compose.ymlをインストールしエラーを解消しました。
先述の通り、AirflowのイメージはDockerfileから作成するようにdocker-compose.ymlを書きかえます。

https://github.com/apache/airflow/discussions/26084

https://airflow.apache.org/docs/apache-airflow/stable/howto/docker-compose/index.html


#### *おまけエラー：InRelease is not valid yet*
Dockerコンテナ内で`apt-get update`しようとした際に発生したエラー。
おそらくWSL特有っぽいエラーで、WSLの時刻とPCの時刻が異なることが原因のようです。

### 解決策
下記サイトを参考にさせていただき、次のコマンドを実行して解消しました。
``` sh
sudo hwclock --hctosys
```
https://zenn.dev/dozo/articles/0cd227743545cc


## 最後に
チュートリアルの情報が古いせいか、バージョンの段差によるエラーが頻発しました。
スムーズに構築とはいきませんでしたが、`dbt×Snowflake×Aiflow`というよくある構成を、自前の環境で試してみることができ勉強になりました。

これから本チュートリアルに挑戦される方へ向けて、少しでも手助けとなる記事になれば幸いです。