Docs Menu
Docs Home
/ /
Atlas Device SDK
/ / /

オブジェクトモデルの変更 - Kotlin SDK

項目一覧

  • Overview
  • スキーマ バージョン
  • 移行
  • スキーマの自動更新
  • プロパティを追加する
  • プロパティを削除する
  • スキーマの手動移行
  • プロパティを変更する
  • その他の移行タスク

注意

同期された Realm のスキーマ プロパティの変更

次のページでは、ローカル Realm のスキーマ プロパティを変更する方法を示します。 同期された Realm のスキーマ プロパティ変更する方法を学びます。

Realm オブジェクトモデル を作成した後、オブジェクト スキーマに変更を加えることができます。 スキーマに加える変更のタイプに応じて、変更を自動的に適用することも、新しいスキーマへの手動更新が必要になることもあります。

  • Realm は、Realm オブジェクトモデルからプロパティを追加または削除すると、Realmオブジェクト スキーマを自動的に更新します。 スキーマのバージョンを更新する必要があるだけです。

  • その他のすべてのスキーマ変更では、特定のオブジェクトの古いインスタンスを新しいスキーマに手動で移行する必要があります。

Tip

開発中のバイパス移行

アプリケーションを開発またはデバッグする際には、Realm を移行するのではなく、 Realm を削除することをお勧めします。 スキーマの不一致により移行が必要になる場合に、データベースを自動的に削除するには、 deleteRealmIfMigrationNetedフラグを使用します。

このフラグを trueに設定して、アプリを本番環境にリリースしないでください。

スキーマ バージョンは、ある時点におけるRealm スキーマの状態を識別します。 Realm は各 Realm のスキーマ バージョンを追跡し、それを使用して各 Realm 内のオブジェクトを正しいスキーマにマッピングします。

スキーマ バージョンは昇順の整数であり、 Realm を開くときに任意で Realm 構成に含めることができます。 クライアント アプリケーションが Realm を開くときにバージョン番号を指定しない場合、Realm はデフォルトでバージョン0になります。

重要

バージョンを単調に増加させる

移行によって、Realm をより高いスキーマ バージョンに更新する必要があります。 Realm は、Realm の現在のバージョンよりも低いスキーマ バージョンでクライアント アプリケーションが Realm を開き、または指定されたスキーマ バージョンが Realm の現在のバージョンと同じであるが、異なるオブジェクト スキーマを含む場合にエラーをスローします。

Realm では、スキーマの更新は移行と呼ばれます。 移行により、Realm とそれに含まれるすべてのオブジェクトが、あるスキーマ バージョンから新しいバージョンに更新されます。

スキーマ バージョンよりも大きいスキーマ バージョンで既存の Realm を開くたびに、スキーマの更新に必要な追加のロジックを定義する移行関数を提供できます。 例:

  • プロパティ値の設定

  • フィールドの結合または分割

  • フィールドの名前を変更する

  • フィールドの型の変更

この関数は Realm のバージョン番号にアクセスし、新しいスキーマに準拠するように Realm 内のオブジェクトを段階的に更新します。

ローカル移行 とは、別の Realm と自動的に 同期 ない Realm の移行です。

注意

同期された Realm のスキーマ プロパティを変更するには、Atlas Device Sync ドキュメントの「データモデルの更新」を参照してください。

スキーマ更新によってプロパティが追加または削除される場合、Realm は移行を自動的に実行できます。 ただし、 schemaVersionを増やす必要があります。

スキーマにプロパティを追加するには

  1. 新しいプロパティをRealmObject定義に追加します。

  2. RealmConfigurationビルダを介してスキーマ バージョンを設定します。

更新されたオブジェクト スキーマでデフォルト値が指定されている場合、Realm は新しいプロパティに値を自動的に設定します。 更新されたオブジェクト スキーマでデフォルト値が指定されていない場合は、移行関数を使用して新しいプロパティの値を手動で設定する必要があります。

スキーマ バージョン1を使用する Realm には、名、姓、年数のプロパティを持つPersonオブジェクトタイプがあります。

// Realm schema version 1
class Person : RealmObject {
var firstName: String = ""
var lastName: String = ""
var age: Int = 0
}

開発者はPersonクラスにemailフィールドを追加します。

// Realm schema version 2
class Person : RealmObject {
var firstName: String = ""
var lastName: String = ""
var age: Int = 0
var email: String? = null
}

更新されたPersonスキーマに準拠するように Realm を変更するには、開発者は Realm のスキーマ バージョンを2に設定します。

val config = RealmConfiguration.Builder(
schema = setOf(Person::class)
)
.schemaVersion(2) // Sets the new schema version to 2
.build()
val realm = Realm.open(config)

スキーマからプロパティを削除するには

  1. オブジェクトのクラスからプロパティを削除します。

  2. RealmConfigurationビルダを介してスキーマ バージョンを設定します。

プロパティを削除しても、既存のオブジェクトには影響しません。

スキーマ バージョン2を使用する Realm には、名、姓、年数、電子メールのプロパティを持つPersonオブジェクトタイプがあります。

// Realm schema version 2
class Person : RealmObject {
var firstName: String = ""
var lastName: String = ""
var age: Int = 0
var email: String? = null
}

