gpt4 book ai didi

ios - 将大数据集导入核心数据(具有多个存储的解决方案)

转载 作者:行者123 更新时间:2023-12-01 16:50:25 26 4
gpt4 key购买 nike

我知道已经讨论了这个主题,但是我正在寻找一种在任何地方都可以讨论的特定解决方案,即使用多个存储而不是一个存储-一个存储默认数据,另一个存储用户输入的数据。

在我的应用程序中,我想为实体X(仅)预加载大量数据,即20 MB json文件。该模型还包含实体Y和实体Z。我认为最适合我需要的解决方案如下:

使用两个sqlite数据库。仅用于实体X的一个数据库,可以在应用程序的 future 版本中替换该数据库...而不会(毫不费力地)影响实体Y和实体Z的数据。

  • 如何实现这样的解决方案?
  • 实用吗?
  • 我必须要制作两个模型吗?
  • 在这种情况下如何设置核心数据托管对象上下文?

  • 详细信息(以防万一):

    我有两个选择(建议):
  • 将json文件与应用程序捆绑在一起,并在应用程序首次启动时加载
  • 生成一个sqlite数据库,并使用预先填充的数据库
  • 交付应用程序

    对于第一种选择,我有以下担忧:
  • 应用程序启动会很慢(因为解析20 MB文件然后在核心数据中创建相应的记录将需要一些时间)。
  • 一旦使用了文件,就不需要应用程序正在使用的20 MB空间。我不认为有什么要摆脱的文件,有吗?

  • 对于第二种选择,我有以下担忧:
  • 可以说,在我的应用程序的2.0版中,我想更新默认存储。例如,我在1.0版中提供的默认sqlite数据库出现了一些问题,或者我想添加更多“默认”记录?我有多个实体,并且用户可能已将数据添加到其他实体。因此,我无法替换sqlite数据库。那么,我该如何更新数据库中的记录?
  • 最佳答案

    我不知道拥有2个数据库是否真的更好,因为为了扩展功能,您所做的大部分更改不只是一个。

    对于数据库迁移,可以使用类似这样的方法。

    首先使用核心数据的内部版本控制系统,并将当前使用的版本保存在NSUserDefaults中,在我的示例中为infoDictionary(您连接的.plist文件)。因此,您可以先尝试轻量级迁移,然后如果无法自动合并更改,则需要手动进行操作。

    NSNumber *newDbVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"DBVersion"];
    NSNumber *oldDbVersion = [[NSUserDefaults standardUserDefaults] objectForKey:@"DBVersion"];

    NSURL *storeUrlOld;
    if(!oldDbVersion)
    storeUrlOld = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent:@"default.sqlite"]]; // default path
    else
    storeUrlOld = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: [NSString stringWithFormat:@"db_%d.sqlite",[oldDbVersion intValue]]]];

    NSURL *storeUrlNew = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: [NSString stringWithFormat:@"db_%d.sqlite",[newDbVersion intValue]]]];

    NSString *path = [[NSBundle mainBundle] pathForResource:@"myDB" ofType:@"momd"];
    if(oldDbVersion)
    path = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"db_%d.mom", [oldDbVersion intValue]]];

    NSURL *momURLOld = [NSURL fileURLWithPath:path];
    NSLog(@"mom-path old: %@", path);
    NSLog(@"mom-url old: %@", momURLOld);

    NSManagedObjectModel *oldManagedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURLOld];

    // - - -

    path = nil;
    path = [[NSBundle mainBundle] pathForResource:@"db" ofType:@"momd"];
    path = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"db_%d.mom",[newDbVersion intValue]]];

    NSURL *momURLNew = [NSURL fileURLWithPath:path];
    NSLog(@"mom-path new: %@", path);
    NSLog(@"mom-url new: %@", momURLNew);
    NSManagedObjectModel *newManagedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURLNew];

    // # # # # # # # # # # # # # # # # # # # # #
    // - - - - Connect with old Database - - - -
    // # # # # # # # # # # # # # # # # # # # # #

    NSError *error;
    NSPersistentStoreCoordinator *persistentStoreCoordinatorOld = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:oldManagedObjectModel];

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

    if (![persistentStoreCoordinatorOld addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrlOld options:options error:&error])
    {
    // Handle the error
    NSLog(@"Failed to add old persistent store: %@", [error localizedDescription]);
    NSArray* detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey];

    if(detailedErrors != nil && [detailedErrors count] > 0)
    {
    for(NSError* detailedError in detailedErrors) {
    NSLog(@" DetailedError: %@", [detailedError userInfo]);
    }
    }
    else
    {
    NSLog(@"ERROR persistentStoreCoordinator: %@", [error userInfo]);
    }
    return;
    }

    NSManagedObjectContext *oldManagedObjectContext = [[NSManagedObjectContext alloc] init];
    [oldManagedObjectContext setPersistentStoreCoordinator:persistentStoreCoordinatorOld];

    // # # # # # # # # # # # # # # # # # # # # #
    // - - - - Connect with new Database - - - -
    // # # # # # # # # # # # # # # # # # # # # #

    NSPersistentStoreCoordinator *persistentStoreCoordinatorNew = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: newManagedObjectModel];

    if (![persistentStoreCoordinatorNew addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrlNew options:options error:&error])
    {
    // Handle the error
    NSLog(@"Failed to add new persistent store: %@", [error localizedDescription]);
    NSArray* detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey];

    if(detailedErrors != nil && [detailedErrors count] > 0)
    {
    for(NSError* detailedError in detailedErrors) {
    NSLog(@" DetailedError: %@", [detailedError userInfo]);
    }
    }
    else
    {
    NSLog(@"ERROR persistentStoreCoordinator: %@", [error userInfo]);
    }
    return;
    }

    NSManagedObjectContext *newManagedObjectContext = [[NSManagedObjectContext alloc] init];
    [newManagedObjectContext setPersistentStoreCoordinator:persistentStoreCoordinatorNew];
    managedObjectContext = newManagedObjectContext;

    // # # # # # # # # # # # # # # # # # # # # # # #
    // - - - Transfere data from old DB to new - - -
    // # # # # # # # # # # # # # # # # # # # # # # #

    // - - -

    // # # # # # # # # #
    // - - - Users - - -
    // # # # # # # # # #

    NSString *entityName = @"User";
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:oldManagedObjectContext];
    [request setEntity:entity];
    NSString *predicateFormat ;
    NSPredicate *predicate;
    error = nil;

    NSMutableArray *mutableFetchResultsUsers = [NSMutableArray arrayWithArray: [oldManagedObjectContext executeFetchRequest:request error:&error]];

    if (mutableFetchResultsUsers == nil) {
    // Handle the error.
    }
    NSLog(@"Users: %@", mutableFetchResultsUsers);
    for(User *user in mutableFetchResultsUsers)
    {
    NSLog(@"%@, %@, %@",user.userLogin,user.userDomain, user.serverAddress);
    User *userNew = [[DatabaseFactory sharedInstance] newObject:@"User"];
    [...] // do here integration
    userNew.attibute = user.attribute;

    [self saveContext];
    }
    [request release];
    request = nil;

    // next one

    希望我能对您有所帮助;)

    关于ios - 将大数据集导入核心数据(具有多个存储的解决方案),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16522044/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com