Go のクエリビルダ squirrel で IN 句を使ったクエリを書く

February 9, 2022

はじめに

自戒をこめて書きます. Go のクエリビルダ squirrel で IN 句を使ったクエリを書く方法です.

要点

何も考えずに配列を渡せばいい. squirrel がよしなにやってくれる.

q, a, err := squirrel.
 Select("columns").
 From("table_name").
 Where(squirrel.Eq{"some_id": someIds}).
 ToSql()
if err != nil {
 // エラー処理
}

本文

はじめは squirrel を使って IN 句を使ったクエリを書く方法がわからず,素直に内部実装を読めばいいものを未熟な私は gg って解決しようとしました. そこで「sqlx.In を併用することで解決する」旨の記事を見つけました. 私はその内容を鵜呑みにし,しばらく sqlx.In を使ったコードを量産していました.

inq, ina, err := sqlx.In("some_id IN (?)", someIds...)
if err != nil {
 // エラー処理
}
q, a, err := squirrel.Select("columns").From("table_name").Where(inq, ina...).ToSql()
if err != nil {
 // エラー処理
}

あるときにリファクタリングをして貰う機会があり, squirrel.Where および Squirrel.Eq に配列を渡すことでよしなに IN 句を含むクエリを返してくれるので sqlx.In を使わなくてもいいと指摘をいただきました.

q, a, err := squirrel.Select("columns").From("table_name").Where(squirrel.Eq{"some_id": someIds}).ToSql()
if err != nil {
 // エラー処理
}

考えてみたらそうですよね. 広く使われているのに In 句に対応できないわけがない. 大体のクエリビルダってこうなっているんですかね.

困ったときには 内部実装 をしっかり読んでみようと思いました. 読めない量ではないですし,何よりコードは書いたとおりにしか動かないものですし.