Migrations fails #234

Closed
opened 2025-12-29 15:27:06 +01:00 by adam · 11 comments
Owner

Originally created by @Miggets7 on GitHub (Oct 12, 2018).

Hi John,

I would like to begin with sayring that I absolutly love CoreStore! It's an awesome project and very nice to use.

I'm having trouble though migrating my models. I'm using v5.3.1 and this is the error log:

2018-10-12 18:30:27.097806+0200 Vigilantia[26402:6772160] [Accessibility] ****************** Loading GAX Client Bundle ****************
2018-10-12 18:30:27.537123+0200 Vigilantia[26402:6772160] [Crashlytics] Version 3.9.3 (128)
Task
2018-10-12 18:30:28.239207+0200 Vigilantia[26402:6772160] [error] error: -addPersistentStoreWithType:SQLite configuration:(null) URL:file:///var/mobile/Containers/Data/Application/7A2FF1DE-E414-4FB7-8A33-51029CA90D9F/Library/Application%20Support/com.appbriek.vigilancebuddy/Vigilantia.sqlite options:{
    NSInferMappingModelAutomaticallyOption = 1;
    NSMigratePersistentStoresAutomaticallyOption = 1;
    NSSQLitePragmasOption =     {
        "journal_mode" = WAL;
    };
    "_NSBinaryStoreInsecureDecodingCompatibilityOption" = 1;
} ... returned error Error Domain=NSCocoaErrorDomain Code=134130 "Persistent store migration failed, missing source managed object model." UserInfo={URL=file:///var/mobile/Containers/Data/Application/7A2FF1DE-E414-4FB7-8A33-51029CA90D9F/Library/Application%20Support/com.appbriek.vigilancebuddy/Vigilantia.sqlite, metadata={
    NSPersistenceFrameworkVersion = 865;
    NSStoreModelVersionHashes =     {
        TapRegistration = <92494ce6 cf7b07fd 9cacc648 cda0066d 145c0dcc d6f87789 38022916 79009c3d>;
        Task = <776b332e a906c8d4 d8e7d811 67b5ea1e 135dcb70 b6e2d66e 80dd607e c912c899>;
    };
    NSStoreModelVersionHashesVersion = 3;
    NSStoreModelVersionIdentifiers =     (
    );
    NSStoreType = SQLite;
    NSStoreUUID = "BE2790F9-0F22-4576-948B-F668B57C6326";
    "_NSAutoVacuumLevel" = 2;
}, reason=Can't find model for source store} with userInfo dictionary {
    URL = "file:///var/mobile/Containers/Data/Application/7A2FF1DE-E414-4FB7-8A33-51029CA90D9F/Library/Application%20Support/com.appbriek.vigilancebuddy/Vigilantia.sqlite";
    metadata =     {
        NSPersistenceFrameworkVersion = 865;
        NSStoreModelVersionHashes =         {
            TapRegistration = <92494ce6 cf7b07fd 9cacc648 cda0066d 145c0dcc d6f87789 38022916 79009c3d>;
            Task = <776b332e a906c8d4 d8e7d811 67b5ea1e 135dcb70 b6e2d66e 80dd607e c912c899>;
        };
        NSStoreModelVersionHashesVersion = 3;
        NSStoreModelVersionIdentifiers =         (
        );
        NSStoreType = SQLite;
        NSStoreUUID = "BE2790F9-0F22-4576-948B-F668B57C6326";
        "_NSAutoVacuumLevel" = 2;
    };
    reason = "Can't find model for source store";
}
CoreData: error: -addPersistentStoreWithType:SQLite configuration:(null) URL:file:///var/mobile/Containers/Data/Application/7A2FF1DE-E414-4FB7-8A33-51029CA90D9F/Library/Application%20Support/com.appbriek.vigilancebuddy/Vigilantia.sqlite options:{
    NSInferMappingModelAutomaticallyOption = 1;
    NSMigratePersistentStoresAutomaticallyOption = 1;
    NSSQLitePragmasOption =     {
        "journal_mode" = WAL;
    };
    "_NSBinaryStoreInsecureDecodingCompatibilityOption" = 1;
} ... returned error Error Domain=NSCocoaErrorDomain Code=134130 "Persistent store migration failed, missing source managed object model." UserInfo={URL=file:///var/mobile/Containers/Data/Application/7A2FF1DE-E414-4FB7-8A33-51029CA90D9F/Library/Application%20Support/com.appbriek.vigilancebuddy/Vigilantia.sqlite, metadata={
    NSPersistenceFrameworkVersion = 865;
    NSStoreModelVersionHashes =     {
        TapRegistration = <92494ce6 cf7b07fd 9cacc648 cda0066d 145c0dcc d6f87789 38022916 79009c3d>;
        Task = <776b332e a906c8d4 d8e7d811 67b5ea1e 135dcb70 b6e2d66e 80dd607e c912c899>;
    };
    NSStoreModelVersionHashesVersion = 3;
    NSStoreModelVersionIdentifiers =     (
    );
    NSStoreType = SQLite;
    NSStoreUUID = "BE2790F9-0F22-4576-948B-F668B57C6326";
    "_NSAutoVacuumLevel" = 2;
}, reason=Can't find model for source store} with userInfo dictionary {
    URL = "file:///var/mobile/Containers/Data/Application/7A2FF1DE-E414-4FB7-8A33-51029CA90D9F/Library/Application%20Support/com.appbriek.vigilancebuddy/Vigilantia.sqlite";
    metadata =     {
        NSPersistenceFrameworkVersion = 865;
        NSStoreModelVersionHashes =         {
            TapRegistration = <92494ce6 cf7b07fd 9cacc648 cda0066d 145c0dcc d6f87789 38022916 79009c3d>;
            Task = <776b332e a906c8d4 d8e7d811 67b5ea1e 135dcb70 b6e2d66e 80dd607e c912c899>;
        };
        NSStoreModelVersionHashesVersion = 3;
        NSStoreModelVersionIdentifiers =         (
        );
        NSStoreType = SQLite;
        NSStoreUUID = "BE2790F9-0F22-4576-948B-F668B57C6326";
        "_NSAutoVacuumLevel" = 2;
    };
    reason = "Can't find model for source store";
}
CoreData: annotation: NSPersistentStoreCoordinator's current model hashes are {
    TapRegistration = <92494ce6 cf7b07fd 9cacc648 cda0066d 145c0dcc d6f87789 38022916 79009c3d>;
    Task = <4aeff274 d1f5b24b b1bb90bc e14b49dc 3164197f 2bae3ebf 43c58756 f8eb384e>;
}
⚠️ [CoreStore: Error] DataStack.swift:352 addStorageAndWait
  ↪︎ Failed to add 'CoreStore.SQLiteStore' to the stack.
    (CoreStore.CoreStoreError) .internalError (
    .errorDomain = "com.corestore.error";
    .errorCode = 4;
    .NSError = (
        .domain = "NSCocoaErrorDomain";
        .code = 134130;
        .userInfo = 3 key-value(s) [
            "URL" = "file:///var/mobile/Containers/Data/Application/7A2FF1DE-E414-4FB7-8A33-51029CA90D9F/Library/Application%20Support/com.appbriek.vigilancebuddy/Vigilantia.sqlite";
            "metadata" = {
                NSPersistenceFrameworkVersion = 865;
                NSStoreModelVersionHashes =     {
                    TapRegistration = <92494ce6 cf7b07fd 9cacc648 cda0066d 145c0dcc d6f87789 38022916 79009c3d>;
                    Task = <776b332e a906c8d4 d8e7d811 67b5ea1e 135dcb70 b6e2d66e 80dd607e c912c899>;
                };
                NSStoreModelVersionHashesVersion = 3;
                NSStoreModelVersionIdentifiers =     (
                );
                NSStoreType = SQLite;
                NSStoreUUID = "BE2790F9-0F22-4576-948B-F668B57C6326";
                "_NSAutoVacuumLevel" = 2;
            };
            "reason" = "Can't find model for source store";
        ];
    );
)

