Coredata 手动迁移

Posted

技术标签:

【中文标题】Coredata 手动迁移【英文标题】:Coredata manual migration 【发布时间】:2010-09-17 14:16:44 【问题描述】:

我在一个 ios 项目中使用 Core 数据。每当我修改实体属性时,我都会设置用于自动数据迁移的数据模型。但我最近对一些实体关系进行了一些更改,现在我的应用程序崩溃了:“找不到源商店的模型”

我意识到重置应用程序,即删除并重新安装将解决这个问题,我已经有一个实时版本,我的用户将丢失所有数据!

所以现在我正在尝试手动迁移,但 iOS 文档并不是很有帮助。例如,我在创建模型映射后运行了这段代码:

NSURL *destinationStoreURL = [NSURL fileURLWithPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: @"import.sqlite"]];

NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"db.sqlite"]]; 

//initialize migration manager
NSMigrationManager *migrationManager = [[NSMigrationManager alloc] initWithSourceModel:[[self persistentStoreCoordinator] managedObjectModel]
                                                                      destinationModel:[[self persistentStoreCoordinator] managedObjectModel]];

//perform migration     
NSError *error = nil;       
NSMappingModel *mappingModel = [NSMappingModel inferredMappingModelForSourceModel:[[self persistentStoreCoordinator] managedObjectModel]
                                                                 destinationModel:[[self persistentStoreCoordinator] managedObjectModel] error:&error];

if (mappingModel == nil) 
    NSLog(@"No Mapping model error %@, %@", error, [error userInfo]);


[migrationManager migrateStoreFromURL:sourceStoreURL
                                 type:NSSQLiteStoreType
                              options:nil
                     withMappingModel:mappingModel
                     toDestinationURL:destinationStoreURL
                      destinationType:NSSQLiteStoreType
                   destinationOptions:nil
                                error:&error];  

运行此代码可以工作并重置数据库,但我找不到旧数据,当我保存任何新数据时,我收到一个错误,即没有持久存储!

有人有什么想法吗?

【问题讨论】:

Kwame ,我有同样的问题,但我无法解决。这篇文章正是发生在我身上的事情。 【参考方案1】:

这些家伙是对的......

如果还不算太晚,试试这个:打开你的“[你的数据库].xcdatamodel”文件。然后(假设您使用的是 Xcode),转到您的主菜单。选择设计 > 数据模型 > 添加模型版本。这会创建一个新文件,在我们的例子中是“[your database] 2.xcdatamodel”:

现在转到设计 > 数据模型 > 设置当前版本。这样做会告诉 Xcode 这是您将使用的数据库模式。现在进行您想要的任何数据库架构更改。现在可能是在直接影响数据库架构更改的情况下进行任何代码更改的好时机。

现在编译你的程序。这次它应该加载。

我遇到了同样的麻烦。这是我第一次真正阅读 iPhone 开发文档。我不得不真正注意。现在我准备好了。我实际上选择了轻量级迁移。这段代码是直接从 Apple 的一个(或多个)示例程序中劫持的(通常有错误,只是为了让您知道...... :-/ )

 - (NSPersistentStoreCoordinator *)persistentStoreCoordinator  
 if (persistentStoreCoordinator != nil) 
    return persistentStoreCoordinator;
 

 NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory]
      stringByAppendingPathComponent:DATABASENAME]];
 NSError *error;
 persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:      
  [self managedObjectModel]];

 // Allow inferred migration from the original version of the application.
 NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
        [NSNumber numberWithBool:YES], 
        NSMigratePersistentStoresAutomaticallyOption,
        [NSNumber numberWithBool:YES], 
         NSInferMappingModelAutomaticallyOption, nil];

 //ATTENTION: YOU WERE CRASHING HERE...
 if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType 
 configuration:nil URL:storeUrl options:options error:&error]) 
       // Handle the error.
      NSLog(@"WTF??? FAILED to create automatic lightweight migration. Error[%@]", error);
     

【讨论】:

【参考方案2】:

Core Data 将首先检查您的数据模型是否与当前数据存储兼容,但如果您修改了关系,则情况并非如此。您需要首先添加模型版本,这可以通过选择数据模型,然后从菜单中选择选项设计>数据模型>添加模型版本从 Xcode 中完成。您还需要设置模型的当前版本。

Apple 有一些关于迁移的好资源。

【讨论】:

谢谢。我认为您所描述的是自动轻量级迁移,我已经尝试过。它通常会报错:reason = "Can't find model for source store";所以这促使我尝试手动迁移。【参考方案3】:

您是否从设计菜单设置了当前版本?假设选项 NSMigratePersistentStoresAutomaticallyOption 和 NSInferMappingModelAutomaticallyOption 设置为 YES 之后,自动迁移应该可以工作。

【讨论】:

自动迁移不起作用,因为我更改了 mom 文件中的关系。因此,Apple 文档建议我进行手动迁移。所以我创建了一个映射模型,比较了源实体和目标实体。删除不匹配的属性,然后在上面添加手动迁移代码(在注释掉轻量级迁移之后)。这给我留下了一个新的数据库。所以现在我找不到旧数据库了! 我认为我错误地设置了映射管理器和迁移管理器。请看一下上面的代码,看看你的想法。我不确定将什么用作源模型和目标模型。也许问题是我对两者都使用相同的模型!但是目标模型是什么?【参考方案4】:

轻量级迁移:适用于即使按照上述步骤仍然失败的人!

只需确保将您的 DATABASE.sqlite 重命名为与 DATABASE.xcdatamodeld 相同,并将它们放在 Documents 目录下的同一位置:) 祝你好运

【讨论】:

以上是关于Coredata 手动迁移的主要内容,如果未能解决你的问题,请参考以下文章

从 Sqlite 迁移到 CoreData

CoreData:不能轻量级迁移删除实体“没有这样的表”

iOS CoreData 版本升级和数据库迁移

从 sqlite3 迁移到 CoreData?

删除开发中使用的 CoreData 迁移

IOS手动添加CoreData