はじめに
struct
でモデル定義、AutoMigrate
でマイグレーションを実行、といった辺りで少し調べた部分をメモしておきます。
IDにUUIDを使用するには
UUIDの自動生成をライブラリに任せつつ、テストやシードデータの投入時には固定のUUIDも指定できるようにしたかったため、以下のように対応しました。
まずはstructでのモデルの定義
package model
import (
"github.com/go-playground/validator/v10"
"github.com/google/uuid"
)
type User struct {
ID string `validate:"is_valid_uuid" gorm:"primaryKey;size:255;default:uuid_generate_v4()" json:"id"`
...
}
// IDが渡ってこなければバリデーションをかけず、渡ってきたらUUIDかを確認
validate := validator.New()
validate.RegisterValidation("is_valid_uuid", isValidUUID)
func isValidUUID(fl v.FieldLevel) bool {
id := fl.Field().String()
if len(id) == 0 {
return true
}
_, err := uuid.Parse(id)
return err == nil
}
上記uuid_generate_v4()
を利用するために、AutoMigrate(&User{})
する前にpostgresに拡張機能 uuid-ossp
をインストール
db, err = gorm.Open("postgres", fmt.Sprintf(
"host=%s port=%s user=%s password=%s dbname=%s", host, port, user, password, dbname,
))
if err != nil {
panic(err)
}
db.Exec(`CREATE EXTENSION IF NOT EXISTS "uuid-ossp";`)
result := db.AutoMigrate(&model.User{})
...
Postgresのenum型を使用するには
structのタグで型を指定
type User struct {
Role string `validate:"is_valid_role" gorm:"type:role_enum;default:'user'" json:"role"`
...
}
AutoMigrate
する前にpostgresに型の定義を追加
db.Exec(`
DO
$$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'role_enum') THEN
create type role_enum AS ENUM ('admin', 'editor', 'user');
END IF;
END
$$;
`)
result := db.AutoMigrate(&model.User{})
...
まとめ
GORMのマイグレーションまわりに関してのメモでした。また他にあれば追記していきます。