And this is initialization code:

CoreStore.defaultStack = DataStack(
             schemaHistory: SchemaHistory(
                CoreStoreSchema(
                    modelVersion: "V1",
                    entities: [
                        Entity<V1.TaskDBModel>(String(describing: Task.self)),
                        Entity<V1.TapRegistrationDBModel>(String(describing: TapRegistration.self))
                    ],
                    versionLock: [
                        "TapRegistration": [0xfd077bcfe64c4992, 0x6d06a0cd48c6ac9c, 0x8977f8d6cc0d5c14, 0x3d9c007916290238],
                        "Task": [0xd4c806a92e336b77, 0x1eeab56711d8e7d8, 0x6ed6e2b670cb5d13, 0x99c812c97e60dd80]
                    ]
                ),
                CoreStoreSchema(
                    modelVersion: "V2",
                    entities: [
                        Entity<V2.TaskDBModel>(String(describing: Task.self)),
                        Entity<V2.TapRegistrationDBModel>(String(describing: TapRegistration.self))
                    ],
                    versionLock: [
                        "TapRegistration": [0xfd077bcfe64c4992, 0x6d06a0cd48c6ac9c, 0x8977f8d6cc0d5c14, 0x3d9c007916290238],
                        "Task": [0x4bb2f5d174f2ef4a, 0xdc494be1bc90bbb1, 0xbf3eae2b7f196431, 0x4e38ebf85687c543]
                    ]
                ),
              migrationChain: ["V1", "V2"]
            )
        )

        do {
//            try CoreStore.addStorageAndWait()
            try CoreStore.addStorageAndWait(SQLiteStore(fileName: "Vigilantia.sqlite", localStorageOptions: .allowSynchronousLightweightMigration))
        }
        catch {
            print("error setting up storage: \(error)")
        }

And the model code:

typealias TaskDBModel = V2.TaskDBModel
typealias TapRegistrationDBModel = V2.TapRegistrationDBModel

enum V2 {
    class TaskDBModel: CoreStoreObject {

