0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

sqlfluffの環境をdocker composeで構築してみよう

0
Posted at

SQL linterの1つであるsqlfluffの環境をdocker composeでサクッと構築したい。

背景

最近はAIにSQLを書いてもらうことも多く、少し前からlinter/formatterを使いたいと考えていた。そんな中で開発チームに新しく参加した方のコーディングスタイルが既存メンバーのものと大きく異なっていたため、本格的にlinter導入を検討し始めた。
linterはいくつか選択肢があるがsqlfluffはpythonパッケージで、組織の環境にマッチしているため少し触ってみようという次第。
執筆時点では勝手に導入を検討している段階で、業務では使用していない。

構築

今回は以下のようにコンテナ構築用のdocker-composeと確認対象のSQLファイルを作成する。

│   docker-compose.yaml
│
└── sql
        tables.sql
        transactions.sql

まずは肝となるdocker-compose.yamlを作成する。
sqlfluffは公式イメージが配布されているのでこちらを使用。業務で使うときにはバージョンを固定しよう。
sqlfluffが対象のファイルを読めるようにマウントしておく。

services:
  lint:
    image: sqlfluff/sqlfluff:latest
    volumes:
      - type: bind
        source: ./sql/
        target: /sql/

サンプルSQLには適当に以下のようなものを用意。ちなみにDBはPostgreSQL。

create table users (
    id serial primary key,
    username varchar(50) not null unique,
    email varchar(100) not null unique,
    created_at timestamp default current_timestamp
);

create table orders (
    id serial primary key,
    user_id int references users(id),
    product_name varchar(100) not null,
    quantity int not null,
    order_date timestamp default current_timestamp
);
insert into users(
    username,
    email
) values
('hoge', 'hoge@example.com'),
('huga', 'huga@example.com')
;

insert into orders(
    user_id,
    product_name,
    quantity,
    order_date
) values
(1, 'Product A', 2, now()),
(1, 'Product B', 1, now()),
(2, 'Product C', 5, now())
;

select
    product_name,
    quantity,
    order_date,
    username,
    email
from
    orders
left join
    users on orders.user_id = users.id
where
    orders.id = '1'
;

動作確認

sqlfluffでは、sqlfluff lintでlintを、sqlfluff fixでformatを実行できる。
公式イメージはコンテナのエントリーポイントを/sqlfluffに設定しているので実際のコマンドは以下を使用した。

docker compose run --rm lint lint ./ --dialect postgres

サービス名をlintとしたため分かりにくいが1つ目のlintがコンテナ指定、2つ目のlintがsqlfluffのコマンドになっている。その後は対象ファイルと言語を指定。
主要な言語は基本的に網羅しているように思われる。詳細はDialects Referenceを参照。
上記のコマンドを実行した結果、次のようにエラー発生位置と抵触しているルール、詳細が表示された。

[+] Creating 1/1
 ✔ Network sqlfluff_default  Created                                         0.2s 
== [tables.sql] FAIL
L:  10 | P:  33 | LT01 | Expected single whitespace between naked identifier and  
                       | start bracket '('. [layout.spacing]
== [transaction.sql] FAIL
L:   1 | P:  18 | LT01 | Expected single whitespace between naked identifier and  
                       | start bracket '('. [layout.spacing]
L:   6 | P:  29 | CV06 | Statements must end with a semi-colon.
                       | [convention.terminator]
...
L:  21 | P:   5 | RF02 | Unqualified reference 'product_name' found in select     
                       | with more than one referenced table/view.
                       | [references.qualification]
...
All Finished 📜 🎉!

「かっこの前にスペースが無い」、「改行セミコロンするな」、「select句で元のテーブルを明示せよ」
と怒られている。続いてfixコマンドを実行した。

==== finding fixable violations ====
== [tables.sql] FAIL
L:  10 | P:  33 | LT01 | Expected single whitespace between naked identifier and
                       | start bracket '('. [layout.spacing]
== [tables.sql] FIXED
== [transaction.sql] FAIL
L:   1 | P:  18 | LT01 | Expected single whitespace between naked identifier and
                       | start bracket '('. [layout.spacing]
...
== [transaction.sql] FIXED
6 fixable linting violations found
  [5 unfixable linting violations found]

「かっこの前にスペースが無い」、「改行セミコロンするな」のエラーは解消してくれた。
一方で「select句で元のテーブルを明示せよ」は自動処理できなかった。テーブル構造を理解しないと対処できないので仕方ない。

まとめ

docker-composeを使ってsqlfluffを動かせる環境を作った。軽く動かすだけなら非常に簡単にできた。
AIが爆速でクエリを量産する中でスタイルを意識するのは疲れる。fixコマンドでは自動で修正できないパターンもあるため完全にお任せとはいかないが、CIで動かしてできる限り楽をしたい。

また、公式でチームに採用する手順をまとめてくれている。
これを参考に周囲へのプレゼンを行い、うまくいけばスタイルバトルが始まる...
https://docs.sqlfluff.com/en/stable/guides/setup/teamrollout.html

参考

SQLFluffを導入しました
Rules Reference

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?