Skip to content

Commit

Permalink
fix: auto migration column order unpredictable
Browse files Browse the repository at this point in the history
  • Loading branch information
halfcrazy committed Jan 5, 2022
1 parent 4dd2647 commit c04db4a
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 3 deletions.
7 changes: 4 additions & 3 deletions migrator/migrator.go
Expand Up @@ -97,19 +97,20 @@ func (m Migrator) AutoMigrate(values ...interface{}) error {
if err := m.RunWithValue(value, func(stmt *gorm.Statement) (errr error) {
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

for _, columnType := range columnTypes {
if columnType.Name() == field.DBName {
if columnType.Name() == dbName {
foundColumn = columnType
break
}
}

if foundColumn == nil {
// 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
}
} else if err := m.DB.Migrator().MigrateColumn(value, field, foundColumn); err != nil {
Expand Down
72 changes: 72 additions & 0 deletions tests/migrate_test.go
@@ -1,7 +1,9 @@
package tests_test

import (
"gorm.io/gorm/schema"
"math/rand"
"reflect"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -455,3 +457,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)
}
}
}

0 comments on commit c04db4a

Please sign in to comment.