        let testName = Value.Required<String>("testName", initial: "")
        let remark = Value.Optional<String>("remark")
        let date = Value.Required<Date>("date", initial: Date())
        let taps = Relationship.ToManyUnordered<V2.TapRegistrationDBModel>("taps", inverse: { $0.task })
        let age = Value.Optional<Int>("age")
        let sex = Value.Optional<String>("sex")
    }
    class TapRegistrationDBModel: CoreStoreObject {

        let milliseconds = Value.Optional<Int32>("milliseconds", initial: 0)
        let date = Value.Required<Date>("date", initial: Date())
        let task = Relationship.ToOne<V2.TaskDBModel>("task")
    }
}

enum V1 {
    class TaskDBModel: CoreStoreObject {

        let testName = Value.Required<String>("testName", initial: "")
        let remark = Value.Optional<String>("remark")
        let date = Value.Required<Date>("date", initial: Date())
        let taps = Relationship.ToManyUnordered<V1.TapRegistrationDBModel>("taps", inverse: { $0.task })

    }
    class TapRegistrationDBModel: CoreStoreObject {

        let milliseconds = Value.Optional<Int32>("milliseconds", initial: 0)
        let date = Value.Required<Date>("date", initial: Date())
        let task = Relationship.ToOne<V1.TaskDBModel>("task")
    }
}

This used to be the initialization code before(on V5.0):

CoreStore.defaultStack = DataStack(
            CoreStoreSchema(
                modelVersion: "V1",
                entities: [
                    Entity<TaskDBModel>("Task"),
                    Entity<TapRegistrationDBModel>("TapRegistration")
                ]
            )
        )

        do {
            try CoreStore.addStorageAndWait()
        }
        catch {
            print("error setting up storage: \(error)")
        }

Can you tell why it isn't working?

