Core Data 模型版本升級和數據遷移(二)輕量級數據遷移

文章來源:developer.apple.com html

輕量級數據遷移(下稱LM), Core Data 自動執行,適用模型簡單改變(simple changes),包括:實體/表中增長新屬性/字段,LM 與普通遷移原理徹底同樣,只是不須要映射模型(mapping model) (參見 「Mapping Overview」),Core Data 自行推測(infers)版本間的差別。


LM 適用於APP早期開發,那時老是在改變數據結構,同時沒有必要保存一些測試數據。另外一個好處是,當你使用推測模型(inferred model)和 SQLite 存儲時,Core Data 能夠執行就地(in situ)遷移,嚴格講,直接生成並執行 SQL 語句。由於沒有載入任何數據,因此此時能保證效率。 數據結構

LM中 Core Data 必須能推測出映射關係


Core Data 須要可以在運行時找到源和目標的映射關係,通常咱們將數據模型存放在 bundles文件夾中(使用 NSBundle 的 allBundles 和 allFrameworks 方法得到)Core Data能夠找到並發現它,若是放在別的地方,須要按照  「Use a Migration Manager if Models Cannot Be Found Automatically .」 中說的作。Core Data 隨後自動分析現有表和字段的變化,自動產生推測的映射模型(inferred mapping model)。 併發

如下幾種狀況,Core Data 能夠自動推測出: app

  • 添加新屬性/字段 ide

  • 刪除屬性/字段 工具

  • 必填屬性/字段改成可選屬性/字段 測試

  • 可選屬性/字段改成必填屬性/字段,並設置默認值 ui

  • 重命名實體/表或屬性/字段 spa

若是要重命名,須要將新版本中新實體/屬性的「重命名標識符」(renaming identifier)的值設置爲原來的實體名或屬性名。具體方法:Xcode Data Modeling 工具->屬性查看器(property inspector)。能夠想象,這樣作之後,如一個屬性的名字在三次修改中都變化了,且都標記了重命名標識符,這樣無論是從 version 2 到 version 3 仍是從 version 1 到 version 3 均可以無錯誤的遷移。 code

另外,Core Data 還能夠自動猜想出:

  • 增長關係relationship)和 改變關係類型

    • 增長新關係,刪除現有關係

    • 重命名關係名稱 (一樣設置重命名標識符)

    • 改變關係由對一到對多,或者a non-ordered to-many to ordered (反之亦然)

  • 改變實體/表的體系結構

    • 增長、刪除、重命名實體/表

    • 增長新的父、子實體/表,移動屬性/字段的順序

    • 將實體/表移出體系

      注意,不能整合(merge)兩個實體體系(if two existing entities do not share a common parent in the source, they cannot share a common parent in the destination)

使用選項字典(Options Dictionary)請求自動遷移(Automatic Migration)


定義選項字典,將 NSMigratePersistentStoresAutomaticallyOption 和 NSInferMappingModelAutomaticallyOption 兩個鍵值設置爲YES,而後調用 addPersistentStoreWithType:configuration:URL:options:error:

NSError *error = nil;
NSURL *storeURL = <#The URL of a persistent store#>;
NSPersistentStoreCoordinator *psc = <#The coordinator#>;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
 
BOOL success = [psc addPersistentStoreWithType:<#Store type#>
                    configuration:<#Configuration or nil#> URL:storeURL
                    options:options error:&error];
if (!success) {
    // Handle the error.
}

可使用 NSMappingModel 的 inferredMappingModelForSourceModel:destinationModel:error: 方法,獲取推測的映射模型,若是能夠推測出返回,若是不能夠,返回 nil。

若是不能自動找到模型,則使用遷移管理器(Migration Manager)


執行自動遷移,必須保證 Core Data 可以在運行時找到源對象模型和目標對象模型,若是你須要將模型存放於自動搜索範圍以外,那麼須要咱們本身生成推測的模型,並實例化遷移管理器(NSMigrationManager)。以下面的代碼,這些代碼假設已經實現了sourceModel 和 destinationModel,這兩個方法分別返回源對象和目標對象。

- (BOOL)migrateStore:(NSURL *)storeURL toVersionTwoStore:(NSURL *)dstStoreURL error:(NSError **)outError {
 
    // Try to get an inferred mapping model.
    NSMappingModel *mappingModel =
        [NSMappingModel inferredMappingModelForSourceModel:[self sourceModel]
                        destinationModel:[self destinationModel] error:outError];
 
    // If Core Data cannot create an inferred mapping model, return NO.
    if (!mappingModel) {
        return NO;
    }
 
    // Create a migration manager to perform the migration.
    NSMigrationManager *manager = [[NSMigrationManager alloc]
        initWithSourceModel:[self sourceModel] destinationModel:[self destinationModel]];
 
    BOOL success = [manager migrateStoreFromURL:storeURL type:NSSQLiteStoreType
        options:nil withMappingModel:mappingModel toDestinationURL:dstStoreURL
        destinationType:NSSQLiteStoreType destinationOptions:nil error:outError];
 
    return success;
}
相關文章
相關標籤/搜索