GORM × DynamoDBを実現するGoのライブラリを作ってる話
はじめに
GORMでDynamoDBに接続するためのドライバを作り始めました
GoでDynamoDBのORMと言えばguregu/dynamo
が有名ですが、データソースがDynamoDBであることをコードから隠蔽できるという点でGORMが使える嬉しさはあるかと思います
GORMドライバとは
かみ砕いて言えばRDBMS製品間でのSQLの方言や、SQLドライバの機能の差分を吸収するためのモジュールです
公式が提供しているGORMドライバ(2024/3/25 時点)
- RDB
- PostgreSQL
- MySQL
- SQLServer
- SQLite
- NoSQL
- BigQuery
- ClickHouse
miyamo2/dynmgrm
ではクエリビルダによるクエリ文字列の生成ロジックをカスタムすることでPartiQLによるDynamoDBの操作を実現しています
モチベーション
DynamoDB向けSQLドライバ btnguyen2k/godynamo
を見つけたことがきっかけです
個人プロジェクトでjmoiron/sqlx
と組み合わせて使おうと思ったのですが、同プロジェクトではCockroachDBへの接続にGORMを使っていたので統一したくなってしまい
今回は割愛しますがmiyamo2/dynmgrm
はがっつりbtnguyen2k/godynamo
の巨人の肩に乗っているのでこちらの紹介記事もいつか書きたいな~と思ってます
btnguyen2k/godynamo
の紹介記事はこちら
サポートしている機能
CRUD
README#Features、pkg.go.dev、もしくは結合テストを参照してください
Document型/Set型
List|Map|String Set|Number Set|Binary Setを適切にマーシャル/アンマーシャルするために以下の型を用意しています
dynmgrm.List
dynmgrm.Map
dynmgrm.Set[string|int|float64|[]byte]
マップ、スライスのDefined typeなので既存の構造体も型定義を以下に沿って変えてもらうだけでそのまま移行できます
type Foo struct {
- List []interface{}
+ List dynmgrm.List
- Map map[string]interface{}
+ Map dynmgrm.Map
- SSet []string
+ SSet dynmgrm.Set[string]
- NSet []float64
+ NSet dynmgrm.Set[float64]
- BSet [][]byte
+ BSet dynmgrm.Set[[]byte]
}
SecondaryIndex
GSI/LSIともにdynmgrm.SecondayIndex
で指定することができます
db.Table("somethings").Clauses(
dynmgrm.SecondaryIndex("aught_sk-index"),
).Select("*").Where(`aught=? AND sk=?`, "A", 1).Scan(&result)
サポート未定の機能
DDL、マイグレーションについては現状サポートしておらず、以下の理由から優先度も低めです
- スキーマレスなのでそもそも恩恵が薄い
- (個人的に)DynamoDBであればCFnなりTerraformなりで管理してほしい
また、テーブル結合やサブクエリはPartiQL for DynamoDBがサポートしない限り、miyamo2/dynmgrm
でもサポートしない予定です
---追記---
v0.6.0
Migratior.CreateTable
サポート
v0.8.0
Migrator.CreateIndex
サポート
おわりに
近々の機能追加としてPartiQL独自の関数用のclause.Expr
を実装したいと思ってます
今はまだ趣味レベルのライブラリですが、今後は実務で採用できるレベルまでブラッシュアップしていきたいです
皆さんのイシュー・PRお待ちしてます
Discussion