Originally created by @Miggets7 on GitHub (Oct 12, 2018). Hi John, I would like to begin with sayring that I absolutly love CoreStore! It's an awesome project and very nice to use. I'm having trouble though migrating my models. I'm using v5.3.1 and this is the error log: ``` 2018-10-12 18:30:27.097806+0200 Vigilantia[26402:6772160] [Accessibility] ****************** Loading GAX Client Bundle **************** 2018-10-12 18:30:27.537123+0200 Vigilantia[26402:6772160] [Crashlytics] Version 3.9.3 (128) Task 2018-10-12 18:30:28.239207+0200 Vigilantia[26402:6772160] [error] error: -addPersistentStoreWithType:SQLite configuration:(null) URL:file:///var/mobile/Containers/Data/Application/7A2FF1DE-E414-4FB7-8A33-51029CA90D9F/Library/Application%20Support/com.appbriek.vigilancebuddy/Vigilantia.sqlite options:{ NSInferMappingModelAutomaticallyOption = 1; NSMigratePersistentStoresAutomaticallyOption = 1; NSSQLitePragmasOption = { "journal_mode" = WAL; }; "_NSBinaryStoreInsecureDecodingCompatibilityOption" = 1; } ... returned error Error Domain=NSCocoaErrorDomain Code=134130 "Persistent store migration failed, missing source managed object model." UserInfo={URL=file:///var/mobile/Containers/Data/Application/7A2FF1DE-E414-4FB7-8A33-51029CA90D9F/Library/Application%20Support/com.appbriek.vigilancebuddy/Vigilantia.sqlite, metadata={ NSPersistenceFrameworkVersion = 865; NSStoreModelVersionHashes = { TapRegistration = <92494ce6 cf7b07fd 9cacc648 cda0066d 145c0dcc d6f87789 38022916 79009c3d>; Task = <776b332e a906c8d4 d8e7d811 67b5ea1e 135dcb70 b6e2d66e 80dd607e c912c899>; }; NSStoreModelVersionHashesVersion = 3; NSStoreModelVersionIdentifiers = ( ); NSStoreType = SQLite; NSStoreUUID = "BE2790F9-0F22-4576-948B-F668B57C6326"; "_NSAutoVacuumLevel" = 2; }, reason=Can't find model for source store} with userInfo dictionary { URL = "file:///var/mobile/Containers/Data/Application/7A2FF1DE-E414-4FB7-8A33-51029CA90D9F/Library/Application%20Support/com.appbriek.vigilancebuddy/Vigilantia.sqlite"; metadata = { NSPersistenceFrameworkVersion = 865; NSStoreModelVersionHashes = { TapRegistration = <92494ce6 cf7b07fd 9cacc648 cda0066d 145c0dcc d6f87789 38022916 79009c3d>; Task = <776b332e a906c8d4 d8e7d811 67b5ea1e 135dcb70 b6e2d66e 80dd607e c912c899>; }; NSStoreModelVersionHashesVersion = 3; NSStoreModelVersionIdentifiers = ( ); NSStoreType = SQLite; NSStoreUUID = "BE2790F9-0F22-4576-948B-F668B57C6326"; "_NSAutoVacuumLevel" = 2; }; reason = "Can't find model for source store"; } CoreData: error: -addPersistentStoreWithType:SQLite configuration:(null) URL:file:///var/mobile/Containers/Data/Application/7A2FF1DE-E414-4FB7-8A33-51029CA90D9F/Library/Application%20Support/com.appbriek.vigilancebuddy/Vigilantia.sqlite options:{ NSInferMappingModelAutomaticallyOption = 1; NSMigratePersistentStoresAutomaticallyOption = 1; NSSQLitePragmasOption = { "journal_mode" = WAL; }; "_NSBinaryStoreInsecureDecodingCompatibilityOption" = 1; } ... returned error Error Domain=NSCocoaErrorDomain Code=134130 "Persistent store migration failed, missing source managed object model." UserInfo={URL=file:///var/mobile/Containers/Data/Application/7A2FF1DE-E414-4FB7-8A33-51029CA90D9F/Library/Application%20Support/com.appbriek.vigilancebuddy/Vigilantia.sqlite, metadata={ NSPersistenceFrameworkVersion = 865; NSStoreModelVersionHashes = { TapRegistration = <92494ce6 cf7b07fd 9cacc648 cda0066d 145c0dcc d6f87789 38022916 79009c3d>; Task = <776b332e a906c8d4 d8e7d811 67b5ea1e 135dcb70 b6e2d66e 80dd607e c912c899>; }; NSStoreModelVersionHashesVersion = 3; NSStoreModelVersionIdentifiers = ( ); NSStoreType = SQLite; NSStoreUUID = "BE2790F9-0F22-4576-948B-F668B57C6326"; "_NSAutoVacuumLevel" = 2; }, reason=Can't find model for source store} with userInfo dictionary { URL = "file:///var/mobile/Containers/Data/Application/7A2FF1DE-E414-4FB7-8A33-51029CA90D9F/Library/Application%20Support/com.appbriek.vigilancebuddy/Vigilantia.sqlite"; metadata = { NSPersistenceFrameworkVersion = 865; NSStoreModelVersionHashes = { TapRegistration = <92494ce6 cf7b07fd 9cacc648 cda0066d 145c0dcc d6f87789 38022916 79009c3d>; Task = <776b332e a906c8d4 d8e7d811 67b5ea1e 135dcb70 b6e2d66e 80dd607e c912c899>; }; NSStoreModelVersionHashesVersion = 3; NSStoreModelVersionIdentifiers = ( ); NSStoreType = SQLite; NSStoreUUID = "BE2790F9-0F22-4576-948B-F668B57C6326"; "_NSAutoVacuumLevel" = 2; }; reason = "Can't find model for source store"; } CoreData: annotation: NSPersistentStoreCoordinator's current model hashes are { TapRegistration = <92494ce6 cf7b07fd 9cacc648 cda0066d 145c0dcc d6f87789 38022916 79009c3d>; Task = <4aeff274 d1f5b24b b1bb90bc e14b49dc 3164197f 2bae3ebf 43c58756 f8eb384e>; } ⚠️ [CoreStore: Error] DataStack.swift:352 addStorageAndWait ↪︎ Failed to add 'CoreStore.SQLiteStore' to the stack. (CoreStore.CoreStoreError) .internalError ( .errorDomain = "com.corestore.error"; .errorCode = 4; .NSError = ( .domain = "NSCocoaErrorDomain"; .code = 134130; .userInfo = 3 key-value(s) [ "URL" = "file:///var/mobile/Containers/Data/Application/7A2FF1DE-E414-4FB7-8A33-51029CA90D9F/Library/Application%20Support/com.appbriek.vigilancebuddy/Vigilantia.sqlite"; "metadata" = { NSPersistenceFrameworkVersion = 865; NSStoreModelVersionHashes = { TapRegistration = <92494ce6 cf7b07fd 9cacc648 cda0066d 145c0dcc d6f87789 38022916 79009c3d>; Task = <776b332e a906c8d4 d8e7d811 67b5ea1e 135dcb70 b6e2d66e 80dd607e c912c899>; }; NSStoreModelVersionHashesVersion = 3; NSStoreModelVersionIdentifiers = ( ); NSStoreType = SQLite; NSStoreUUID = "BE2790F9-0F22-4576-948B-F668B57C6326"; "_NSAutoVacuumLevel" = 2; }; "reason" = "Can't find model for source store"; ]; ); ) ``` And this is initialization code: ``` CoreStore.defaultStack = DataStack( schemaHistory: SchemaHistory( CoreStoreSchema( modelVersion: "V1", entities: [ Entity<V1.TaskDBModel>(String(describing: Task.self)), Entity<V1.TapRegistrationDBModel>(String(describing: TapRegistration.self)) ], versionLock: [ "TapRegistration": [0xfd077bcfe64c4992, 0x6d06a0cd48c6ac9c, 0x8977f8d6cc0d5c14, 0x3d9c007916290238], "Task": [0xd4c806a92e336b77, 0x1eeab56711d8e7d8, 0x6ed6e2b670cb5d13, 0x99c812c97e60dd80] ] ), CoreStoreSchema( modelVersion: "V2", entities: [ Entity<V2.TaskDBModel>(String(describing: Task.self)), Entity<V2.TapRegistrationDBModel>(String(describing: TapRegistration.self)) ], versionLock: [ "TapRegistration": [0xfd077bcfe64c4992, 0x6d06a0cd48c6ac9c, 0x8977f8d6cc0d5c14, 0x3d9c007916290238], "Task": [0x4bb2f5d174f2ef4a, 0xdc494be1bc90bbb1, 0xbf3eae2b7f196431, 0x4e38ebf85687c543] ] ), migrationChain: ["V1", "V2"] ) ) do { // try CoreStore.addStorageAndWait() try CoreStore.addStorageAndWait(SQLiteStore(fileName: "Vigilantia.sqlite", localStorageOptions: .allowSynchronousLightweightMigration)) } catch { print("error setting up storage: \(error)") } ``` And the model code: ``` typealias TaskDBModel = V2.TaskDBModel typealias TapRegistrationDBModel = V2.TapRegistrationDBModel enum V2 { class TaskDBModel: CoreStoreObject { let testName = Value.Required<String>("testName", initial: "") let remark = Value.Optional<String>("remark") let date = Value.Required<Date>("date", initial: Date()) let taps = Relationship.ToManyUnordered<V2.TapRegistrationDBModel>("taps", inverse: { $0.task }) let age = Value.Optional<Int>("age") let sex = Value.Optional<String>("sex") } class TapRegistrationDBModel: CoreStoreObject { let milliseconds = Value.Optional<Int32>("milliseconds", initial: 0) let date = Value.Required<Date>("date", initial: Date()) let task = Relationship.ToOne<V2.TaskDBModel>("task") } } enum V1 { class TaskDBModel: CoreStoreObject { let testName = Value.Required<String>("testName", initial: "") let remark = Value.Optional<String>("remark") let date = Value.Required<Date>("date", initial: Date()) let taps = Relationship.ToManyUnordered<V1.TapRegistrationDBModel>("taps", inverse: { $0.task }) } class TapRegistrationDBModel: CoreStoreObject { let milliseconds = Value.Optional<Int32>("milliseconds", initial: 0) let date = Value.Required<Date>("date", initial: Date()) let task = Relationship.ToOne<V1.TaskDBModel>("task") } } ``` This used to be the initialization code before(on V5.0): ``` CoreStore.defaultStack = DataStack( CoreStoreSchema( modelVersion: "V1", entities: [ Entity<TaskDBModel>("Task"), Entity<TapRegistrationDBModel>("TapRegistration") ] ) ) do { try CoreStore.addStorageAndWait() } catch { print("error setting up storage: \(error)") } ``` Can you tell why it isn't working?
adam added the not a bug label 2025-12-29 15:27:06 +01:00
adam closed this issue 2025-12-29 15:27:07 +01:00
Author
Owner

