Realm オブジェクト スキーマの更新 - Flutter SDK
項目一覧
Realm オブジェクトは最初に作成した後、そのスキーマを変更できます。 スキーマに加える変更のタイプに応じて、変更を自動的に適用するか、新しいスキーマへの手動更新が必要になります。 Realm では手動スキーマ更新は移行と呼ばれます。
Realm オブジェクトモデルからプロパティを追加または削除すると、Realm オブジェクト スキーマを自動的に更新できます。 詳しくは、「 スキーマの自動更新 」セクションを参照してください。
他のすべてのスキーマ変更は手動移行で実行する必要があります。 詳細については、「スキーマの手動移行 」セクションを参照してください。
Tip
開発中のバイパス移行
アプリケーションを開発またはデバッグする際には、Realm を移行するのではなく、Realm を削除することをお勧めします。 LocalConfiguration.ShouldDeleteIfMigrationNeted を使用するスキーマの不一致により移行が必要な場合に、データベースを自動的に削除するプロパティ。
重要
同期された Realm のスキーマ プロパティの変更
このページの内容は、ローカル Realm にのみ適用されます。 Atlas Device Sync を使用して MongoDB Atlas とデータを同期する Realm のスキーマ移行機能は異なります。 「 同期された Realm のスキーマの更新」セクションを参照してください。
スキーマ バージョン
スキーマ バージョンは、ある時点におけるRealm スキーマの状態を識別します。 Realm は各 Realm のスキーマ バージョンを追跡し、それを使用して各 Realm 内のオブジェクトを正しいスキーマにマッピングします。
スキーマ バージョンは昇順の整数であり、Realm を開くときに Realm 構成に任意で含めることができます。 クライアント アプリケーションが Realm を開くときにバージョン番号を指定しない場合、Realm はデフォルトでバージョン 0
になります。
手動移行では、Realm をより高いスキーマ バージョンに更新する必要があります。 Realm は、Realm の現在のバージョンよりも低いスキーマ バージョンでクライアント アプリケーションが Realm を開き、または指定されたスキーマ バージョンが Realm の現在のバージョンと同じであるが、異なるオブジェクト スキーマを含む場合にエラーをスローします。
スキーマの自動更新
Realm は、追加および削除されたプロパティを自動的に移行できます。 このような変更を行う場合は、スキーマのバージョンを更新する必要があります。
プロパティを追加する
スキーマにプロパティを追加するには
オブジェクトの
RealmModel
クラスに新しいプロパティを追加します。
例
スキーマ バージョン1
を使用する Realm には、 firstName
とlastName
プロパティを持つPerson
オブジェクトタイプがあります。 開発者は、 _Person
RealmModel クラスにage
プロパティを追加することを決定します。
更新されたPerson
スキーマに準拠するように Realm を変更するには、開発者は Realm のスキーマ バージョンを2
に設定します。
()class _Person { late String firstName; late String lastName; late int age; }
final config = Configuration.local([Person.schema], schemaVersion: 2); final realm = Realm(config);
プロパティを削除する
スキーマからプロパティを削除するには
オブジェクトの
RealmModel
クラスからプロパティを削除します。Realm の構成に、再生成された
RealmObject.schema
を含め、schemaVersion
の値を増やします。
プロパティを削除しても、既存のオブジェクトには影響しません。
例
スキーマ バージョン1
を使用する Realm には、 weight
プロパティを持つPerson
オブジェクトタイプがあります。 開発者は、スキーマからプロパティを削除することを決定します。
更新されたPerson
スキーマに準拠するように Realm を移行するには、開発者は Realm のスキーマ バージョンを2
に設定します。
final config = Configuration.local([Person.schema], schemaVersion: 2); final realm = Realm(config);
スキーマの手動移行
より複雑なスキーマ更新の場合、Realm では特定のオブジェクトの古いインスタンスを新しいスキーマに手動で移行する必要があります。
更新されたスキーマを使用して Realm を開くときは、Realm のConfiguration
で次の操作を行う必要があります。
schemaVersion
プロパティを増やします。migrationCallback で移行ロジックを定義する Realm の 構成 のプロパティ 。移行コールバックには、次のパラメーターがあります。
migration
: 移行 現在の Realm、移行先の Realm、移行操作を支援するメソッドにアクセスするためのインスタンス。oldSchemaVersion
: デバイス上の Realm の前のスキーマ バージョンの数。
次のセクションでは、さまざまな移行操作の実行方法について説明します。
オブジェクトタイプの削除
Realm からタイプのすべてのオブジェクトを削除するには、オブジェクト スキーマの名前の string 表現を Migration.deleteType() に渡します。
これは、前のバージョンのスキーマに Realm オブジェクトタイプがあるが、新しいバージョンのスキーマには Realm オブジェクトタイプがない場合に有用です。
final configWithoutPerson = Configuration.local([Car.schema], schemaVersion: 2, migrationCallback: ((migration, oldSchemaVersion) { // Between v1 and v2 we removed the Person type migration.deleteType('Person'); })); final realmWithoutPerson = Realm(configWithoutPerson);
プロパティの名前を変更する
Migration.renameProperty() を使用してスキーマ プロパティの名前を変更します。
final configWithRenamedAge = Configuration.local([Person.schema, Car.schema], schemaVersion: 2, migrationCallback: ((migration, oldSchemaVersion) { // Between v1 and v2 we renamed the Person 'age' property to 'yearsSinceBirth' migration.renameProperty('Person', 'age', 'yearsSinceBirth'); })); final realmWithRenamedAge = Realm(configWithRenamedAge);
その他の移行タスク
その他の Realm スキーマ移行を実行するには、移行コールバック 関数でMigration
オブジェクトの次のプロパティを使用します。
Migration. oldRealm :以前のスキーマ バージョンを使用して移行する直前に存在していたRealm。 標準のタイプベースのクエリは使用できないため、
oldRealm
の 動的 API を使用する必要があります。 動的 API を使用すると、クラス名の string 表現によって Realm オブジェクトを検索できます。Migration.newRealm :移行後に存在するRealm。 移行コールバックの終了までに、スキーマ更新の影響を受けるすべてのデータを
oldRealm
からnewRealm
に移行する必要があります。 移行されていないスキーマ更新の影響を受けるデータは、失われます。
新しい Realm で古い Realm 内のオブジェクトのインスタンスを検索するには、 Migration.findInNewRealm() を使用します 。古いスキーマからオブジェクトのプロパティにアクセスするには、 RealmObjectBase.dyname API。
final configWithChanges = Configuration.local([Person.schema, Car.schema], schemaVersion: 2, migrationCallback: ((migration, oldSchemaVersion) { // Dynamic query for all Persons in previous schema final oldPeople = migration.oldRealm.all('Person'); for (final oldPerson in oldPeople) { // Find Person instance in the updated realm final newPerson = migration.findInNewRealm<Person>(oldPerson); if (newPerson == null) { // That person must have been deleted, so nothing to do. continue; } // Use dynamic API to get properties from old schema and use in the // new schema newPerson.fullName = "${oldPerson.dynamic.get<String>("firstName")} ${oldPerson.dynamic.get<String>("lastName")}"; // convert `id` from ObjectId to String final oldId = oldPerson.dynamic.get<ObjectId>("id"); newPerson.id = oldId.toString(); } })); final realmWithChanges = Realm(configWithChanges);
同期された Realm のスキーマの更新
同期された Realm のスキーマの更新は、ローカル専用 Realm のスキーマの更新とは別のプロセスです。
同期された Realm にはスキーマ バージョンはなく、オブジェクトが最新のスキーマに自動的に移行されます。 同期された Realm は、スキーマに重大じゃない変更のみをサポートします。