GORM × DynamoDB

2024/03/26に公開

はじめに

GORMでDynamoDBに接続するためのドライバを作り始めました

GoでDynamoDBのORMと言えばguregu/dynamoが有名ですが、データソースがDynamoDBであることをコードから隠蔽できるという点でGORMが使える嬉しさはあるかと思います

https://github.com/miyamo2/dynmgrm

GORMドライバとは

かみ砕いて言えばRDBMS製品間でのSQLの方言や、SQLドライバの機能の差分を吸収するためのモジュールです

https://gorm.io/ja_JP/docs/write_driver.html

公式が提供しているドライバ(2024/3/25 時点)

  • RDB
    • PostgreSQL
    • MySQL
    • SQLServer
    • SQLite
  • NoSQL
    • BigQuery
    • ClickHouse

miyamo2/dynmgrmではクエリビルダによるクエリ文字列の生成ロジックをカスタムすることでPartiQLによるDynamoDBの操作を実現しています

モチベーション

DynamoDB向けSQLドライバ btnguyen2k/godynamoを見つけたことがきっかけです

https://github.com/btnguyen2k/godynamo

個人プロジェクトでjmoiron/sqlxと組み合わせて使おうと思ったのですが、同プロジェクトではCockroachDBへの接続にGORMを使っていたので統一したくなってしまい

今回は割愛しますがmiyamo2/dynmgrmはがっつりbtnguyen2k/godynamoの巨人の肩に乗っているのでこちらの紹介記事もいつか書きたいな~と思ってます

サポートしている機能

CRUD

README#Featurespkg.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=?, sk=?`, "A", 1).Scan(&result)

サポート未定の機能

DDL、マイグレーションについては現状サポートしておらず、以下の理由から優先度も低めです

  • スキーマレスなのでそもそも恩恵が薄い
  • (個人的に)DynamoDBであればCFnなりTerraformなりで管理してほしい

また、テーブル結合やサブクエリはPartiQL for DynamoDBがサポートしない限り、miyamo2/dynmgrmでもサポートしない予定です

おわりに

近々の機能追加としてPartiQL独自の関数用のclause.Exprを実装したいと思ってます

今はまだ趣味レベルのライブラリですが、今後は実務で採用できるレベルまでブラッシュアップしていきたいです
皆さんのイシュー・PRお待ちしてます

Discussion