@JohnEstropia commented on GitHub (Oct 14, 2018):

I am not sure but I'll throw out some ideas.

First, your versionLock for V2's TapRegistration seem to be the same with V1, which shouldn't be the case.

Second, check your usage of String(describing: Task.self). I don't recommend using non-static strings for entity names because they will break if you refactor your types.

If none of those are the issue, I'm afraid this may be caused by your initialization of dates. (I haven't proved this but I wouldn't be surprised if it was the cause)

let date = Value.Required<Date>("date", initial: Date())

The initial: argument here should be a statically reproducible value (e.g. Date.distantPast), not Date(), which creates the date instance during the time the code was run.

@JohnEstropia commented on GitHub (Oct 14, 2018): I am not sure but I'll throw out some ideas. First, your `versionLock` for V2's `TapRegistration` seem to be the same with V1, which shouldn't be the case. Second, check your usage of `String(describing: Task.self)`. I don't recommend using non-static strings for entity names because they will break if you refactor your types. If none of those are the issue, I'm afraid this may be caused by your initialization of `dates`. (I haven't proved this but I wouldn't be surprised if it was the cause) ```swift let date = Value.Required<Date>("date", initial: Date()) ``` The `initial:` argument here should be a statically reproducible value (e.g. `Date.distantPast`), not `Date()`, which creates the date instance during the time the code was run.
Author
Owner

@scogeo commented on GitHub (Oct 15, 2018):

I'm new to CoreStore myself, but I hit a similar issue when using synchronous migration with CoreStoreObjects. Try switching to the asynchronous CoreStore.addStorage() call instead and see if the problem goes away for you.

I still see get the Core Data error logs on the console, but the migration does proceed correctly. I just chalked those up to spurious logging due to opening an out-of-date store prior to then beginning migration.

@scogeo commented on GitHub (Oct 15, 2018): I'm new to CoreStore myself, but I hit a similar issue when using synchronous migration with `CoreStoreObject`s. Try switching to the asynchronous `CoreStore.addStorage()` call instead and see if the problem goes away for you. I still see get the Core Data error logs on the console, but the migration does proceed correctly. I just chalked those up to spurious logging due to opening an out-of-date store prior to then beginning migration.
Author
Owner

@Miggets7 commented on GitHub (Oct 15, 2018):

@JohnEstropia The versionLock for TapRegistration is the one I got from the output of CoreStore itself. So maybe there is a bug there?

I've changed the String(describing: Task.self) to static strings.

And I've changed the date code to:

