jinja2 ベースの自作テンプレートエンジンで sqlc の対抗を作ってみた
※ Disclaimer: ツール自体は OSS 公開になっていますが、現段階でメンテする予定はない(基本自分用)ためここで名前やリンクなどは載せないこととします。
普段は sqlc を使っていませんが(CRUDを直接コード生成するため)こちらのツイートで少し興味を持ったためです。https://x.com/voluntas/status/1821912712638820653
jinja2 は Python ベースのテンプレートエンジンです。ansible や最近では dbt で利用されているので割と有名だと思います。
対象は play.sqlc.dev にあるスキーマとクエリをベースにした検証となります。
一段階目としてスキーマとクエリをそれぞれパースします。詳細は割愛。
仕組みとしては github.com/pganalyze/pg_query_go/v5 を利用して Go で SQL を読み込むイメージです。
読み込んだものを一旦 JSON に落とします。(JSONに落としている理由はこちらツールは sql のみならず GraphQL や OpenAPI まで幅広く対応するため中間レイヤー相当となります、本記事対象外)
JSON で見るとこういうイメージです。
ParseToJSON というメソードもあるので pg_query_go で直接JSONに落とすのも可能です。
(自分はカスタマイズしたいので使っておりません)
JSON が用意できましたら jinja2 ベースの自作テンプレートエンジンに渡します。
モデルの生成は一番シンプルでテンプレートは以下となります。
スキーマ
※ ヘッダーの部分とかは別ファイルで用意するイメージです。
生成されるコード(型などは適度にマッピングする感じです)
次はクエリの生成です。
スキーマ
クエリのJSONはこんな感じです。
SQL 部分のコード生成用のテンプレート
生成されるコード
Go のメソードを生成用のテンプレート
生成されるコード
Insert 文
テンプレート
生成されるコード
DELETE や List または Update も似たようなものなのでここでは省略します。
sqlc のコードと比較して実装部分に差分がないことまでは確認できました。
実際試しているのはサンプルにあるコードのみなので sqlc の他の機能に関しては調整は必要になるかと思います。
以上
Discussion