次のページに、dbt BestPracticeとしてコードスタイルの記載があり、
pre-commit hooksで自動化しようとかも書かれているのですが、
設定例が見当たらなかったので書いてみました。

How we style our dbt projects | dbt
https://docs.getdbt.com/best-practices/how-we-style/0-how-we-style-our-dbt-projects

BestPracticeのコードスタイルでは、以下のようにツールへの言及があるので、
これらのツールを導入していきます。

  • How we style our SQL
    • Use SQLFluff to maintain these style rules automatically.
  • How we style our Python
    • Our current recommendations are
      • black formatter
      • ruff linter
  • How we style our YAML
    • Use the dbt JSON schema with any compatible IDE and a YAML formatter (we recommend Prettier) to validate your YAML files and format them automatically.

設定ファイルの例

pre-commitの設定ファイル例を示します。
実際には、blackとruffはどちらかのみにした方が混乱がないと思います。

pre-commit-config.yaml

repos:
  - repo: https://github.com/sqlfluff/sqlfluff
    rev: 3.1.1
    hooks:
      - id: sqlfluff-lint
        additional_dependencies:
          - sqlfluff-templater-dbt==3.1.1
          #  - dbt-bigquery==1.8.2 # it's a example, add package if you need.
      - id: sqlfluff-fix
        additional_dependencies:
          - sqlfluff-templater-dbt==3.1.1
          #  - dbt-bigquery==1.8.2 # it's a example, add package if you need.
  - repo: https://github.com/psf/black
    rev: 24.4.2
    hooks:
      - id: black
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.6.4
    hooks:
      - id: ruff
        # args:
        #  - --fix # commentin if you like autofix
      - id: ruff-format
  - repo: local
    hooks:
      - id: prettier-yaml
        name: Prettier YAML
        entry: prettier --write
        language: system
        types: [yaml]
  - repo: https://github.com/python-jsonschema/check-jsonschema
    rev: 0.29.2
    hooks:
      - id: check-jsonschema
        name: "Check dbt dbt_project yaml"
        files: dbt_project.yml$
        types: [yaml]
        args:
          - --schemafile
          - https://raw.githubusercontent.com/dbt-labs/dbt-jsonschema/main/schemas/latest/dbt_project-latest.json
      - id: check-jsonschema
        name: "Check dbt selectors yaml"
        files: selectors.yml$
        types: [yaml]
        args:
          - --schemafile
          - https://raw.githubusercontent.com/dbt-labs/dbt-jsonschema/main/schemas/latest/selectors-latest.json
      - id: check-jsonschema
        name: "Check dbt package yaml"
        files: packages.yml$
        types: [yaml]
        args:
          - --schemafile
          - https://raw.githubusercontent.com/dbt-labs/dbt-jsonschema/main/schemas/latest/packages-latest.json
      - id: check-jsonschema
        name: "Check dbt properties yaml"
        files: (models|analysis|snapshots)/.*.yml$
        types: [yaml]
        args:
          - --schemafile
          - https://raw.githubusercontent.com/dbt-labs/dbt-jsonschema/main/schemas/latest/dbt_yml_files-latest.json

.github/workflows/ci.yaml

name: ci
on:
  - push
jobs:
  unit_test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
      - run: npm install prettier -g
      - uses: pre-commit/action@v3.0.1

プロジェクト作成~導入の手順

ここではdatabaseはsqliteを利用するとして、説明を記載します。

Gitのリポジトリを作成します。

mkdir dbt-pre-commit-study && cd $_
git init

Pythonの仮想環境を作成し、dbt-coreをインストールします。

python -m venv .venv
echo ".venv" >> .gitignore
. .venv/bin/activate
pip install dbt-sqlite

dbtのプロジェクトを作成します。

echo "logs" >> .gitignore
dbt init myproject

requirements.txtを追加します。

pip install -r requirements.txt

sqlfluffの設定ファイルを作成します。

.sqlfluff

[sqlfluff]
dialect = sqlite

Prettierをインストールします。

npm install prettier -g
prettier --version

.pre-commit-config.yamlを作成します。 ファイルの内容は「設定ファイルの例」を参照。

.pre-commit-config.yamlをGitに追加します。

git add .pre-commit-config.yaml
git commit .pre-commit-config.yaml -m "add pre-commit config"

Gitのフックにpre-commitをインストールします。

pre-commit install

Git管理下にソースコードを追加して、commitを実施します。

git add .
git commit -a -m "initial commit"

commitを実施すると、次のようにチェックが走ってcommitが失敗します。
このケースは自動修正されているので、再度commitコマンド実行でcommitは成功します。

$ git commit -a -m "initial commit"
sqlfluff-lint............................................................Failed
- hook id: sqlfluff-lint
- exit code: 1

== [myproject/models/example/my_first_dbt_model.sql] FAIL
L:   1 | P:   1 | LT13 | Files must not begin with newlines or whitespace.
                       | [layout.start_of_file]
== [myproject/models/example/my_second_dbt_model.sql] FAIL
L:   1 | P:   1 | LT13 | Files must not begin with newlines or whitespace.
                       | [layout.start_of_file]
All Finished 📜 🎉!


sqlfluff-fix.............................................................Failed
- hook id: sqlfluff-fix
- files were modified by this hook

==== finding fixable violations ====
== [myproject/models/example/my_second_dbt_model.sql] FAIL
L:   1 | P:   1 | LT13 | Files must not begin with newlines or whitespace.
                       | [layout.start_of_file]
== [myproject/models/example/my_second_dbt_model.sql] FIXED
== [myproject/models/example/my_first_dbt_model.sql] FAIL
L:   1 | P:   1 | LT13 | Files must not begin with newlines or whitespace.
                       | [layout.start_of_file]
== [myproject/models/example/my_first_dbt_model.sql] FIXED
2 fixable linting violations found
==== lint for unfixable violations ====
== [myproject/models/example/my_first_dbt_model.sql] PASS
== [myproject/models/example/my_second_dbt_model.sql] PASS


black................................................(no files to check)Skipped
ruff.................................................(no files to check)Skipped
ruff-format..........................................(no files to check)Skipped
Prettier YAML............................................................Failed
- hook id: prettier-yaml
- files were modified by this hook

myproject/dbt_project.yml 22ms
myproject/models/example/schema.yml 3ms

Check dbt dbt_project yaml...............................................Passed
Check dbt selectors yaml.............................(no files to check)Skipped
Check dbt package yaml...............................(no files to check)Skipped
Check dbt properties yaml................................................Passed

GitHubActionsでもチェックしたい場合は、
.github/workflows/ci.yamlを追加します。
ファイルの内容は「設定ファイルの例」を参照。

導入ツール一覧

導入したツールのリンク一覧です。

ツール毎の設定

基本はデフォルト設定で運用かと思いますが、
ツール毎の設定方法のリンクを記載しておきます。

sqlfluffの設定

blackの設定

ruffの設定

prettierの設定

check-jsonschemaの設定

以上。