let date = Value.Required<Date>("date", initial: Date(timeIntervalSince1970: 0))

And still I'm getting those errors.

@scogeo I've tried with the asynchronous CoreStore.addStorage() call but still the same results. A simple call like CoreStore.fetchAll(From<TaskDBModel>()) fails. It returnsnil

@Miggets7 commented on GitHub (Oct 15, 2018): @JohnEstropia The `versionLock` for `TapRegistration` is the one I got from the output of CoreStore itself. So maybe there is a bug there? I've changed the `String(describing: Task.self`) to static strings. And I've changed the date code to: ``` let date = Value.Required<Date>("date", initial: Date(timeIntervalSince1970: 0)) ``` And still I'm getting those errors. @scogeo I've tried with the asynchronous `CoreStore.addStorage()` call but still the same results. A simple call like `CoreStore.fetchAll(From<TaskDBModel>())` fails. It returns`nil`
Author
Owner

@JohnEstropia commented on GitHub (Oct 15, 2018):

@Miggets7

The versionLock for TapRegistration is the one I got from the output of CoreStore itself. So maybe there is a bug there?

Can you try commenting out the versionLock arguments for both V1 and V2 and check if the hashes are the same?

@JohnEstropia commented on GitHub (Oct 15, 2018): @Miggets7 > The versionLock for TapRegistration is the one I got from the output of CoreStore itself. So maybe there is a bug there? Can you try commenting out the `versionLock` arguments for both V1 and V2 and check if the hashes are the same?
Author
Owner

@Miggets7 commented on GitHub (Oct 15, 2018):

@JohnEstropia These are the versionLock results:

🔸 [CoreStore: Notice] CoreStoreSchema.swift:188 init(modelVersion:entityConfigurations:versionLock:)
  ↪︎ These are hashes for the 'CoreStoreSchema' with version name "V1". Copy the dictionary below and pass it to the 'CoreStoreSchema' initializer's "versionLock" argument:
versionLock: [
    "TapRegistration": [0xfd077bcfe64c4992, 0x6d06a0cd48c6ac9c, 0x8977f8d6cc0d5c14, 0x3d9c007916290238],
    "Task": [0xd4c806a92e336b77, 0x1eeab56711d8e7d8, 0x6ed6e2b670cb5d13, 0x99c812c97e60dd80]
]

🔸 [CoreStore: Notice] CoreStoreSchema.swift:188 init(modelVersion:entityConfigurations:versionLock:)
  ↪︎ These are hashes for the 'CoreStoreSchema' with version name "V2". Copy the dictionary below and pass it to the 'CoreStoreSchema' initializer's "versionLock" argument:
versionLock: [
    "TapRegistration": [0xfd077bcfe64c4992, 0x6d06a0cd48c6ac9c, 0x8977f8d6cc0d5c14, 0x3d9c007916290238],
    "Task": [0xcf35773200b21f75, 0xce61aef165810847, 0x1a435a2d66adaabe, 0x1483319388071899]
]
@Miggets7 commented on GitHub (Oct 15, 2018): @JohnEstropia These are the `versionLock` results: ``` 🔸 [CoreStore: Notice] CoreStoreSchema.swift:188 init(modelVersion:entityConfigurations:versionLock:) ↪︎ These are hashes for the 'CoreStoreSchema' with version name "V1". Copy the dictionary below and pass it to the 'CoreStoreSchema' initializer's "versionLock" argument: versionLock: [ "TapRegistration": [0xfd077bcfe64c4992, 0x6d06a0cd48c6ac9c, 0x8977f8d6cc0d5c14, 0x3d9c007916290238], "Task": [0xd4c806a92e336b77, 0x1eeab56711d8e7d8, 0x6ed6e2b670cb5d13, 0x99c812c97e60dd80] ] 🔸 [CoreStore: Notice] CoreStoreSchema.swift:188 init(modelVersion:entityConfigurations:versionLock:) ↪︎ These are hashes for the 'CoreStoreSchema' with version name "V2". Copy the dictionary below and pass it to the 'CoreStoreSchema' initializer's "versionLock" argument: versionLock: [ "TapRegistration": [0xfd077bcfe64c4992, 0x6d06a0cd48c6ac9c, 0x8977f8d6cc0d5c14, 0x3d9c007916290238], "Task": [0xcf35773200b21f75, 0xce61aef165810847, 0x1a435a2d66adaabe, 0x1483319388071899] ] ```
Author
Owner

@JohnEstropia commented on GitHub (Oct 15, 2018):

@Miggets7 Oops, sorry I've been misreading the entities. The TapRegistration didn't have attribute changes so the same hash should be fine.

Couple of things I'd like to clarify:

do {
            try CoreStore.addStorageAndWait(SQLiteStore(fileName: "Vigilantia.sqlite", localStorageOptions: .allowSynchronousLightweightMigration))
        }
        catch {
            print("error setting up storage: \(error)")
        }

Is error setting up storage: actually being reached here?

Also when you tried to use the asynchronous CoreStore.addStorage() method, were you getting a .failure result from the completion block?

