🍊

dbt Core × BigQuery で Dev Container の環境構築

2024/09/17に公開

構成要素 : SQLFluff、BigQuery Runner、dbt power user
下記の Dev Container 版構築
https://zenn.dev/yuichi_dev/articles/ba5c376c955e52

はじめに

  • ローカルで、dbt coreを開発するためには環境構築の手間がかかるため、Dev Containerを作成しました。とはいえ、IDEをVS Codeに強制してしまうため、Dockerファイルだけでも良かったかもです。
  • 業務委託の方であったり新しいメンバーに対して迅速に開発環境を提供できます。

ディレクトリ構造

dbt_project/

my_repository
├──.devcontainer/
│   ├── devcontainer.json
│   ├── Dockerfile
│   ├── postCreateCommand.sh
│   └── requirements.txt
├── dbt_project/
│   ├── .sqlfluff
│   ├── .sqlfluffignore
│   ├── dbt_project.yml
│   ├── packages.yml
│   └── ...
└──.gitignore

.devcontainer/

devcontainer.json
  • BigqueryのプロジェクトID:project_id
  • リポジトリ名設定:my_repository
  • dbtのプロジェクト名:dbt_project
  • "forwardPorts": [8080,8080]はdbt docs用、dbt docs serveでブラウザでエラーになる時は、何回かブラウザを更新するとdbt docsが表示できる
  • "extensions"で必要なVS Codeの拡張機能を設定しています
{
	"name": "dbt container",
	"build": {
		"context": ".",
		"dockerfile": "Dockerfile"
	},
	"mounts": [
		"source=${localEnv:HOME}/.dbt,target=/home/vscode/.dbt,type=bind,consistency=cached",
		"source=${localEnv:HOME}/.config/gcloud/,target=/home/root/.gcloud/,type=bind,consistency=cached"
	],
	"remoteEnv": {
		"CLOUDSDK_CONFIG": "/home/root/.gcloud"
	},
	"forwardPorts": [8080,8080],
	"customizations": {
		"vscode": {
			"settings": {
				"files.eol": "\n", // eol=lf
				"python.pythonPath": "/usr/local/bin/python",
				"python.interpreter.infoVisibility": "always",
				"DBT_PROFILES_DIR": "/workspaces/my_repository/dbt_project", // リポジトリ名及びdbtのプロジェクト名設定
				"dbt.dbtPythonPathOverride": "/usr/local/bin/python",
				"files.associations": {
					"*.yml": "jinja-yaml",
					"*.sql": "jinja-sql"
				},
				"bigqueryRunner.projectId": "project_id", // プロジェクトID設定
				"bigqueryRunner.keyFilename": "/home/root/.gcloud/application_default_credentials.json",
				"bigqueryRunner.location": "asia-northeast1",
				"sqlfluff.config": "/workspaces/my_repository/dbt_project/.sqlfluff", // リポジトリ名及びdbtのプロジェクト名設定
				"sqlfluff.executablePath": "/usr/local/bin/sqlfluff",
				"sqlfluff.dialect": "bigquery",
				"sqlfluff.linter.run": "onSave",
				"sqlfluff.experimental.format.executeInTerminal": true,
				"sqlfluff.format.enabled": true
			},
			"extensions": [
				"ms-vscode-remote.remote-containers",
				"ms-python.python",
				"ms-python.vscode-pylance",
				"GitHub.vscode-pull-request-github",
				"innoverio.vscode-dbt-power-user",
				"dorzey.vscode-sqlfluff",
				"minodisk.bigquery-runner"
			]
		}
	},
	"postCreateCommand": "/bin/bash .devcontainer/postCreateCommand.sh"
}
Dockerfile
# ベースイメージとしてPython 3.12.4を使用します。
FROM python:3.12.4-slim-bullseye as base

