Go言語で堅牢なDBアクセスを実現するためのsqlc活用法
Go言語でデータベース(DB)を扱う際、ORM(Object-Relational Mapping)を利用する選択肢もありますが、内部で発行されるSQLを完全に把握するのが難しいことがあります。これが原因でパフォーマンスの最適化が困難になったり、予期しないバグが発生する可能性があります。
その点、sqlc を使えば、事前に定義したSQLから型安全なGoコードを自動生成でき、より堅牢なシステム構築が可能になります。本記事では、sqlcの概要から具体的な導入方法、実践的な活用方法までを解説します。
sqlcとは?
sqlcは、SQLクエリから型安全なGoコードを生成するツール です。従来のORMのように抽象化するのではなく、明示的に書かれたSQLを解析し、それに対応するGoの型を自動生成するため、以下のようなメリットがあります。
- SQLの最適化を自分でコントロールできる
- 型安全なGoコードを生成し、バグを未然に防ぐ
- ランタイムではなくビルド時にエラーを検出できる
- 余計な抽象化がなく、パフォーマンスが最適化される
sqlcの導入方法
sqlcをプロジェクトに導入するには、以下の手順を実施します。
1. sqlcのインストール
# 最新版のsqlcをインストール
go install github.com/kyleconroy/sqlc/cmd/sqlc@latest
2. 設定ファイルの作成
sqlcの設定ファイル sqlc.yaml
をプロジェクトのルートディレクトリに作成します。
version: "2"
sql:
- engine: "postgresql"
schema: "schema.sql"
queries: "queries.sql"
gen:
go:
package: "db"
out: "internal/db"
この設定では、PostgreSQLをターゲットとし、schema.sql
にスキーマ定義を、queries.sql
にSQLクエリを記述する構成になっています。
3. スキーマとクエリの定義
スキーマ定義(schema.sql)
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL
);
クエリ定義(queries.sql)
-- name: GetUser :one
SELECT * FROM users WHERE id = $1;
-- name: CreateUser :one
INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *;
4. Goコードの生成
以下のコマンドを実行すると、型安全なGoコードが自動生成されます。
sqlc generate
これにより、 internal/db
ディレクトリ内に queries.sql
で定義したSQLに対応するGoの型と関数が生成されます。
sqlcを使ったDBアクセス
生成されたGoコードを使って、データベースの操作を行うサンプルを見てみましょう。
package main
import (
"context"
"database/sql"
"fmt"
"log"
"_ "github.com/lib/pq" // PostgreSQLドライバ
"myapp/internal/db" // 生成されたパッケージ
)
func main() {
connStr := "postgres://user:password@localhost:5432/mydb?sslmode=disable"
conn, err := sql.Open("postgres", connStr)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
queries := db.New(conn)
// ユーザーを作成
newUser, err := queries.CreateUser(context.Background(), db.CreateUserParams{
Name: "Alice",
Email: "alice@example.com",
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Created user: %+v\n", newUser)
// ユーザーを取得
user, err := queries.GetUser(context.Background(), newUser.ID)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Fetched user: %+v\n", user)
}
まとめ
sqlcを使うことで、最適化されたSQLを元に型安全なGoのコードを自動生成 し、予期しないエラーを未然に防ぎつつ、堅牢なDBアクセスを実現できます。
従来のORMのように抽象化しすぎることなく、SQLを明示的に書きつつも、Goの型システムによる安全性を確保できる のが大きなメリットです。パフォーマンスと保守性の両方を重視するプロジェクトでは、sqlcの導入を検討してみる価値があるでしょう。
次のステップとして、実際にプロジェクトに組み込んで試してみてください!
Discussion