@JohnEstropia commented on GitHub (Oct 15, 2018): @Miggets7 Oops, sorry I've been misreading the entities. The TapRegistration didn't have attribute changes so the same hash should be fine. Couple of things I'd like to clarify: ```swift do { try CoreStore.addStorageAndWait(SQLiteStore(fileName: "Vigilantia.sqlite", localStorageOptions: .allowSynchronousLightweightMigration)) } catch { print("error setting up storage: \(error)") } ``` Is `error setting up storage:` actually being reached here? Also when you tried to use the asynchronous `CoreStore.addStorage()` method, were you getting a `.failure` result from the completion block?
Author
Owner

@Miggets7 commented on GitHub (Oct 15, 2018):

@JohnEstropia
It seems to be working now with the CoreStore.addStorage() call. It does throw an exeption in NSPersistentStoreCoordinator+Setup.swift here:

@nonobjc
    internal func addPersistentStoreSynchronously(_ storeType: String, configuration: ModelConfiguration, URL storeURL: URL?, options: [AnyHashable: Any]?) throws -> NSPersistentStore {
        
        return try self.performSynchronously {
            
            do {
                
                return try self.addPersistentStore(
                    ofType: storeType,
                    configurationName: configuration,
                    at: storeURL,
                    options: options
                )
            }
            catch {
                
                throw CoreStoreError(error)
            }
        }
    }

But it retuns a success call. It seems the data also seems right and running tha app a second time doens't throw any errors. But the completion still return an error object:

Printing description of error.differentStorageExistsAtURL.existingPersistentStoreURL:
▿ (CoreStore.SQLiteStore) (
    .configuration = nil;
    .storeOptions = 2 key-value(s) [
        "_NSBinaryStoreInsecureDecodingCompatibilityOption" = true;
        "NSSQLitePragmasOption" = 1 key-value(s) [
            "journal_mode" = "WAL";
        ];
    ];
    .fileURL = "file:///var/mobile/Containers/Data/Application/C261FF7A-FDA1-49FF-AE48-B7C63C00CB07/Library/Application%20Support/com.appbriek.vigilancebuddy/Vigilantia.sqlite";
    .migrationMappingProviders = 0 item(s) [];
    .localStorageOptions = [.none];
    .fileSize = 32768;
)
  ▿ _url : (CoreStore.SQLiteStore) (
    .configuration = nil;
    .storeOptions = 2 key-value(s) [
        "_NSBinaryStoreInsecureDecodingCompatibilityOption" = true;
        "NSSQLitePragmasOption" = 1 key-value(s) [
            "journal_mode" = "WAL";
        ];
    ];
    .fileURL = "file:///var/mobile/Containers/Data/Application/C261FF7A-FDA1-49FF-AE48-B7C63C00CB07/Library/Application%20Support/com.appbriek.vigilancebuddy/Vigilantia.sqlite";
    .migrationMappingProviders = 0 item(s) [];
    .localStorageOptions = [.none];
    .fileSize = 32768;
)

Right now it seems I can use this without any problem, so I guess this issue could be closed?

@Miggets7 commented on GitHub (Oct 15, 2018): @JohnEstropia It seems to be working now with the `CoreStore.addStorage()` call. It does throw an exeption in NSPersistentStoreCoordinator+Setup.swift here: ``` @nonobjc internal func addPersistentStoreSynchronously(_ storeType: String, configuration: ModelConfiguration, URL storeURL: URL?, options: [AnyHashable: Any]?) throws -> NSPersistentStore { return try self.performSynchronously { do { return try self.addPersistentStore( ofType: storeType, configurationName: configuration, at: storeURL, options: options ) } catch { throw CoreStoreError(error) } } } ``` But it retuns a success call. It seems the data also seems right and running tha app a second time doens't throw any errors. But the completion still return an error object: ``` Printing description of error.differentStorageExistsAtURL.existingPersistentStoreURL: ▿ (CoreStore.SQLiteStore) ( .configuration = nil; .storeOptions = 2 key-value(s) [ "_NSBinaryStoreInsecureDecodingCompatibilityOption" = true; "NSSQLitePragmasOption" = 1 key-value(s) [ "journal_mode" = "WAL"; ]; ]; .fileURL = "file:///var/mobile/Containers/Data/Application/C261FF7A-FDA1-49FF-AE48-B7C63C00CB07/Library/Application%20Support/com.appbriek.vigilancebuddy/Vigilantia.sqlite"; .migrationMappingProviders = 0 item(s) []; .localStorageOptions = [.none]; .fileSize = 32768; ) ▿ _url : (CoreStore.SQLiteStore) ( .configuration = nil; .storeOptions = 2 key-value(s) [ "_NSBinaryStoreInsecureDecodingCompatibilityOption" = true; "NSSQLitePragmasOption" = 1 key-value(s) [ "journal_mode" = "WAL"; ]; ]; .fileURL = "file:///var/mobile/Containers/Data/Application/C261FF7A-FDA1-49FF-AE48-B7C63C00CB07/Library/Application%20Support/com.appbriek.vigilancebuddy/Vigilantia.sqlite"; .migrationMappingProviders = 0 item(s) []; .localStorageOptions = [.none]; .fileSize = 32768; ) ``` Right now it seems I can use this without any problem, so I guess this issue could be closed?
Author
Owner

