79795938

Date: 2025-10-21 14:40:53
Score: 0.5
Natty:
Report link

The main problem here is that, you are using custom migration in wrong way.

0. If your old database was not VersionedSchema already, then migration will not work.
1. Custom migration still migrate data in automatic way, so you don't need to remove or add models by yourself.
2. willMigrate give you access to new context with model V1
3. didMigrate give you access to new context with model V2
4. Doing migrationFromV1ToV2Data = v1Data is nothing else like copying references. After removing it from context with context.delete you are left with empty references.

So you have 2 options:
A)
You should make migrationFromV1ToV2Data: [PersistentIdentifier: Bool] and in willMigrate copy current property1 with modelID.

  
    private static var migrationFromV1ToV2Data: [PersistentIdentifier: Bool] = [:]
    
    static let migrateFromV1ToV2 = MigrationStage.custom(
        fromVersion:    MyDataSchemaV1.self,
        toVersion:      MyDataSchemaV2.self,
        willMigrate:
        {
            modelContext in
            
            let descriptor  : FetchDescriptor<MyDataV1>    = FetchDescriptor<MyDataV1>()
            let v1Data      : [MyDataV1]                   = try modelContext.fetch(descriptor)
            
            v1Data.forEach {
                migrationFromV1ToV2Data[$0.persistentModelID] = $0.property1
            }
        },
        didMigrate:
        {
            modelContext in

            for (id, data) in migrationFromV1ToV2Data{
                if let model: MyDataV2 = modelContext.registeredModel(for: id) {
                    model.property1 = [data]
                }
            }

            try? modelContext.save()
        }
    )
}

B)
Create V2 model from V1 in willMigrate, and populate into new context in didMigrate.

  
    private static var migrationFromV1ToV2Data: [MyDataV2] = []
    
    static let migrateFromV1ToV2 = MigrationStage.custom(
        fromVersion:    MyDataSchemaV1.self,
        toVersion:      MyDataSchemaV2.self,
        willMigrate:
        {
            modelContext in
            
            let descriptor  : FetchDescriptor<MyDataV1>    = FetchDescriptor<MyDataV1>()
            let v1Data      : [MyDataV1]                   = try modelContext.fetch(descriptor)
            
            migrationFromV1ToV2Data = v1Data.map{ MyDataV2(myDataV1: $0) }
            
            try modelContext.delete(model: MyDataV1.self)
            try modelContext.save()
        },
        didMigrate:
        {
            modelContext in

            migrationFromV1ToV2Data.forEach
            {
                modelContext.insert($0)
            }
            
            try modelContext.save()
        }
    )
}

I had problem with relationships in one of my migration where i need to use option B, but in most cases opt A is enough.

Reasons:
  • Blacklisted phrase (0.5): i need
  • Long answer (-1):
  • Has code block (-0.5):
  • Unregistered user (0.5):
  • Low reputation (1):
Posted by: Chris