GORM v1 から v2 に移行してみた

ふと思い立って個人プロジェクトの GORM を v1 から v2 に移行してみました。

まずはプロジェクトに GORM v2 をインストールします。

$ go get gorm.io/gorm

import を github.com/jinzhu/gorm から gorm.io/gorm に変更します。 gofmt での一括置換が便利です。

$ gofmt -w -r '"github.com/jinzhu/gorm" -> "gorm.io/gorm"' *.go
-"github.com/jinzhu/gorm"
+"gorm.io/gorm"

ドライバは blank import ではなく普通に import する形になりました。

-_ "github.com/jinzhu/gorm/dialects/postgres"
+"gorm.io/driver/postgres"

ドライバの Open()gorm.Open() で包む形に変更します。

-db, err = gorm.Open("postgres", databaseURL)
+db, err = gorm.Open(postgres.Open(databaseURL), &gorm.Config{})

DDL 系のメソッドは Migrator 配下に移動されたのでそれを介して呼び出します。また、メソッドは直接 error を返すので従来のように Error フィールドから取り出す必要がありません。

-if err := db.DropTable(table).Error; err != nil {
+if err := db.Migrator().DropTable(table); err != nil {

エラーハンドリングは errors.Is() で行います。

-if gorm.IsRecordNotFoundError(err) {
+if errors.Is(err, gorm.ErrRecordNotFound) {

また Postgres に関してはドライバが https://github.com/lib/pq から https://github.com/jackc/pgx に変更になっているので、ドライバに依存したコードがある場合は変更する必要があります。私のプロジェクトではテーブルが見つからなかった場合のテストに修正が必要でした。

-assert.EqualError(t, err, `pq: relation "foo" does not exist`)
+assert.EqualError(t, err, `ERROR: relation "foo" does not exist (SQLSTATE 42P01)

とりあえずこれだけの変更で移行することができました。

メジャーバージョンのアップグレードにしては修正が必要な箇所がかなり少ない印象です。おそらく互換性を意識して API の大規模な変更を避けたのでしょう。

これなら商用プロジェクトでも比較的容易に移行が行えるかもしれませんね。