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 3c0b0f4
Show file tree
Hide file tree
Showing 2 changed files with 56 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
52 changes: 52 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,53 @@ 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
}
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's number not match struct and ddl, %s != %s",
columnTypes[i].Name(), expectName)
}
}
}

0 comments on commit 3c0b0f4

Please sign in to comment.