【问题标题】:SQLite to Core Data MigrationSQLite 到核心数据的迁移
【发布时间】:2016-12-16 10:19:13
【问题描述】:

我在 App Store 上有一个实时应用程序,它使用 SQLite 作为数据库,现在我想在下一次更新中实现 Core Data 在应用程序中加载来自 .sqlite 的所有数据文件而不破坏应用程序。我一直在阅读教程,但没有太大帮助。我不知道该怎么做。请指出正确的方向。

【问题讨论】:

  • 为什么?你认为你会得到什么好处?您现有的 SQL 解决方案是否正常工作?有什么不能做的吗?

标签: ios objective-c swift sqlite core-data


【解决方案1】:

我认为@SaintThread 在这里解决了主要问题。原因是 Core Data 不是 SQLite 的包装器——它是一个不同的 API,有不同的假设,只是碰巧在内部使用 SQLite。如果您单独使用 SQLite,Core Data 不会尝试与您使用 SQLite 的方式兼容。

也就是说,如果您仍想迁移,则必须设计一个 Core Data 模型,然后编写完全自定义的代码以从现有 SQLite 文件迁移到 Core Data。您的代码需要从 SQLite 读取所有内容,将其转换为新的 Core Data 表示,保存更改,然后删除现有的 SQLite 文件。

删除现有 SQLite 文件时,请确保同时删除 SQLite 日志文件(如果有)。

【讨论】:

    【解决方案2】:

    来自核心数据documentation

    如何将现有的 SQLite 数据库与 Core Data 一起使用?

    除非您将现有的 SQLite 数据库导入到 核心数据存储。虽然 Core Data 支持 SQLite 作为它的一种 持久存储类型,数据库格式是私有的。你不能 使用原生 SQLite API 创建 SQLite 数据库并使用它 直接使用核心数据。如果你有一个现有的 SQLite 数据库,你 需要将其导入核心数据存储。此外,不要 使用本机操作现有的 Core Data 创建的 SQLite 存储 SQLite API

    您可以尝试使用工具https://github.com/tapasya/Sqlite2CoreData,但它似乎已经过时了。

    【讨论】:

      【解决方案3】:

      难度主要取决于您的代码架构设置得有多好。没有简单的程序可以做到这一点...... 将 Core 数据添加到项目中如果相当简单,理解它是另一回事。

      您可能需要注意以下几点:

      • CoreData 以自己的方式创建 sqlite 文件,这意味着您不能向其提供任何 .sqlite 文件并希望获得最好的结果。您必须让 CoreData 创建自己的文件并将数据从您的 sqlite 存储传输到核心数据的存储。

      • 你的表变成类(在大多数 ORM 中,它被称为实体),你不能直接实例化一个新实体,这意味着如果你有一个表 Employee,你不能做 Employee * john = [[Employee alloc]在里面];那不行!插入元素是 NSEntityDescriptpion 类的职责。因此,请检查您的代码是否存在可能的错误...

      如果核心数据有点复杂,Realm 是一个不错的 ORM 替代方案:https://realm.io/products/objc/

      祝你好运……

      【讨论】:

        【解决方案4】:

        这是我认为最好的工作方式;但请确保在 throws 上使用良好的错误处理。

        这是来自 Apple 的原始方式:

        https://developer.apple.com/library/content/samplecode/CoreDataBooks/Listings/Classes_CoreDataBooksAppDelegate_m.html#//apple_ref/doc/uid/DTS40008405-Classes_CoreDataBooksAppDelegate_m-DontLinkElementID_8

        NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreDataBooks.CDBStore"];
        
        /*
         Set up the store.
         For the sake of illustration, provide a pre-populated default store.
         */
        NSFileManager *fileManager = [NSFileManager defaultManager];
        // If the expected store doesn't exist, copy the default store.
        if (![fileManager fileExistsAtPath:[storeURL path]]) {
            NSURL *defaultStoreURL = [[NSBundle mainBundle] URLForResource:@"CoreDataBooks" withExtension:@"CDBStore"];
            if (defaultStoreURL) {
                [fileManager copyItemAtURL:defaultStoreURL toURL:storeURL error:NULL];
            }
        }
        
        NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption: @YES, NSInferMappingModelAutomaticallyOption: @YES};
        _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
        
        NSError *error;
        if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
        

        ....

        这些是新的方式--Xcode8

        Swift 3 preload from SQL files in appDelegate

        Core Data with pre-filled .sqlite (Swift3)

        Why does not copy database.db from bundle to document directory in swift 3?

        https://www.raywenderlich.com/145877/core-data-tutorial-multiple-managed-object-contexts-2

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-09-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-22
          • 2023-03-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多