2

我有一个目前正在生产使用的应用程序。我对该应用程序的核心数据模型的下一个版本进行了重大更改。

为了避免从旧数据模型到新数据模型的大量转换工作,我只是简单地重命名了新的对象模型和数据库,从而导致新版本的应用程序不再引用旧数据库(这不是问题,因为旧的数据库数据很小,不需要)。

但是,我确实需要旧数据库中的一条数据,并且我不希望用户需要手动将其重新输入到新数据库中。

我的问题:我有哪些选择可以将这条数据放入新数据库?

我可以对 sqlite 数据库运行查询并简单地输入新数据库吗?还是我需要创建一个完整的其他持久存储和对象模型来提取数据?

还是我一起错过了什么?

4

3 回答 3

1

似乎您只需要在用户首次运行更新的应用程序时将数据复制到新数据库即可。那时你可能会清除旧的,所以它会占用空间。不知道还需要什么更复杂的解决方案。似乎足够了。

于 2012-11-29T16:08:00.820 回答
1

我同意,我认为您应该使用核心数据连接到旧数据库并提取数据,然后将其移动到新数据库。完成后,您应该使用以下内容删除旧的数据库文件(注意我假设您将核心数据结果存储到 SQLite 中):

- (NSURL *)urlForDocumentsDirectoryWithFile:(NSString *)fileName {
    NSURL *docPath = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
    return [docPath URLByAppendingPathComponent:fileName];
}

- (void)deleteFileFromDocumentsIfExists:(NSString *)fileName {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSURL *filePath = [self urlForDocumentsDirectoryWithFile:fileName];
    NSLog(@"Deleting file: %@", filePath.absoluteString);
    if ([fileManager fileExistsAtPath:[filePath path]])
    {
        BOOL success = [fileManager removeItemAtURL:filePath error:&error];
        if (!success) NSLog(@"Error: %@", [error localizedDescription]);
    }
}

删除代码:

[self deleteFileFromDocumentsIfExists:@"MyOldDatabaseName.sqlite"];

如果您只使用一次旧的对象模型,我不会担心拥有 2 个对象模型......永远。我可以看到在您的应用程序中“使用一次”代码是一种浪费,但即使跳过核心数据并手动查询仍然需要您拥有它。

另外,我有一个 DataAccessManager 单元,我将所有核心数据的荒谬初始化代码转储到其中,这样我就可以轻松访问多个上下文,如果您担心您正在手动编写所有内容,您可能希望将其移动到一个可共享的单元。

于 2012-11-29T16:17:02.280 回答
0

感谢以上两个建议。我最终使用以下方法来解决我的问题:

脚步:

  • 尝试连接到旧的 SQLite 数据库。
  • 如果连接成功,读取记录。
  • 在托管对象上下文中创建一个新的托管对象。
  • 使用 sql 结果中的值填充托管对象中的值。
  • 持久化托管对象。
  • 删除旧数据库。
NSString *dbFilePath = [[self applicationDocumentsDirectoryString] stringByAppendingPathComponent:@"RPS.sqlite"];

sqlite3 *数据库;

if (sqlite3_open([dbFilePath UTF8String], &database)) {
    NSLog(@"sqlite3_open: 失败");
} 别的 {
    NSString *nsquery = [[NSString alloc] initWithFormat:@"SELECT * FROM ztable"];
    const char *query = [nsquery UTF8String];

    sqlite3_stmt *语句;
    int prepareCode = (sqlite3_prepare_v2(database, query, -1, &statement, NULL));
    如果(准备代码 == SQLITE_OK){
        我的表 *myTableRecord;
        NSLog(@"即将开始添加数据");
        而(sqlite3_step(语句)== SQLITE_ROW)
        {
            NSLog(@"**************** 行返回 ******************");

            myObject = [NSEntityDescription insertNewObjectForEntityForName:@"myTable" inManagedObjectContext:self.managedObjectContext];

            [myTable setValue:[NSString stringWithFormat:@"%s",(char *)sqlite3_column_text(statement, 7)] forKey:@"field1"];
            [myTable setValue:[NSString stringWithFormat:@"%s",(char *)sqlite3_column_text(statement, 8)] forKey:@"field2"];

            [自我保存上下文];

        }

        sqlite3_finalize(语句);
        NSLog(@"添加了 sqlite3 数据");
    } 别的 {
        NSLog(@"准备代码不正确:%d",prepareCode);
    }

    NSError *错误;
    NSFileManager *filemgr = [[NSFileManager alloc] init];
    [filemgr removeItemAtPath:dbFilePath 错误:&err];
    NSLog(@"删除了旧的 sqlite3 数据库");
}
于 2012-11-29T18:58:20.363 回答