開発者はPersonクラスからageフィールドを削除します。

// Realm schema version 3
class Person : RealmObject {
var firstName: String = ""
var lastName: String = ""
// var age: Int = 0
var email: String? = null
}

更新されたPersonスキーマに準拠するように Realm を変更するには、開発者は Realm のスキーマ バージョンを3に設定します。

val config = RealmConfiguration.Builder(
schema = setOf(Person::class)
)
.schemaVersion(3) // Sets the new schema version to 3
.build()
val realm = Realm.open(config)

より複雑なスキーマ更新の場合、Realm では特定のオブジェクトの古いインスタンスを新しいスキーマに手動で移行する必要があります。

更新されたスキーマを使用してRealmを開き、 RealmConfigurationで次の操作を行う必要があります。

  • schemaVersionプロパティを増やします。

  • migrationContext を使用して移行ロジックを定義します。

オブジェクトのプロパティを変更するには(例: 名前変更、マージ、分割、またはプロパティタイプの変更):

  1. オブジェクト スキーマの プロパティを変更します。

  2. インクリメントされたスキーマ バージョンと、既存のオブジェクトを新しいプロパティを使用するようにマッピングする移行関数を使用してRealmを開きます。

次の例では、プロパティタイプの変更、2 つのプロパティを新しいプロパティにマージする方法、および既存のプロパティの名前を変更するためにスキーマをアップデートします。

// Realm schema version 1 (oldObject)
class Person : RealmObject {
var _id: ObjectId = ObjectId()
var firstName: String = ""
var lastName: String = ""
var age: Int = 0
}
// Realm schema version 2 (newObject)
class Person : RealmObject {
var _id: String = "" // change property type
var fullName: String = "" // merge firstName and lastName properties
var yearsSinceBirth: Int = 0 // rename property
}

次に、移行関数は、古いオブジェクト スキーマの変更されたプロパティと新しいオブジェクト スキーマ間でデータをマッピングするための移行ロジックを定義します。

// Use the configuration builder to open the realm with the newer schema version
// and define the migration logic between your old and new realm objects
val config = RealmConfiguration.Builder(
schema = setOf(Person::class)
)
.schemaVersion(2) // Set the new schema version to 2
.migration(AutomaticSchemaMigration {
it.enumerate(className = "Person") { oldObject: DynamicRealmObject, newObject: DynamicMutableRealmObject? ->
newObject?.run {
// Change property type
set(
"_id",
oldObject.getValue<ObjectId>(fieldName = "_id").toString()
)
// Merge properties
set(
"fullName",
"${oldObject.getValue<String>(fieldName = "firstName")} ${oldObject.getValue<String>(fieldName = "lastName")}"
)
// Rename property
set(
"yearsSinceBirth",
oldObject.getValue<String>(fieldName = "age")
)
}
}
})
.build()
val realm = Realm.open(config)

注意

スキーマの更新にRealmObject埋め込みRealm オブジェクトに変換することが含まれている場合、移行関数によって、埋め込みオブジェクトの親オブジェクトが 1 つだけ にリンクされていることを確認する必要があります。 埋め込みオブジェクトは、親オブジェクトと独立して存在することはできません。

その他の Realm スキーマ移行を実行するには、 AutomaticSchemaMigration.MigrationContextインターフェースの次のプロパティを使用します。

  • oldRealm : 前のスキーマ バージョンを使用する移行前に存在していたRealm。 動的 API を使用すると、クラス名の string 表現によって Realm オブジェクトを検索できます。

  • newRealm : 新しいスキーマ バージョンを使用した移行後に存在するRealm。

oldRealmnewRealmから取得されたオブジェクトは、移行関数の範囲内でのみ有効です。

移行が終了するまでに、スキーマ更新の影響を受けるすべてのデータを、古い Realm から新しい Realm に移行する必要があります。 移行されていないスキーマ更新の影響を受けるデータは、失われます。

val config = RealmConfiguration.Builder(
schema = setOf(Person::class)
)
.schemaVersion(2)
.migration(AutomaticSchemaMigration { migrationContext ->
val oldRealm = migrationContext.oldRealm // old realm using the previous schema
val newRealm = migrationContext.newRealm // new realm using the new schema
// Dynamic query for all Persons in old realm
val oldPersons = oldRealm.query(className = "Person").find()
for (oldPerson in oldPersons) {
// Get properties from old realm
val firstName: String = oldPerson.getValue(
propertyName = "firstName", String::class
)
// Get objects from old realm as dynamic realm objects
val pet: DynamicRealmObject? = oldPerson.getObject(
propertyName = "pets"
)
}
// Get migrated objects from the new realm as mutable objects
val oldPerson: DynamicMutableRealmObject? =
newRealm.findLatest(oldPersons[0])
oldPerson?.let {
it.set("fullName", "Crow T. Robot")
}
// Create an object in the new realm and set property values
val newPerson = newRealm.copyToRealm(
DynamicMutableRealmObject.create(
type = "Person",
mapOf(
"_id" to "123456",
"fullName" to "Tom Servo",
"yearsSinceBirth" to 33,
)
)
)
})
.build()
val realm = Realm.open(config)

戻る

地理空間データ