Migrating Data When Model Hasn't Changed

I have a problem I'm not exactly sure how to phrase well enough to find previous discussions. Hoping this hasn't been done to death, but please point me to previous discussions if that's the case.


I have my Core Data stack set up to migrate step-wise across versions when I deploy a new model version. This is working great. However, I can only reliably get the migration to run when there are non-trivial differences between model versions (e.g., added a new non-optional property to an entity). Otherwise, the auto-migration takes over.


In the cases where auto-migration qualifies, any migration policy or mapping model I provide seems to be ignored. How can I get the migration to acknowledge a custom NSEntityMigrationPolicy so I can do transformations on the data the user has already persisted?


Thanks!

Accepted Reply

I don't think that's quite the right way to put it. What Core Data cares about is whether the data models are equivalent, which is important because it's possible for you to dynamically generate data models. It doesn't actually care that you set the identifier to different values for the two models if they pass the equivalency test.


The details are spelled out in "Understanding Versions" in the "Core Data Model Versioning and Data Migration Programming Guide" (my link broke, sorry).


So if you're trying to do database updates on your schedule, you probably want to organize things so that the Core Data migration is a sub step in your process, not try to squeeze your stuff into substeps of the migration process.

Replies

To further clarify, my persistent store is added with the following options:

let options = [
            NSInferMappingModelAutomaticallyOption: true,
            NSMigratePersistentStoresAutomaticallyOption : true
        ]


Is my only available avenue to disable both of these and perform a manual migration 100% of the time?

When you specify those two options, you're asking Core Data to perform lightweight migration when possible. If you have that turned on, then by the time Core Data gets to your heavyweight migration code, there's nothing to migrate. So you need to turn that off if you want everything to go through heavyweight migration.

Understood. Something else I'm seeing that makes this difficult is - Core Data doesn't seem to actually store a model version number in the persistent store. So if a persistent store LOOKS like v11, Core Data will assume that. Even if the user data was saved with a v10 model. Is this correct?

I don't think that's quite the right way to put it. What Core Data cares about is whether the data models are equivalent, which is important because it's possible for you to dynamically generate data models. It doesn't actually care that you set the identifier to different values for the two models if they pass the equivalency test.


The details are spelled out in "Understanding Versions" in the "Core Data Model Versioning and Data Migration Programming Guide" (my link broke, sorry).


So if you're trying to do database updates on your schedule, you probably want to organize things so that the Core Data migration is a sub step in your process, not try to squeeze your stuff into substeps of the migration process.

Very good. I think I get it now. Thanks!