Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit da2b286

Browse files
authoredJan 1, 2023
fix(migrator): ignore relationships when migrating #5913 (#5946)
1 parent 7da24d1 commit da2b286

File tree

3 files changed

+99
-22
lines changed

3 files changed

+99
-22
lines changed
 

‎gorm.go

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ type Config struct {
3737
DisableAutomaticPing bool
3838
// DisableForeignKeyConstraintWhenMigrating
3939
DisableForeignKeyConstraintWhenMigrating bool
40+
// IgnoreRelationshipsWhenMigrating
41+
IgnoreRelationshipsWhenMigrating bool
4042
// DisableNestedTransaction disable nested transaction
4143
DisableNestedTransaction bool
4244
// AllowGlobalUpdate allow global update

‎migrator/migrator.go

+33-22
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,11 @@ func (m Migrator) AutoMigrate(values ...interface{}) error {
143143
}
144144
}
145145

146-
for _, rel := range stmt.Schema.Relationships.Relations {
147-
if !m.DB.Config.DisableForeignKeyConstraintWhenMigrating {
146+
if !m.DB.DisableForeignKeyConstraintWhenMigrating && !m.DB.IgnoreRelationshipsWhenMigrating {
147+
for _, rel := range stmt.Schema.Relationships.Relations {
148+
if rel.Field.IgnoreMigration {
149+
continue
150+
}
148151
if constraint := rel.ParseConstraint(); constraint != nil &&
149152
constraint.Schema == stmt.Schema && !queryTx.Migrator().HasConstraint(value, constraint.Name) {
150153
if err := execTx.Migrator().CreateConstraint(value, constraint.Name); err != nil {
@@ -244,8 +247,11 @@ func (m Migrator) CreateTable(values ...interface{}) error {
244247
}
245248
}
246249

247-
for _, rel := range stmt.Schema.Relationships.Relations {
248-
if !m.DB.DisableForeignKeyConstraintWhenMigrating {
250+
if !m.DB.DisableForeignKeyConstraintWhenMigrating && !m.DB.IgnoreRelationshipsWhenMigrating {
251+
for _, rel := range stmt.Schema.Relationships.Relations {
252+
if rel.Field.IgnoreMigration {
253+
continue
254+
}
249255
if constraint := rel.ParseConstraint(); constraint != nil {
250256
if constraint.Schema == stmt.Schema {
251257
sql, vars := buildConstraint(constraint)
@@ -818,26 +824,31 @@ func (m Migrator) ReorderModels(values []interface{}, autoAdd bool) (results []i
818824
}
819825
parsedSchemas[dep.Statement.Schema] = true
820826

821-
for _, rel := range dep.Schema.Relationships.Relations {
822-
if c := rel.ParseConstraint(); c != nil && c.Schema == dep.Statement.Schema && c.Schema != c.ReferenceSchema {
823-
dep.Depends = append(dep.Depends, c.ReferenceSchema)
824-
}
827+
if !m.DB.IgnoreRelationshipsWhenMigrating {
828+
for _, rel := range dep.Schema.Relationships.Relations {
829+
if rel.Field.IgnoreMigration {
830+
continue
831+
}
832+
if c := rel.ParseConstraint(); c != nil && c.Schema == dep.Statement.Schema && c.Schema != c.ReferenceSchema {
833+
dep.Depends = append(dep.Depends, c.ReferenceSchema)
834+
}
825835

826-
if rel.Type == schema.HasOne || rel.Type == schema.HasMany {
827-
beDependedOn[rel.FieldSchema] = true
828-
}
836+
if rel.Type == schema.HasOne || rel.Type == schema.HasMany {
837+
beDependedOn[rel.FieldSchema] = true
838+
}
829839

830-
if rel.JoinTable != nil {
831-
// append join value
832-
defer func(rel *schema.Relationship, joinValue interface{}) {
833-
if !beDependedOn[rel.FieldSchema] {
834-
dep.Depends = append(dep.Depends, rel.FieldSchema)
835-
} else {
836-
fieldValue := reflect.New(rel.FieldSchema.ModelType).Interface()
837-
parseDependence(fieldValue, autoAdd)
838-
}
839-
parseDependence(joinValue, autoAdd)
840-
}(rel, reflect.New(rel.JoinTable.ModelType).Interface())
840+
if rel.JoinTable != nil {
841+
// append join value
842+
defer func(rel *schema.Relationship, joinValue interface{}) {
843+
if !beDependedOn[rel.FieldSchema] {
844+
dep.Depends = append(dep.Depends, rel.FieldSchema)
845+
} else {
846+
fieldValue := reflect.New(rel.FieldSchema.ModelType).Interface()
847+
parseDependence(fieldValue, autoAdd)
848+
}
849+
parseDependence(joinValue, autoAdd)
850+
}(rel, reflect.New(rel.JoinTable.ModelType).Interface())
851+
}
841852
}
842853
}
843854

‎tests/migrate_test.go

+64
Original file line numberDiff line numberDiff line change
@@ -1203,3 +1203,67 @@ func TestMigrateSameEmbeddedFieldName(t *testing.T) {
12031203
_, err = findColumnType(&GameUser{}, "rate_ground_rb_ground_destory_count")
12041204
AssertEqual(t, nil, err)
12051205
}
1206+
1207+
func TestMigrateIgnoreRelations(t *testing.T) {
1208+
type RelationModel1 struct {
1209+
ID uint
1210+
}
1211+
type RelationModel2 struct {
1212+
ID uint
1213+
}
1214+
type RelationModel3 struct {
1215+
ID uint
1216+
RelationModel1ID uint
1217+
RelationModel1 *RelationModel1
1218+
RelationModel2ID uint
1219+
RelationModel2 *RelationModel2 `gorm:"-:migration"`
1220+
}
1221+
1222+
var err error
1223+
_ = DB.Migrator().DropTable(&RelationModel1{}, &RelationModel2{}, &RelationModel3{})
1224+
1225+
tx := DB.Session(&gorm.Session{})
1226+
tx.IgnoreRelationshipsWhenMigrating = true
1227+
1228+
err = tx.AutoMigrate(&RelationModel3{})
1229+
if err != nil {
1230+
t.Errorf("AutoMigrate err:%v", err)
1231+
}
1232+
1233+
// RelationModel3 should be existed
1234+
_, err = findColumnType(&RelationModel3{}, "id")
1235+
AssertEqual(t, nil, err)
1236+
1237+
// RelationModel1 should not be existed
1238+
_, err = findColumnType(&RelationModel1{}, "id")
1239+
if err == nil {
1240+
t.Errorf("RelationModel1 should not be migrated")
1241+
}
1242+
1243+
// RelationModel2 should not be existed
1244+
_, err = findColumnType(&RelationModel2{}, "id")
1245+
if err == nil {
1246+
t.Errorf("RelationModel2 should not be migrated")
1247+
}
1248+
1249+
tx.IgnoreRelationshipsWhenMigrating = false
1250+
1251+
err = tx.AutoMigrate(&RelationModel3{})
1252+
if err != nil {
1253+
t.Errorf("AutoMigrate err:%v", err)
1254+
}
1255+
1256+
// RelationModel3 should be existed
1257+
_, err = findColumnType(&RelationModel3{}, "id")
1258+
AssertEqual(t, nil, err)
1259+
1260+
// RelationModel1 should be existed
1261+
_, err = findColumnType(&RelationModel1{}, "id")
1262+
AssertEqual(t, nil, err)
1263+
1264+
// RelationModel2 should not be existed
1265+
_, err = findColumnType(&RelationModel2{}, "id")
1266+
if err == nil {
1267+
t.Errorf("RelationModel2 should not be migrated")
1268+
}
1269+
}

0 commit comments

Comments
 (0)
Please sign in to comment.