magicalpanda / MagicalRecord

Super Awesome Easy Fetching for Core Data!
Other
10.79k stars 1.79k forks source link

How to do lightweight migration with MR? #323

Closed ychw closed 11 years ago

ychw commented 11 years ago

I use this statement to start my data store:

    [MagicalRecord setupCoreDataStackWithAutoMigratingSqliteStoreNamed:@"Kotor.sqlite"];

However, after adding an extra field to an entity, the app crashes with error:

Can't merge models with two different entities named ...

What should I do in this case? Is there a general guide to implement lightweight migration in MR? For example, attribute / relationship type changes, attribute name changes, remove / add attributes.

Thanks

casademora commented 11 years ago

This is generally a problem when you did not start with a versioned model. Make sure you:

Another way you may need to get over this if your app is already released is to specify exactly which model file you're using prior to setting up the magical record stack. There is a helper method called setDefaultModelNamed: that will take care of most of the work for you.

This problem happens because there are two models with exactly the same entity names, and core data can't figure out which one is the real one. This is not a magical record problem, but i hope this helps get you going.

Saul

On Nov 28, 2012, at 1:43 AM, YuchenW notifications@github.com wrote:

I use this statement to start my data store:

[MagicalRecord setupCoreDataStackWithAutoMigratingSqliteStoreNamed:@"Kotor.sqlite"];

However, after adding an extra field to an entity, the app crashes with error:

Can't merge models with two different entities named ...

What should I do in this case? Is there a general guide to implement lightweight migration in MR? For example, attribute / relationship type changes, attribute name changes, remove / add attributes.

Thanks

— Reply to this email directly or view it on GitHub.

ychw commented 11 years ago

yeah I delete my app and then create a new model version, and then everything is fine. Fortunately I haven't released my app yet. Thanks!

johnphan commented 11 years ago

What happen if I already submitted the app using setupCoreDataStackWithStoreNamed and want to use auto migration later on?

mdelamata commented 11 years ago

I have the same problem...

I released a version with setupCoreDataStackWithStoreNamed and now I'm trying to use auto migration as well... Someone could help, please? I used setDefaultModelNamed: with no success.

Thanks!

powerje commented 11 years ago

How are you trying to use setDefaultModelNamed?

I'm a bit confused on the proper way myself, I don't see any documentation on it anywhere.

Personally I thought based on the above comments I should setup as normal: [MagicalRecord setupCoreDataStackWithAutoMigratingSqliteStoreNamed:@"MyDb.sqlite"]; and then set the default model name to my new model: [MagicalRecord setDefaultModelNamed:@"MyNewModel.xcdatamodel"];

Either line by itself crashes the app, so reversing the order doesn't help. The first complains about being unable to merge entities (isn't that what the xcmappingmodel is supposed to do?), the second crashes because a file from the bundle (which looks to be the MyNewModel.xcdatamodel) apparently doesn't exist.

I'm not sure what the next step should be. Did you end up fixing your issue @mdelamata?

powerje commented 11 years ago

Okay, I seem to have got something working.

In NSManagedObjectModel+MagicalRecord.m I replaced setting the path in here:

+ (NSManagedObjectModel *) MR_newManagedObjectModelNamed:(NSString *)modelFileName
{
NSString *path = [[NSBundle mainBundle] pathForResource:[modelFileName stringByDeletingPathExtension] 
                                                 ofType:[modelFileName pathExtension]];
NSURL *momURL = [NSURL fileURLWithPath:path];

NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];
return model;
}

with:

NSString* path = [[NSBundle mainBundle] pathForResource:@"MyNewModel" ofType:@"mom"];

Note: that's MyModel without xcdatamodel

In my AppDelegate I'm doing:

[MagicalRecord setDefaultModelNamed:@"MyNewModel.xcdatamodel"];
[MagicalRecord setupCoreDataStackWithAutoMigratingSqliteStoreNamed:@"MyDb.sqlite"];

I'm not sure yet that the migrations are behaving as expected, but I no longer see crashes. I'm also not sure if this is a MagicalRecord bug, or I'm just doing something silly.

woodmister1 commented 11 years ago

@powerje : How have you got on testing your fix? I have just started working with a code base where we have the data layer in a separate common xcodeproj included into my project. I am wanting to point to that model, and store any data and handle any migration inside my project file and not in the common code base. Sounds like this would be a good way to go if you're able to confirm its working as desired.

mdelamata commented 11 years ago

@powerje It was a deeper problem... When you have more than one xcdatamodeld (I have no idea why the project has 2) and you have a light migration in progress it makes you bleed.

My solution was to change the name for the DataBase and assume that some users have to "restore their purchases". Not the best solution at all, but I needed to solve it!

I am so sorry for my delay replying you!!

marianoabdala commented 9 years ago

For the record, I do have two different models that contain an entity with the same name (so, not a versioning issue) and setting: [MagicalRecord setDefaultModelNamed:@"MyModel.momd"];

Right before: [MagicalRecord setupCoreDataStackWithAutoMigratingSqliteStoreNamed:[@"MyDb.sqlite"]];

Fixed it for me.

yasirmturk commented 6 years ago

Solution is MagicalRecord.setDefaultModelNamed("MyApp.momd") MagicalRecord.setupAutoMigratingCoreDataStack()

rockylive commented 6 years ago

For me worked solution was

MagicalRecord.setupCoreDataStack(withAutoMigratingSqliteStoreNamed: "MyDB.sqlite") 
MagicalRecord.setDefaultModelNamed("MyModel.momd")
MagicalRecord.setupAutoMigratingCoreDataStack()