mirror of https://github.com/go-gorm/gorm.git
fix: auto migration column order unpredictable (#4980)
This commit is contained in:
parent
b47cf57f5e
commit
f757b8fdc9
|
@ -97,11 +97,12 @@ func (m Migrator) AutoMigrate(values ...interface{}) error {
|
||||||
if err := m.RunWithValue(value, func(stmt *gorm.Statement) (errr error) {
|
if err := m.RunWithValue(value, func(stmt *gorm.Statement) (errr error) {
|
||||||
columnTypes, _ := m.DB.Migrator().ColumnTypes(value)
|
columnTypes, _ := m.DB.Migrator().ColumnTypes(value)
|
||||||
|
|
||||||
for _, field := range stmt.Schema.FieldsByDBName {
|
for _, dbName := range stmt.Schema.DBNames {
|
||||||
|
field := stmt.Schema.FieldsByDBName[dbName]
|
||||||
var foundColumn gorm.ColumnType
|
var foundColumn gorm.ColumnType
|
||||||
|
|
||||||
for _, columnType := range columnTypes {
|
for _, columnType := range columnTypes {
|
||||||
if columnType.Name() == field.DBName {
|
if columnType.Name() == dbName {
|
||||||
foundColumn = columnType
|
foundColumn = columnType
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -109,7 +110,7 @@ func (m Migrator) AutoMigrate(values ...interface{}) error {
|
||||||
|
|
||||||
if foundColumn == nil {
|
if foundColumn == nil {
|
||||||
// not found, add column
|
// not found, add column
|
||||||
if err := tx.Migrator().AddColumn(value, field.DBName); err != nil {
|
if err := tx.Migrator().AddColumn(value, dbName); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else if err := m.DB.Migrator().MigrateColumn(value, field, foundColumn); err != nil {
|
} else if err := m.DB.Migrator().MigrateColumn(value, field, foundColumn); err != nil {
|
||||||
|
|
|
@ -2,11 +2,13 @@ package tests_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/schema"
|
||||||
. "gorm.io/gorm/utils/tests"
|
. "gorm.io/gorm/utils/tests"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -454,3 +456,73 @@ func TestMigrateIndexesWithDynamicTableName(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check column order after migration, flaky test
|
||||||
|
// https://github.com/go-gorm/gorm/issues/4351
|
||||||
|
func TestMigrateColumnOrder(t *testing.T) {
|
||||||
|
type UserMigrateColumn struct {
|
||||||
|
ID uint
|
||||||
|
}
|
||||||
|
DB.Migrator().DropTable(&UserMigrateColumn{})
|
||||||
|
DB.AutoMigrate(&UserMigrateColumn{})
|
||||||
|
|
||||||
|
type UserMigrateColumn2 struct {
|
||||||
|
ID uint
|
||||||
|
F1 string
|
||||||
|
F2 string
|
||||||
|
F3 string
|
||||||
|
F4 string
|
||||||
|
F5 string
|
||||||
|
F6 string
|
||||||
|
F7 string
|
||||||
|
F8 string
|
||||||
|
F9 string
|
||||||
|
F10 string
|
||||||
|
F11 string
|
||||||
|
F12 string
|
||||||
|
F13 string
|
||||||
|
F14 string
|
||||||
|
F15 string
|
||||||
|
F16 string
|
||||||
|
F17 string
|
||||||
|
F18 string
|
||||||
|
F19 string
|
||||||
|
F20 string
|
||||||
|
F21 string
|
||||||
|
F22 string
|
||||||
|
F23 string
|
||||||
|
F24 string
|
||||||
|
F25 string
|
||||||
|
F26 string
|
||||||
|
F27 string
|
||||||
|
F28 string
|
||||||
|
F29 string
|
||||||
|
F30 string
|
||||||
|
F31 string
|
||||||
|
F32 string
|
||||||
|
F33 string
|
||||||
|
F34 string
|
||||||
|
F35 string
|
||||||
|
}
|
||||||
|
if err := DB.Table("user_migrate_columns").AutoMigrate(&UserMigrateColumn2{}); err != nil {
|
||||||
|
t.Fatalf("failed to auto migrate, got error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
columnTypes, err := DB.Table("user_migrate_columns").Migrator().ColumnTypes(&UserMigrateColumn2{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to get column types, got error: %v", err)
|
||||||
|
}
|
||||||
|
typ := reflect.Indirect(reflect.ValueOf(&UserMigrateColumn2{})).Type()
|
||||||
|
numField := typ.NumField()
|
||||||
|
if numField != len(columnTypes) {
|
||||||
|
t.Fatalf("column's number not match struct and ddl, %d != %d", numField, len(columnTypes))
|
||||||
|
}
|
||||||
|
namer := schema.NamingStrategy{}
|
||||||
|
for i := 0; i < numField; i++ {
|
||||||
|
expectName := namer.ColumnName("", typ.Field(i).Name)
|
||||||
|
if columnTypes[i].Name() != expectName {
|
||||||
|
t.Fatalf("column order not match struct and ddl, idx %d: %s != %s",
|
||||||
|
i, columnTypes[i].Name(), expectName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue