4

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?

SAHM
  • 4,078
  • 7
  • 41
  • 77
  • 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 Oct 27 '12 at 06:06
  • I am trying to solve the same problem...Did you ever come up with a solution for this? – cowfaboo Feb 05 '13 at 00:52
  • 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 Feb 05 '13 at 04:05
  • 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 Feb 05 '13 at 05:21

2 Answers2

1

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;

}

Bjinse
  • 1,339
  • 12
  • 25
0

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".

brynbodayle
  • 6,546
  • 2
  • 33
  • 49
  • Thanks bbodayle, but to clarify: The user will be manually restoring the sqlite database, replacing it with the database downloaded from Dropbox. Then, I take steps to reset the data based on the newly downloaded database. Nothing happens automatically in this process - no lightweight migration happens here. Lightweight migration only happens when the user updates the app. So, in this case the user has an app where the data has been migrated, and is trying to replace the updated database with an old version of the database. – SAHM Sep 14 '12 at 16:10