核心数据模型迁移步骤

Posted

技术标签:

【中文标题】核心数据模型迁移步骤【英文标题】:Core data model migration steps 【发布时间】:2015-02-11 22:55:03 【问题描述】:

我的迁移遇到了一些问题。 在迁移之前,我的模型中有 2 个表:

食物:名称(字符串)、类别(字符串)等... CartFood:名称(字符串)、类别(字符串)等...

我需要创建一个新实体“类别”并将两个表的类别属性转换为一对多的关系。我还想为 Food 实体添加属性并创建其他实体。

我遵循的步骤如下:

1- 添加模型版本并创建新的类别实体,删除类别属性,创建关系,添加新属性等...

2- 使用相同的代码创建我的自定义实体迁移策略类(它们是 NSEntityMigrationPolicy 的子类)

- (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)sInstance
                                  entityMapping:(NSEntityMapping *)mapping
                                        manager:(NSMigrationManager *)manager
                                          error:(NSError **)error     

    NSLog(@"createDestinationInstancesForSourceInstance");

    // Create a new object for the model context
    NSManagedObject *newObject = [NSEntityDescription insertNewObjectForEntityForName:[mapping destinationEntityName] inManagedObjectContext:[manager destinationContext]];

    // Ancienne catégorie
    NSString* oldCategory = [sInstance valueForKey:@"categorie"];
    NSLog(@"oldCategory : %@", oldCategory);

    // Nouvelle catégorie
    [newObject setValue:nil forKey:@"categorie"]; // Nothing for the moment

    // do the coupling of old and new
    [manager associateSourceInstance:sInstance withDestinationInstance:newObject forEntityMapping:mapping];

    return YES;

3- 创建映射模型

4- 禁用轻量级迁移

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator 
    // Stop that right now if necessary
    if (persistentStoreCoordinator != nil) 
        return persistentStoreCoordinator;
    

    // Store URL
    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"LeSecretDuPoids.sqlite"]];

    // Get store
    NSError *error = nil;
    NSDictionary *options = @ NSMigratePersistentStoresAutomaticallyOption : @YES, NSInferMappingModelAutomaticallyOption : @NO ;
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) 
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    

    return persistentStoreCoordinator;

但是,当我启动新应用程序时,我收到以下错误,并且控制台没有显示任何日志:

CoreData: error: -addPersistentStoreWithType:SQLite configuration:(null)

我错过了什么吗?

问候, 塞巴斯蒂安。

【问题讨论】:

【参考方案1】:

与其在此处对自定义迁移进行故障排除(这可能很困难),我是否建议您简单地忽略这两个字符串属性(或将它们重新用于其他用途)并改用轻量级迁移?

添加存储后,您可以将旧的字符串值复制到关系中,只需几行代码即可将它们归零。例如

// create all necessary category objects
// fetch them and all food objects
for (Food *food in allFoodObjects) 
   Category *category = [allCategories filteredArrayUsingPredicate:
    [NSPredicate predicateWithFormat:@"title = %@", food.oldCategory]].firstObject;
   if (category) 
     food.category = category;
   

// repeat with cartfood

【讨论】:

是否可以使用 NSEntityMigrationPolicy 子类进行轻量级迁移? 如果我忽略这两个字符串,当新商店创建时,类别关系将为空,我将无法获取旧值:/ 不,请阅读我的回答。您必须自己填充新关系。但它确实比使用调试自定义迁移更简单。 如何获取 food.oldCategory 值?在迁移之前,它是一个具有良好价值的字符串集。迁移后,它是一个设置为 nil 的 Category 实体。有没有办法在迁移替换之前获取类别旧值? 它不应该是零。也许您需要在第一次通过时保留名称。

以上是关于核心数据模型迁移步骤的主要内容,如果未能解决你的问题,请参考以下文章

将旧数据模型文件复制到新项目中进行轻量级核心数据迁移

核心数据模型迁移

迁移复杂的核心数据模型

核心数据迁移问题:“持久存储迁移失败,缺少源托管对象模型。”

快速核心数据迁移以更改属性类型

没有找到适合核心数据迁移的映射模型