# 必要なパッケージのインストールと不要なキャッシュのクリーンアップ
RUN apt-get update \
  && apt-get dist-upgrade -y \
  && apt-get install -y --no-install-recommends \
    git \
    ssh-client \
    curl \
    gnupg \
    apt-transport-https \
    make \
    ca-certificates \
  && apt-get clean \
  && rm -rf \
    /var/lib/apt/lists/* \
    /tmp/* \
    /var/tmp/*

# GCP SDKのインストール
RUN echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
RUN curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key --keyring /usr/share/keyrings/cloud.google.gpg add -
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
    && apt-get -y install --no-install-recommends lv google-cloud-sdk jq bash-completion \
    && rm -rf /var/lib/apt/lists/*

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

# 必要なファイルをコンテナ内へコピーし、Pythonライブラリをインストールと一時ディレクトリのクリーンアップ
COPY requirements.txt /tmp/pip-tmp/requirements.txt
RUN pip install --upgrade pip \
    && pip install --no-cache-dir -r /tmp/pip-tmp/requirements.txt \
    && rm -rf /tmp/pip-tmp

# 非特権ユーザーの設定
ARG username=vscode
ARG useruid=1000
ARG usergid=${useruid}
RUN groupadd --gid ${usergid} ${username} \
    && useradd -s /bin/bash --uid ${useruid} --gid ${usergid} -m ${username}

# 非特権ユーザーに切り替え
USER ${username}
postCreateCommand.sh
set -eux

# dbtディレクトリに移動
cd dbt_project

# dbt utilsを使えるようにする
dbt deps

# 接続テスト
dbt debug
requirements.txt

必要なものを追加ください

dbt-core
dbt-bigquery
sqlfluff 
sqlfluff-templater-dbt 
dbt-osmosis

dbt_project/

.sqlfluff
[sqlfluff]
templater = dbt
dialect = bigquery
max_line_length = 200
output_line_length = 200
sql_file_exts = .sql
# バイト制限解除
large_file_skip_byte_limit = 0

# ルールの中から取り除くものを選ぶ
exclude_rules = 
    # sqlfluff fixでカラムの順序を変えないようにするための設定
    structure.column_order
    ,ambiguous.column_count
    ,structure.using
    # Salesforceはキャメルケースでlowerにすると読みにくくなるため追加
    ,capitalisation.identifiers

# dbt templaterの設定
# https://docs.sqlfluff.com/en/stable/configuration.html#installation-configuration
[sqlfluff:templater:dbt]
# 環境に合った設定をする
project_dir = ./
profiles_dir = ~/.dbt/ 
profile = dbt_project
target = dev

[sqlfluff:templater:jinja]
; dbt jinjaの組み込み関数(ref)などの機能に対応するかどうかというフラグ
apply_dbt_builtins = True

[sqlfluff:indentation]
indent_unit = space
tab_space_size = 2

[sqlfluff:rules:layout.long_lines]
# コメント行は長くても可とする。URLなどが入るため
# 行の長さに関してコメント行は無視する
ignore_comment_lines = True 
# 行の長さに関してコメント句は無視する
ignore_comment_clauses = True 

[sqlfluff:layout:type:comma]
# 先頭のカンマの強制
line_position = leading
# 前カンマの場合スペース入れない
spacing_after = touch

[sqlfluff:rules:capitalisation.keywords]
# 予約語の大文字小文字
capitalisation_policy = upper

[sqlfluff:rules:capitalisation.functions]
# 関数名の大文字小文字
extended_capitalisation_policy = upper

[sqlfluff:rules:capitalisation.literals]
# リテラル値 (null・true・false) の大文字小文字
capitalisation_policy = upper

[sqlfluff:rules:capitalisation.types]
# データ型の大文字小文字
extended_capitalisation_policy = upper

[sqlfluff:rules:capitalisation.identifiers]
# normalize(str, 'NFKC')といった形式で呼び出しいる箇所がnormalize(str, 'nfkc')となってしまう事象回避
ignore_words = NFD,NFC,NFKD,NFKC
.sqlfluffignore
dbt_packages/
macros/
target/
dbt_modules/
dbt_project.yml

# Name your project! Project names should contain only lowercase characters
# and underscores. A good package name should reflect your organization's
# name or the intended use of these models
name: 'dbt_project'
version: '1.0.0'
profile: 'dbt_project'

model-paths: ["models"]
analysis-paths: ["analyses"]
test-paths: ["tests"]
seed-paths: ["seeds"]
macro-paths: ["macros"]
snapshot-paths: ["snapshots"]

clean-targets:
  - "target"
  - "dbt_packages"

models:
  dbt_project:
    +persist_docs:
      relation: true
      columns: true
    +dbt-osmosis: "{model}.yml"
    work_dbt:
      +materialized: view
      +schema: work_dbt
packages.yml

必要なものを追加ください
https://dev.classmethod.jp/articles/dbt-package-dbt-utils/

packages:
  - package: dbt-labs/dbt_utils
    version: 1.1.1
.gitignore
logs/
target/
.DS_Store
dbt_packages/
packages.yml
.vscode/settings.json

Dev container で dbt をセットアップ

VSCodeのdevcontainerを使用してdbtをセットアップし、BigQueryと連携する方法について説明します。

前提条件

  • dbt Core用のファイル群がGitHubリポジトリで管理されている

手順

  1. GitHubアカウントを作成 → dbtのリポジトリに招待してもらう

  2. VSCodeをインストール

  3. ローカルにGitをインストール

  4. Docker Desktopをインストール

  5. VSCodeにDev Containers拡張機能をインストール

  6. gcloudの認証情報を準備していること

    1. ~/.config/gcloudディレクトリに必要な認証情報が含まれていることを確認します。具体的には、application_default_credentials.jsonファイルが含まれている必要があります。

    2. 認証設定

      gcloud auth application-default login
      

      設定確認(ファイルが確認できたらOK)

      cat ~/.config/gcloud/application_default_credentials.json
      
  7. ~/.dbt/profiles.ymlが設定されていること

    1. ~/.dbt/profiles.ymlファイルを以下のように設定します。
    dbt_project:
      outputs:
        dev:
          dataset: dbt
          job_execution_timeout_seconds: 300
          job_retries: 1
          location: asia-northeast1
          method: oauth
          priority: interactive
          project: project_id
          threads: 1
          type: bigquery
      target: dev
    
    1. ~/.dbt/profiles.ymlファイル確認したい場合

      cat ~/.dbt/profiles.yml
      
    2. ~/.dbt/profiles.ymlファイル編集したい場合

      code ~/.dbt/profiles.yml
      
    3. ~/.dbt/profiles.ymlファイルの作成したい場合

      touch ~/.dbt # ホームディレクトリに/.dbtディレクトリを作成する
      touch ~/.dbt/profiles.yml # /.dbtディレクトリ内にprofiles.ymlを作成する。
      code ~/.dbt/profiles.yml # ファイル編集
      
  8. dbtのリポジトリをクローンして開く

  9. Dev ContainerのGitHubへの認証設定
    Dev Container内にgitがあれば git commit 等は可能ですが、 git push となるとGitHubへの認証が必要になります。

    1. .gitconfigの情報確認(無ければgitの初期設定を行う)

      cat ~/.gitconfig
      
    2. VSCodeの .gitconfig の設定をDev Containerにコピーする設定

    3. GitHub CLIのCredential Helperを利用して、HTTPSでアクセス

      1. Git に GitHub の認証情報をキャッシュするのGitHub CLIの項目を順に実行
  10. VSCodeでdevcontainerを開く

    1. VSCodeでリポジトリを開きます。

    2. 左下の「><」アイコンをクリックし、「コンテナーでリビルドして再度開く」を選択します。

      1. 一度起動した後なら 「コンテナーで再度開く
    3. 自動でdbt debug(接続テストが走るようになってます)

  11. プロジェクトフォルダに移動

    cd dbt_project
    

実運用について

  1. ブランチを切る
  2. クエリを叩きながらSQLの開発(コンパイルやリネージュを確認しながら)
  3. ビルドする
  4. 説明文を書く
  5. SQLのフォーマット
  6. プルリクエストを発行

参考

https://qiita.com/tkshymgch/items/48c6c024b6c971ea71b5
https://qiita.com/mida12251141/items/47b4ade9cbbb82290d43
https://wapa5pow.com/posts/2021-09-06--local-development-on-dev-container
https://qiita.com/yamamoto-yuta/items/412b6e8167758e174d0a
https://zenn.dev/above/articles/f09f5acf64cde7
https://zenn.dev/bells17/articles/devcontainer-2024
https://zenn.dev/streamwest1629/articles/vscode_wanderer-in-devcontainer
https://qiita.com/im-dev/items/a2eb4ebba6b6df1e0521

Discussion