@scogeo commented on GitHub (Oct 15, 2018):

Just a brief followup to the above comment after some brief investigation on my own prototype. You can suppress the Core Data log messages caused by the throw from the call to addPresistentStore mentioned by @Miggets7 by explicitly declaring a simple CustomSchemaMappingProvider. This will cause a different code path to be taken and avoid the throw and error logs during migration.

In this example, something like this should work:

let storage = SQLiteStore(
  fileName: "Vigilantia.sqlite",
  migrationMappingProviders: [
    CustomSchemaMappingProvider(
      from: "V1",
      to: "V2",
      entityMappings: [
        .transformEntity(sourceEntity: "Task", destinationEntity: "Task", transformer: CustomSchemaMappingProvider.CustomMapping.inferredTransformation),
        .copyEntity(sourceEntity: "TapRegistration", destinationEntity: "TapRegistration")
      ]
    )
  ]
)
@scogeo commented on GitHub (Oct 15, 2018): Just a brief followup to the above comment after some brief investigation on my own prototype. You can suppress the Core Data log messages caused by the throw from the call to `addPresistentStore` mentioned by @Miggets7 by explicitly declaring a simple `CustomSchemaMappingProvider`. This will cause a different code path to be taken and avoid the throw and error logs during migration. In this example, something like this should work: ```swift let storage = SQLiteStore( fileName: "Vigilantia.sqlite", migrationMappingProviders: [ CustomSchemaMappingProvider( from: "V1", to: "V2", entityMappings: [ .transformEntity(sourceEntity: "Task", destinationEntity: "Task", transformer: CustomSchemaMappingProvider.CustomMapping.inferredTransformation), .copyEntity(sourceEntity: "TapRegistration", destinationEntity: "TapRegistration") ] ) ] ) ```
Author
Owner

@JohnEstropia commented on GitHub (Oct 16, 2018):

Ah, I see. There is actually a quirk in lightweight migrations where it fails in addPersistentStore(), but succeeds when using the inferred mapping model that it should have used internally in addPersistentStore(). You'll find that logic here:

screen shot 2018-10-16 at 10 24 54

I'll look for a way to silent these error logs in this case.

@scogeo Thanks for the suggestion to use CustomSchemaMappingProvider. While this would work for your data, there is a tradeoff in memory use here as lightweight migration uses batched SQL queries internally as much as it can, while CustomSchemaMappingProvider recreates all objects one by one. If you have small data it should be more or less the same. (On a separate note, if your models are expected to succeed with an inferred mapping, you can omit the CustomSchemaMappingProvider's entityMappings argument)

@JohnEstropia commented on GitHub (Oct 16, 2018): Ah, I see. There is actually a quirk in lightweight migrations where it fails in `addPersistentStore()`, but succeeds when using the inferred mapping model that it should have used internally in `addPersistentStore()`. You'll find that logic here: <img width="828" alt="screen shot 2018-10-16 at 10 24 54" src="https://user-images.githubusercontent.com/3029684/46987135-c3973400-d12d-11e8-86aa-b76586f56f8b.png"> I'll look for a way to silent these error logs in this case. @scogeo Thanks for the suggestion to use `CustomSchemaMappingProvider`. While this would work for your data, there is a tradeoff in memory use here as lightweight migration uses batched SQL queries internally as much as it can, while `CustomSchemaMappingProvider` recreates all objects one by one. If you have small data it should be more or less the same. (On a separate note, if your models are expected to succeed with an inferred mapping, you can omit the `CustomSchemaMappingProvider`'s `entityMappings` argument)
Author
Owner

@scogeo commented on GitHub (Oct 17, 2018):

@JohnEstropia thank you for looking into the problem further, it would be nice to resolve it so I can use the implicit lightweight migration without any errors in the console logs.

Really enjoying CoreStore so far though!

@scogeo commented on GitHub (Oct 17, 2018): @JohnEstropia thank you for looking into the problem further, it would be nice to resolve it so I can use the implicit lightweight migration without any errors in the console logs. Really enjoying CoreStore so far though!
Author
Owner

@JohnEstropia commented on GitHub (Dec 5, 2018):

I'm closing this issue now, thanks for all the input.

To future developers who would hit this issue, please note that "lightweight migration" somehow has two types in Core Data: one that would succeed synchronously, and one that needs to run an NSInferredMappingModel, which means synchronous migration would not work. I have added a new error CoreStoreError.asynchronousMigrationRequired(localStoreURL:NSError:) thrown from addStorageAndWait() which would indicate this case.

@JohnEstropia commented on GitHub (Dec 5, 2018): I'm closing this issue now, thanks for all the input. To future developers who would hit this issue, please note that "lightweight migration" somehow has two types in Core Data: one that would succeed synchronously, and one that needs to run an `NSInferredMappingModel`, which means synchronous migration would not work. I have added a new error `CoreStoreError.asynchronousMigrationRequired(localStoreURL:NSError:)` thrown from `addStorageAndWait()` which would indicate this case.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/CoreStore#234