Core Dataの自動マイグレーション

in

Core Dataの使い始めの頃、マイグレーションには散々苦労したのですがいつの間にか自動マイグレーション機能なんかができていてこれがいたって簡単でした。手順としては

  1. 新しいモデルの作成
  2. マッピングモデルの作成
  3. 自動マイグレーションの指定

の3ステップだけ。

まず新しいモデルを作成する場合ですが、既存のモデルエディタに直接修正を加えるのではなくて、[設計]-[データモデル]-[モデルバージョンを追加]で新しいモデルを作成します。これで、既存のモデルをベースに新しいモデルが作成されますので新しいモデルに必要な修正を加えます。モデルの作成が終了したら[設計]-[データモデル]-[現在のバージョンを設定]で、新しく作成したモデルをカレントモデルに設定します。これが第一段階。

次はマッピングモデルの作成。ある意味、これがマイグレーションの本体となります。[新規ファイル追加]-[リソース]-[マッピングモデル]で新しいマッピングモデルを作成しますが、ここで「ソースモデル」と「デスティネーションモデル」を指定します。「ソースモデル」が既存のモデル、「デスティネーションモデル」が先に作った新しいモデルファイルになります。

このマッピングモデルに(旧)エンティティ(のどのプロパティ)が(新)エンティティ(のプロパティ)にマッピングされるかを記述していくわけです。作成直後の状態では、名前を元にマッピングが作成されているのでこれをベースに必要なマッピングを記述していけばホント簡単にマイグレーションできちゃいます。マッピングは新旧エンティティが一対一にならなくとも良くて、いくつもマッピングを作成することができます。例えばPredicateを指定すれば、ある(旧)エンティティAのうち、条件xに合致するデータは(新)エンティティA'にマッピング、条件yに合致するデータは(新)エンティティA''にマッピングなどということができるわけです。

最後は、コーディネーターに自動でやってねってお願いするのを忘れずに。

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
[persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType 
                            configuration:nil 
                            URL:url
                            options:options
                            error:&err]);

たったこれだけで、エンティティとその属性(もちろん関連も)移行してしかも殆どノーコード。モデルのバリデーション(例えば新しく追加した属性がオプショナルでない場合など)に注意すれば実にスマートな移行ができます。実際のところ、単なる属性追加だけとか非オプションをオプションに変えるだけとかだったらマッピングモデルの作成すら省略することができるなんてサービスしすぎな気がしなくもないです。

さらにはNSEntityMigrationPolicyをオーバーライドしてさらに複雑なマイグレーションのための手段もあるので次回はもう少し複雑なパターンを書いてみようと思ってます。

あっ、v10.4では...ちょっとね、ダメみたいです。悲しいことに。

(参考)Introduction to Core Data Model Versioning and Data Migration Programming Guide

この記事のトラックバックURL:

http://hippos-lab.com/blog/trackback/367

Comments