Describe the feature
AutoMigrate is useful to migrate database but it runs migration every time even if the table structure (struct define) not changed.
Motivation
The AutoMigrate is prefixed with Auto, which should be more smart. And I found that some prime users like me just use AutoMigrate at the begining of program and image it will skip migration when possible (LOL).
Related Issues
If this feature was too complex to implement, maybe add this to docs?
Comment From: jinzhu
We are trying to achieve this goal, could you create a playground that could reproduce the case?
Comment From: kkocdko
My personal method to run migrate on-demand. Just fit my personal usage.
package main
import (
"encoding/json"
"fmt"
"reflect"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
// MUST keep outputs stable
func GetDefine(v any) string {
t := reflect.TypeOf(v)
ret := "type " + t.Name() + " struct {\n"
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
ret += " " + field.Name + " " + field.Type.Name()
tag := string(field.Tag)
if tag != "" {
ret += " `" + string(field.Tag) + "`"
}
ret += "\n"
}
ret += "}"
return ret
}
func panicErr(v error, msg ...string) {
if v != nil {
if len(msg) != 0 {
fmt.Println(msg[0])
}
panic(v)
}
}
type KeyValue struct {
Key string
Value []byte
}
type FooBar struct {
Field1 string
Field2 int
Field3 byte
}
func initGorm() error {
gormCfg := gorm.Config{}
gormCfg.Logger.LogMode(logger.Info)
dsn := "file:data.db"
d, err := gorm.Open(sqlite.Open(dsn), &gormCfg)
panicErr(err)
// My personal method to run migrate on-demand
defs := map[string]string{}
kv := KeyValue{Key: "db_def"}
if d.First(&kv).Error == nil {
panicErr(json.Unmarshal(kv.Value, &defs))
}
for _, v := range []any{FooBar{}} {
name, def := reflect.TypeOf(v).Name(), GetDefine(v)
if defs[name] != def {
panicErr(d.AutoMigrate(&v))
defs[name] = def
fmt.Printf("AutoMigrate: %v\n", name)
}
}
kv.Value, _ = json.Marshal(defs)
d.Save(&kv)
return nil
}
func main() {
initGorm()
}