How to do lightweight migration with MR? #323

Closed
ychw opened this Issue Nov 28, 2012 · 10 comments

Comments

Projects
None yet
8 participants
@ychw

ychw commented Nov 28, 2012

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

This comment has been minimized.

Show comment Hide comment
@casademora

casademora Nov 28, 2012

Owner

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

  • clean your build
  • reset/delete your test app from your device
  • try again

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.

Owner

casademora commented Nov 28, 2012

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

  • clean your build
  • reset/delete your test app from your device
  • try again

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

This comment has been minimized.

Show comment Hide comment
@ychw

ychw Nov 28, 2012

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!

ychw commented Nov 28, 2012

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!

@casademora casademora closed this Nov 28, 2012

@johnphan

This comment has been minimized.

Show comment Hide comment
@johnphan

johnphan Sep 5, 2013

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

johnphan commented Sep 5, 2013

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

@mdelamata

This comment has been minimized.

Show comment Hide comment
@mdelamata

mdelamata Sep 16, 2013

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!

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

This comment has been minimized.

Show comment Hide comment
@powerje

powerje Oct 1, 2013

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 Oct 1, 2013

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

This comment has been minimized.

Show comment Hide comment
@powerje

powerje Oct 1, 2013

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.

powerje commented Oct 1, 2013

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

This comment has been minimized.

Show comment Hide comment
@woodmister1

woodmister1 Oct 3, 2013

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

@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

This comment has been minimized.

Show comment Hide comment
@mdelamata

mdelamata Oct 3, 2013

@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!!

@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

This comment has been minimized.

Show comment Hide comment
@marianoabdala

marianoabdala Jul 6, 2015

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.

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

This comment has been minimized.

Show comment Hide comment
@yasirmturk

yasirmturk Nov 21, 2017

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

yasirmturk commented Nov 21, 2017

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment