😊

SQLFluffを導入してdbtの開発を加速させる

2023/10/08に公開

SQLFluffのルール集

https://docs.sqlfluff.com/en/stable/rules.html

SQLFluffのインストール

pip3 install sqlfluff

簡単に試してみる

その辺にあったこのSQLファイルで試してみる


with source as (

    select * from {{ source('public', 'raw_orders') }}

),

renamed as (

    select
        id,
        user_id,
        order_date,
        status

    from source

)

select * from renamed


ではコーティングチェックを実施します。
sqlfluff lint stg_public__raw_orders.sql --dialect snowflake

sqlfluff lint stg_public__raw_orders.sql --dialect snowflake
== [stg_public__raw_orders.sql] FAIL
L:   1 | P:   1 | LT13 | Files must not begin with newlines or whitespace.
                       | [layout.start_of_file]
L:  22 | P:   1 | LT12 | Files must end with a single trailing newline.
                       | [layout.end_of_file]
All Finished 📜 🎉!

2つほど違反があった模様。LT13やL T12はルール集のリンクに全量ルールが記載されています。
英語でルール説明があり、ファイルの1行目にスペースはダメとか、ファイルの末尾は改行が必要とかって言われています。

これら違反箇所を修正してもOKなら以下コマンドを実行します。
sqlfluff fix stg_public__raw_orders.sql --dialect snowflake

sqlfluff fix stg_public__raw_orders.sql --dialect snowflake
==== finding fixable violations ====
== [stg_public__raw_orders.sql] FAIL
L:   1 | P:   1 | LT13 | Files must not begin with newlines or whitespace.
                       | [layout.start_of_file]
L:  22 | P:   1 | LT12 | Files must end with a single trailing newline.
                       | [layout.end_of_file]
==== fixing violations ====
2 fixable linting violations found
Are you sure you wish to attempt to fix these? [Y/n] ...
Attempting fixes...
Persisting Changes...
== [stg_public__raw_orders.sql] FIXED
Done. Please check your files to confirm.
All Finished 📜 🎉!

dbtテンプレートを利用してみる

pip3 install sqlfluff-templater-dbt

準備

.sqlfluffと.sqlfluffignoreを作成

dbtプロジェクト直下に「.sqlfluff」ファイルを作成し、そこにSQLfluffのルールを記述することで、独自のルール集を作ることができます。

必要なファイルを作成
touch .sqlfluff
touch .sqlfluffignore

.sqlfluffignoreの設定

.sqlfluffignoreファイルはプロジェクトの一部でない SQLファイルを参照するデプロイスクリプトがある場合、エラーになります。
この問題は、dbtプロジェクト以外のSQLファイルを.sqlfluffignoreに追加することで解決できます。

.sqlfluffignoreに記載
dbt_packages/
macros/
target/
dbt_modules/

.sqlfluffのテンプレート設定

.sqlfluff内にdbtプロジェクトのPATHを記載します。
[sqlfluff]のtemplatorにはdbt、dialectには今回duckdbを設定しました。

.sqlfluff
[sqlfluff:templater:dbt]
project_dir = /home/dbt/jaffle_shop_pj/jaffle_shop
profiles_dir = /home/dbt/jaffle_shop_pj/jaffle_shop
profile = jaffle_shop
target = dev

[sqlfluff]
templater = dbt
dialect = duckdb

オリジナルのルールを作成

よくあるルールだけで簡単に作成してみました。
コーディングルールを決める時は開発メンバーとの合意をもとに作成するのが良いと思います。

[sqlfluff]
templater = dbt
dialect = duckdb


[sqlfluff:rules:capitalisation.keywords]
capitalisation_policy = lower

[sqlfluff:templater:dbt]
project_dir = /home/dbt/jaffle_shop_pj/jaffle_shop
profiles_dir = /home/dbt/jaffle_shop_pj/jaffle_shop
profile = jaffle_shop
target = dev

[sqlfluff:indentation]
tab_space_size = 2
allow_implicit_indents = true

[sqlfluff:rules:aliasing.table]
aliasing = explicit

[sqlfluff:rules:aliasing.column]
aliasing = explicit

[sqlfluff:rules:capitalisation.identifiers]
capitalisation_policy = lower

[sqlfluff:rules:capitalisation.functions]
extended_capitalisation_policy = lower

[sqlfluff:rules:capitalisation.literals]
capitalisation_policy = lower

[sqlfluff:rules:capitalisation.types]
extended_capitalisation_policy = lower

Github Actionsとの連携

チームで開発する際はGithubの運用が多いと思います。
その場合、pushしたらSQLFluffを自動で実行してくれる仕組みがあると便利ですよね。
Github Actionsで自動化をやってみました。

dbtテンプレートを使う場合と使わない場合

dbtパッケージが必要なことは公式ドキュメントにも記載されていました。

準備

Gitリポ直下にYAMLファイルを用意
mkdir -p .github/workflows
cd .github/workflows
touch dbt-actions.yml

dbtテンプレートを使う場合

dbt-actions.yml
name: push_trigger_sqlfluff

on: push

jobs:
   push:
       runs-on: ubuntu-latest

       steps:
       - name: Check out
         uses: actions/checkout@master

       - uses: actions/setup-python@v1
         with:
           python-version: "3.10.x"

       - name: Install packages
         run: |
            python3 -m pip install --upgrade pip
            pip3 install sqlfluff
            pip3 install sqlfluff-templater-dbt
            pip3 install dbt-snowflake ※dbtのパッケージインストールしないとエラーとなる

       - name: execute sqlfluff
         working-directory: snowflake_pj
         run: |
          sqlfluff lint ./models/orders.sql

dbtテンプレートを使わない場合

name: push_trigger_sqlfluff

on: push

jobs:
   push:
       runs-on: ubuntu-latest

       steps:
       - name: Check out
         uses: actions/checkout@master

       - uses: actions/setup-python@v1
         with:
           python-version: "3.10.x"

       - name: Install packages
         run: |
            python3 -m pip install --upgrade pip
            pip3 install sqlfluff
            pip3 install sqlfluff-templater-dbt

       - name: execute sqlfluff
         working-directory: snowflake_pj
         run: |
          sqlfluff lint ./models/orders.sql --rules L001 --dialect snowflake
.sqlfluffファイル
[sqlfluff]
templater = dbt
dialect = snowflake

[sqlfluff:templater:dbt]
project_dir = ./
profiles_dir = ./
profile = snowflake_pj
target = dev

~略~

ディレクトリ構造(参考)

snowflake-dbt
|-- .github
|   `-- workflows
|       |-- dbt-actions.yml_bk
|       `-- dbt-sqlfluff.yml
|-- README.md
|-- edr_target
|-- logs
`-- snowflake_pj
    |-- .sqlfluff
    |-- .sqlfluffignore
    |-- README.md
    |-- analyses
    |-- dbt_packages
    |-- dbt_project.yml
    |-- models
    |-- packages.yml
    |-- profiles.yml
    `--seeds


Discussion