【问题标题】:Core data migration failing with "Can't find model for source store" but managedObjectModel for source is present核心数据迁移失败并显示“找不到源存储模型”但存在源的 managedObjectModel
【发布时间】:2011-05-30 17:56:34
【问题描述】:

我有一个使用 core-data 的 cocoa 应用程序,它现在是其托管对象模型的第 4 版。

我的托管对象模型包含抽象实体,但到目前为止,我已经设法通过创建适当的映射模型并使用 addPersistentStoreWithType:configuration:options:error 并将 NSMigratePersistentStoresAutomaticallyOption 设置为 YES 创建我的持久存储来进行迁移。

NSDictionary *optionsDictionary = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
NSURL *url = [NSURL fileURLWithPath: [applicationSupportFolder stringByAppendingPathComponent: @"MyApp.xml"]];
NSError *error=nil;
[theCoordinator addPersistentStoreWithType:NSXMLStoreType configuration:nil URL:url options:optionsDictionary error:&error]

当我从模型版本 3 迁移到 4 时,这可以正常工作,这是一种涉及向多个实体添加属性的迁移。现在,当我尝试添加新模型版本(版本 5)时,对 addPersistentStoreWithType 的调用返回 nil 并且错误仍然为空。从 4 迁移到 5 涉及添加单个属性。

我正在努力调试问题并检查了以下所有内容;

  1. 源数据库实际上是版本 4,persistentStoreCoordinator 的托管对象模型是版本 5。

  2. 4->5 映射模型以及版本 4 和 5 的托管对象模型存在于我构建的应用程序的资源文件夹中。

  3. 我尝试了各种模型升级路径。奇怪的是,我发现从早期版本 3 -> 5 升级可以工作.. 但从 4 -> 5 升级失败。

  4. 我已尝试添加自定义实体迁移策略以迁移其属性正在更改的实体......在这种情况下,我覆盖了方法 beginEntityMapping:manager:error: 。有趣的是,当迁移工作时(即当我从 3 迁移到 4 或从 3 迁移到 5 时),这个方法确实会被调用,但在失败的情况下(4 到 5 )它不会被调用。

我几乎不知道从哪里开始。任何有助于调试此问题的想法将不胜感激。

【问题讨论】:

    标签: cocoa core-data mapping-model core-data-migration


    【解决方案1】:

    我在这里回答我自己的问题,以防它对某人有所帮助。

    关键问题是,当我达到我的对象模型的第 4 版时,我还向项目中添加了一个额外的托管对象模型。这个附加模型与我的主模型是分开的,仅用于在另一个线程上创建缓存并包含与主模型无关的数据。

    愚蠢地我仍然使用初始化我的 managedObjectModel

    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain]
    

    在我的例子中,它创建了一个模型,其中包含来自我的主模型以及我的其他模型的实体。这些不需要的实体在我的数据库中有它们的版本哈希。当 core-data 然后去寻找一个匹配所有这些哈希的 managedobjectmodel 时,它自然找不到它。

    在我的情况下,解决方案是在迁移之前手动清理我的数据库文件(从不需要的实体中删除版本哈希)..然后将我的 managedObjectModel 加载代码更改为;

    NSString *path = [[NSBundle mainBundle] pathForResource:@"MyDataModel" ofType:@"momd"];
    NSURL *momURL = [NSURL fileURLWithPath:path];
    managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];
    

    【讨论】:

    • Ira,我也遇到了这个问题。当您说您手动清理了数据库文件时,您的意思是您删除了代码中的版本哈希吗?我使用合并模型发布了我以前的数据库版本,所以我不能直接编辑包。
    • 抱歉响应缓慢。是的,我确实清理了代码中的版本哈希。我必须承认我已经很长时间没有真正看过这个了,但我认为我需要这样做,因为合并模型中所有对象的版本哈希都保存在用户数据库中。因此,旧数据库需要在迁移之前清理代码。
    猜你喜欢
    • 2011-04-17
    • 1970-01-01
    • 2016-05-12
    • 1970-01-01
    • 1970-01-01
    • 2014-10-30
    • 1970-01-01
    • 2011-04-04
    • 1970-01-01
    相关资源
    最近更新 更多