fix(migrator): ignore relationships when migrating #5913
This commit is contained in:
		
							parent
							
								
									7da24d1d52
								
							
						
					
					
						commit
						969e2a05e8
					
				
							
								
								
									
										2
									
								
								gorm.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								gorm.go
									
									
									
									
									
								
							@ -37,6 +37,8 @@ type Config struct {
 | 
				
			|||||||
	DisableAutomaticPing bool
 | 
						DisableAutomaticPing bool
 | 
				
			||||||
	// DisableForeignKeyConstraintWhenMigrating
 | 
						// DisableForeignKeyConstraintWhenMigrating
 | 
				
			||||||
	DisableForeignKeyConstraintWhenMigrating bool
 | 
						DisableForeignKeyConstraintWhenMigrating bool
 | 
				
			||||||
 | 
						// IgnoreRelationshipsWhenMigrating
 | 
				
			||||||
 | 
						IgnoreRelationshipsWhenMigrating bool
 | 
				
			||||||
	// DisableNestedTransaction disable nested transaction
 | 
						// DisableNestedTransaction disable nested transaction
 | 
				
			||||||
	DisableNestedTransaction bool
 | 
						DisableNestedTransaction bool
 | 
				
			||||||
	// AllowGlobalUpdate allow global update
 | 
						// AllowGlobalUpdate allow global update
 | 
				
			||||||
 | 
				
			|||||||
@ -143,8 +143,11 @@ func (m Migrator) AutoMigrate(values ...interface{}) error {
 | 
				
			|||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if !m.DB.DisableForeignKeyConstraintWhenMigrating && !m.DB.IgnoreRelationshipsWhenMigrating {
 | 
				
			||||||
					for _, rel := range stmt.Schema.Relationships.Relations {
 | 
										for _, rel := range stmt.Schema.Relationships.Relations {
 | 
				
			||||||
					if !m.DB.Config.DisableForeignKeyConstraintWhenMigrating {
 | 
											if rel.Field.IgnoreMigration {
 | 
				
			||||||
 | 
												continue
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
						if constraint := rel.ParseConstraint(); constraint != nil &&
 | 
											if constraint := rel.ParseConstraint(); constraint != nil &&
 | 
				
			||||||
							constraint.Schema == stmt.Schema && !queryTx.Migrator().HasConstraint(value, constraint.Name) {
 | 
												constraint.Schema == stmt.Schema && !queryTx.Migrator().HasConstraint(value, constraint.Name) {
 | 
				
			||||||
							if err := execTx.Migrator().CreateConstraint(value, constraint.Name); err != nil {
 | 
												if err := execTx.Migrator().CreateConstraint(value, constraint.Name); err != nil {
 | 
				
			||||||
@ -244,8 +247,11 @@ func (m Migrator) CreateTable(values ...interface{}) error {
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if !m.DB.DisableForeignKeyConstraintWhenMigrating && !m.DB.IgnoreRelationshipsWhenMigrating {
 | 
				
			||||||
				for _, rel := range stmt.Schema.Relationships.Relations {
 | 
									for _, rel := range stmt.Schema.Relationships.Relations {
 | 
				
			||||||
				if !m.DB.DisableForeignKeyConstraintWhenMigrating {
 | 
										if rel.Field.IgnoreMigration {
 | 
				
			||||||
 | 
											continue
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
					if constraint := rel.ParseConstraint(); constraint != nil {
 | 
										if constraint := rel.ParseConstraint(); constraint != nil {
 | 
				
			||||||
						if constraint.Schema == stmt.Schema {
 | 
											if constraint.Schema == stmt.Schema {
 | 
				
			||||||
							sql, vars := buildConstraint(constraint)
 | 
												sql, vars := buildConstraint(constraint)
 | 
				
			||||||
@ -818,7 +824,11 @@ func (m Migrator) ReorderModels(values []interface{}, autoAdd bool) (results []i
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		parsedSchemas[dep.Statement.Schema] = true
 | 
							parsedSchemas[dep.Statement.Schema] = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if !m.DB.IgnoreRelationshipsWhenMigrating {
 | 
				
			||||||
			for _, rel := range dep.Schema.Relationships.Relations {
 | 
								for _, rel := range dep.Schema.Relationships.Relations {
 | 
				
			||||||
 | 
									if rel.Field.IgnoreMigration {
 | 
				
			||||||
 | 
										continue
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				if c := rel.ParseConstraint(); c != nil && c.Schema == dep.Statement.Schema && c.Schema != c.ReferenceSchema {
 | 
									if c := rel.ParseConstraint(); c != nil && c.Schema == dep.Statement.Schema && c.Schema != c.ReferenceSchema {
 | 
				
			||||||
					dep.Depends = append(dep.Depends, c.ReferenceSchema)
 | 
										dep.Depends = append(dep.Depends, c.ReferenceSchema)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@ -840,6 +850,7 @@ func (m Migrator) ReorderModels(values []interface{}, autoAdd bool) (results []i
 | 
				
			|||||||
					}(rel, reflect.New(rel.JoinTable.ModelType).Interface())
 | 
										}(rel, reflect.New(rel.JoinTable.ModelType).Interface())
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		valuesMap[dep.Schema.Table] = dep
 | 
							valuesMap[dep.Schema.Table] = dep
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1203,3 +1203,67 @@ func TestMigrateSameEmbeddedFieldName(t *testing.T) {
 | 
				
			|||||||
	_, err = findColumnType(&GameUser{}, "rate_ground_rb_ground_destory_count")
 | 
						_, err = findColumnType(&GameUser{}, "rate_ground_rb_ground_destory_count")
 | 
				
			||||||
	AssertEqual(t, nil, err)
 | 
						AssertEqual(t, nil, err)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestMigrateIgnoreRelations(t *testing.T) {
 | 
				
			||||||
 | 
						type RelationModel1 struct {
 | 
				
			||||||
 | 
							ID uint
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						type RelationModel2 struct {
 | 
				
			||||||
 | 
							ID uint
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						type RelationModel3 struct {
 | 
				
			||||||
 | 
							ID               uint
 | 
				
			||||||
 | 
							RelationModel1ID uint
 | 
				
			||||||
 | 
							RelationModel1   *RelationModel1
 | 
				
			||||||
 | 
							RelationModel2ID uint
 | 
				
			||||||
 | 
							RelationModel2   *RelationModel2 `gorm:"-:migration"`
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						_ = DB.Migrator().DropTable(&RelationModel1{}, &RelationModel2{}, &RelationModel3{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tx := DB.Session(&gorm.Session{})
 | 
				
			||||||
 | 
						tx.IgnoreRelationshipsWhenMigrating = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = tx.AutoMigrate(&RelationModel3{})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Errorf("AutoMigrate err:%v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// RelationModel3 should be existed
 | 
				
			||||||
 | 
						_, err = findColumnType(&RelationModel3{}, "id")
 | 
				
			||||||
 | 
						AssertEqual(t, nil, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// RelationModel1 should not be existed
 | 
				
			||||||
 | 
						_, err = findColumnType(&RelationModel1{}, "id")
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							t.Errorf("RelationModel1 should not be migrated")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// RelationModel2 should not be existed
 | 
				
			||||||
 | 
						_, err = findColumnType(&RelationModel2{}, "id")
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							t.Errorf("RelationModel2 should not be migrated")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tx.IgnoreRelationshipsWhenMigrating = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = tx.AutoMigrate(&RelationModel3{})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Errorf("AutoMigrate err:%v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// RelationModel3 should be existed
 | 
				
			||||||
 | 
						_, err = findColumnType(&RelationModel3{}, "id")
 | 
				
			||||||
 | 
						AssertEqual(t, nil, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// RelationModel1 should be existed
 | 
				
			||||||
 | 
						_, err = findColumnType(&RelationModel1{}, "id")
 | 
				
			||||||
 | 
						AssertEqual(t, nil, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// RelationModel2 should not be existed
 | 
				
			||||||
 | 
						_, err = findColumnType(&RelationModel2{}, "id")
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							t.Errorf("RelationModel2 should not be migrated")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user