2024年はGoでSpannerを扱うにあたっていくつかツールを作ったので、せっかくなのでアドベントカレンダーに投稿してみる。

go-zetasqlfmt Link to heading

弊社プロダクトではGoからSpannerを扱うにあたって cloud.google.com/go/spanner を素で使っているが、SQLの部分が文字列なので書き手によってフォーマットが異なってしまっていた。

レビューやドキュメントで揃えるのも非効率なのでどうにか自動でフォーマットできないものかと思い、このフォーマッタを作成した。

ZetaSQLを採用したのはGoogleの出している一番スターが多いライブラリだったため。そこまで比較検討はしていない。

GoにBindingしていただいている go-zetasql をありがたく使わせていただき、プロジェクトのSQLは統一できるようになった。

CI少々ビルドに時間がかかってしまうため、 go-zetasqlfmt-action 作ったことによってCIも回しやすくして今もプロダクトのSQLのフォーマットを揃えてくれている。

spansqlfmt Link to heading

コード内のSQLのフォーマットが揃ったら今度はDDLのフォーマットも揃えたくなったため、DDLをフォーマットするツールを作った。

最初はZetaSQLを使おうと思ったが、SpannerのDDLは方言になっているらしく解析できなかったため、とりあえず公式パッケージに含まれている spansql を使用している。

微妙にコメント周りの挙動は怪しいが、それっぽい挙動にはできた。

go-spanner-ddlstructdiff Link to heading

弊社のプロダクトではSpannerのデータ操作に構造体をそのまま使っているため、DDLのカラムと構造体のフィールドはズレないようにする必要があった。

もちろん動作確認をすればズレていることは確認できるものの、実行しないとわからないのは非効率だったため、構造体のフィールドとカラムに差分があれば警告を出すLinterを作った。

単純に同名の有無しか確認しておらず型の比較までは行っていないが、カラムの追加やテーブルの追加時に目検で確認していた差分のチェックの手間は減らせている。

spansqlfmtを作っているときにspansqlへプロダクトのSQLを食わせてみたところ、簡単なものは解析できてもちょっとでも複雑だと解析できないことはわかっていた。

そのため今回のツールはライブラリ選定にちょっと意志を持ち、プロダクトで使われているちょっと凝ったDMLでもParseできた memefish を使って作成した。

感想とか Link to heading

振り返ってみると小さいツールを作るためとはいえ、そこそこSpanner周辺のGoのライブラリに触っていたっぽい。

使ってみてどうもいろいろな歴史的経緯があることは感じていた。

触った限り、SpannerのDDLとDMLを解析する必要のあるツールを1つのライブラリで作ろうと思ったらmemefishしかないのもわかっていた。

仕事も忙しく調べなきゃなぁと思いながら詳細を追えていないそんなとき、ちょうど以下の記事が流れてきた。

https://zenn.dev/apstndb/articles/requirem-for-spansql

まさに自分の知りたかった歴史的経緯が書いてる記事でもあり、個人的にはmemefishを最初の選択肢にいれる安心を貰える記事だった。

業務に使えそうなツールでまだ作りたいものはあったりする。今後は心配せずにmemefishを最初の選択肢として選んでいこうと思う。

最後に、これらのツールを短時間で作ることができたのは、多くの方が公開してくださったライブラリのおかげである。この場を借りて深く感謝の意を表したいと思う。