How to actually execute CoreData heavyweight migration - ios

I am performing a CoreData heavyweight migration in my app. I have created a mapping model, made associated NSEntityMigrationPolicy subclasses, and selected the new model as the current. However, the migration does not appear to be happening. What do I need to do for this to actually occur?

If your model is not eligible for lightweight migration, then you have to do it manually. Simply this process can explained as reading records from old store and dumping them in the new store according to new model.
See here and here for more details

You have to manually switch off the automatic migrations from persistent store coordinator so core data would not automatically infer mapping model and use your custom created model in core data stack.
key: NSInferMappingModelAutomaticallyOption
value: false

Related

Core data versioning/migration after deleting entities

I have a database which consists of 3 entities, say
'IronMan', 'CaptainAmerica' and 'SpiderMan'.
With new changes, I want to delete all three entities and create another entity called 'Thanos'.
I would not need to use any of the code and data stored earlier with entities 'IronMan', 'CaptainAmerica' and 'SpiderMan'. Do I need to do core data versioning or migration in this case?
As mentioned in Apple's documentation
https://developer.apple.com/documentation/coredata/using_lightweight_migration
You can add, remove, and rename entities in the hierarchy.
So, yes, you need to provide migration (new version model) but can stick to a light-weight migration, hence it will be done automatically based on changes done between the 2 models.

Execute a code after data model migration in Core Data (MagicalRecord)

I have to data models and a mapping model.
I would like to execute some code after the migration is done between my model v11 and model v12.
How can I do that? I'm using Magical Record.
I tried to do it in endEntityMapping from NSEntityMigrationPolicy, but it is an action that should be done after the entire migration, not in the middle.
Another idea I have is to save a flag in NSUserDefaults in any endEntityMapping and use it (and remove the flag) after my Core Data stack is setup by Magical Record, but this seems a bit workaround.

Move a Core Data entity and its data into new Core Data model file through Migration

Is it possible to move a Core Data entity Car and its data in Model1 into a new Core Data model Model2 using migration? Model2 will also have a new CarOwner entity + other new relationships (so model file is different than Model1). Is this possible using lightweight migration or do I have to use custom migration? I'm using Magical Record to setup my Core Data Stack.
I have been using lightweight migration for years with success. So I don't have any custom migration mechanism in place. I want to ask first before I implement a new system so I can incorporate CD custom migration into my existing MagicalRecord Core Data stack.
EDIT: updated question to clarify that Model1 and Model2 have differences.
With the same xcdatamodel file and different versions you can use a Mapping Model file, but being different mom files i guess those are different stacks and migration will not work.
Model migration is only relevant if the model has changed-- meaning, if the entities contained in the data model don't match the entities saved in the persistent store file. Migration doesn't depend on what model file you use, it depends on the entity hashes contained in that model.
Meaning: If your new model file has exactly the same entities as the persistent store file has, you don't actually need to migrate anything. Just start using the new model file. However keep in mind that if you ditch the old model file and all of its old versions, you won't be able to migrate from older versions of that model any more.

Create Core Data entities dynamically during runtime

I need to be able to create new core data entities during runtime. I've written the code to create the objects programmatically, however, I can't add the entities during runtime as the model is immutable.
My problem is similar to this post, however there is no satisfactory answer: How to dyanmic create a new entity (table) via CoreData model?
The documentation regarding changing the core data model explains:
Managed object models are editable until they are used by an object
graph manager (a managed object context or a persistent store
coordinator). This allows you to create or modify them dynamically.
However, once a model is being used, it must not be changed. This is
enforced at runtime—when the object manager first fetches data using a
model, the whole of that model becomes uneditable. Any attempt to
mutate a model or any of its sub-objects after that point causes an
exception to be thrown. If you need to modify a model that is in use,
create a copy, modify the copy, and then discard the objects with the
old model.
However, I'm unclear on what exactly this is saying--that the whole core data model can't be changed once the persistent store coordinator has been used or the attributes/etc of the individual entities can't be changed.
To be clear, I do not want to change the attributes of my current entities, I simply want to add new entities. It just seems weird to me to have to use migration to add new entities.
Any thoughts?
Thanks!
The documentation is pretty clear.
Copy the model.
Apply your changes to the new copy.
Destroy your old MOC, Persistent Store Coordinator, and all objects created from those.
Apply a migration, if necessary.
Create a new Core Data Stack (MOC, PSC, etc) using your updated model.
The migration could be a sticking point, but it should be do-able.

Need some info on how to set up core data migration with a new 1-to-many relationship

Question regarding Core Data migrations:
The original model was just a single entity (Transaction) with multiple properties. The app could store N Transactions, and display them in a table.
Original Core Data Model (simplified):
Transaction:
property_x
property_y
property_z
The model has now been changed so that the new top-level entity is a TransactionsList entity, with a 1-to-many relationship so that each TransactionsList has multiple Transactions.
New Core Data Model (simplified):
TransactionsList:
property_a
property_b
transactions <-->> Transaction:
property_x
property_y
property_z
<- transactionList
The model has now been changed so that the top-level entity is a TransactionsList entity, with a 1-to-many relationship (transactions) so that each TransactionsList has multiple Transactions.
I'm having a problem finding any examples (either in Apple docs, or on the web) of how to set up a migration from the original configuration to this new configuration.
Lightweight migrations don't seem to work (since this change involves adding a new relationship).
I set up a mapping file, and tried to create a custom migration policy, but if I set breakpoints on any of the functions in it, they are never hit.
I turned on migration debugging, and it indicates that the migration succeeded:
"Automatic schema migration succeeded for store at "..."
However, if I look at the internals of the sqlite database, there are no database entries for the TransactionsList entity, and all the transactionList fields in the Transactions (which should be linked to the owning TransactionsList) are null.
Two questions...
1) Any clues as to why my custom entity migration policy might not be getting called
2) Any suggestions on the best way to set up this kind of migration?
Thanks.
You are correct that a light-weight migration will not work. Further, a heavy migration would be very expensive computationally and I would not advise it.
I recommend a two step approach:
Allow a light-weight migration to occur. This will cause your TransactionList entity to be empty.
After the migration, walk through your transactions and create TransactionList entities as appropriate.
This will be faster and easier to test/debug than using a heavy migration. You can test to see if a migration needs to occur using the -[NSManagedObjectModel isConfiguration: compatibleWithStoreMetadata:] method. This will let you know a migration is needed, then you kick off the migration and finally do the post processing.

Resources