4
votes

I have an core-data app that backs up its sqlite database to Dropbox, and the user can restore it by overwriting their current database if/when they need to.

In the next app release, the core-data model has changed, and the databases for existing users will be automatically updated through the lightweight migration process.

My concern is with the databases that have been backed up already. If a user goes to restore an sqlite database that was backed up before the migration, it will not match the latest model and it will crash the app.

Is there any way that I can update a database during the restore process, to match my core-data model? Either a process that I can run, or some steps that I can take to make sure that the backup is not lost?

2
This is still an issue for me. I am concerned that my users will try to download their old SQLite files and will be irate when they are told that they need to first create a new backup. Can anyone help with this problem? - SAHM
I am trying to solve the same problem...Did you ever come up with a solution for this? - cowfaboo
Yes, actually I just restored the database (as described below) after the lightweight migration had already taken place, and everything worked just fine. I was happily surprised. Have you tried it yet? - SAHM
Brilliant - works much more nicely than I thought, just needed to set a few options when recreating the persistent store. Thanks for the quick response, made me realize the issue was simpler than it sounds! - cowfaboo

2 Answers

1
votes

Lightweight migration does happen automatically if you open a sqlite database with core data. Mostly as part of an application update, but also when you open a restored database.

You could add a check to see if migration is necessary after restore:

-(BOOL) storeRequiresMigration: (NSURL *) storeURL {
NSError *error = nil;
NSPersistentStoreCoordinator * temporaryPersistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

//Check if migration is needed
NSDictionary *sourceMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType URL:storeURL error:&error];
NSManagedObjectModel *destinationModel = [temporaryPersistentStoreCoordinator managedObjectModel];
BOOL isCompatibile = [destinationModel isConfiguration:nil compatibleWithStoreMetadata:sourceMetadata];
NSLog(@"Store requires migration: %d", !isCompatibile);
return !isCompatibile;

}

0
votes

As long are you keeping your previous data model versions in the app, the lightweight migration should take care of this process for you. Judging from your question, I believe this is exactly what the lightweight migration takes care of. It infers the changes from previous data model version and maps your old data into the new data model

In the special case that you wish to rename something in your data model, you can do so using the Renaming ID located in the inspector under "Versioning".