更改对象模型 — React Native SDK
更新对象模式时,必须递增模式版本并执行迁移。
如果模式更新操作添加了可选属性或删除了属性,则 Realm 可自动执行迁移。您只需递增 schemaVersion
。
对于更复杂的模式更新,您须在 migration
函数中手动指定迁移逻辑。此操作可能包括以下更改:
添加必须使用默认值填充的必要属性
合并字段
重命名字段
更改字段的类型
从对象转换为嵌入式对象
提示
在开发期间绕过迁移
在开发或调试应用程序时,您可能更愿意删除而不是迁移 Realm。 使用BaseConfiguration.deleteRealmIfMigrationNeeded 属性,以便在模式不匹配而需要迁移时自动删除数据库。
切勿将此属性设为 true
的应用发布到正式上线环境中。
模式版本
模式版本可标识 Realm 模式在某个时间点的状态。Realm 会跟踪每个 Realm 的模式版本,并使用该信息将每个 Realm 中的对象映射到正确的模式。
架构版本为一系列升序整数,而您可将其包含在 Realm 配置中。如果客户端应用程序未指定版本号,Realm 则默认采用 0
版本。
迁移
迁移是一种将 Realm 及其包含的任何对象从一个模式版本更新到较新版本的函数。 迁移允许您随时更改对象模式,以适应新功能和重构。
创建模式版本高于域当前版本的配置时,Realm 会运行您定义的迁移函数。该函数可访问域的版本号并以递增方式更新域中的对象以符合新模式。
Realm 会自动迁移某些更改(例如,新的和已删除的属性),但不会自动为新属性设置值,除非更新后的对象模式制定了默认值。您可在迁移函数中定义其他逻辑,以进一步自定义属性值。
添加属性
要将某一属性添加到模式,请将该新属性添加到对象的类并设置 Configuration
对象的 schemaVersion
。
例子
使用模式版本0
(默认值)的 Realm 具有附带firstName
和lastName
属性的Person
对象类型。 您决定向Person
类添加一个age
属性。
要迁移 realm 以符合更新的 Person
模式,则将 Configuration
中 realm 的模式版本设置为 1
。最后,将配置对象传递给 createRealmContext()
方法。
class Person extends Realm.Object { static schema = { name: 'Person', properties: { _id: 'string', firstName: 'string', lastName: 'string', // add a new property, 'age' to the schema age: 'int', }, }; } const config = { schema: [Person], // Increment the 'schemaVersion', since 'age' has been added to the schema. // The initial schemaVersion is 0. schemaVersion: 2, }; // pass the configuration object with the updated 'schemaVersion' to // createRealmContext() const {RealmProvider} = createRealmContext(config);
class Person extends Realm.Object<Person> { _id!: string; firstName!: string; lastName!: string; age!: number; static schema: ObjectSchema = { name: 'Person', properties: { _id: 'string', firstName: 'string', lastName: 'string', // add a new property, 'age' to the schema age: 'int', }, }; } const config: Realm.Configuration = { schema: [Person], // Increment the 'schemaVersion', since 'age' has been added to the schema. // The initial schemaVersion is 0. schemaVersion: 2, }; // pass the configuration object with the updated 'schemaVersion' to // createRealmContext() const {RealmProvider} = createRealmContext(config);
删除属性
要从模式中删除某一属性,请从对象的类中删除该属性并设置配置对象的 schemaVersion
。 删除属性不影响现有对象。
例子
使用模式版本0
(默认)的域具有附带lastName
属性的Person
对象类型。 您决定从模式中删除该属性。
如要迁移 Realm 以符合更新后的 Person
模式,请在 Configuration
对象中将 Realm 的模式版本设置为 1
。最后,将配置对象传递给 createRealmContext()
方法。
class Person extends Realm.Object { static schema = { name: 'Person', properties: { _id: 'string', firstName: 'string', age: 'int', }, }; } const config = { schema: [Person], // Increment the 'schemaVersion', since 'lastName' has been removed from the schema. // The initial schemaVersion is 0. schemaVersion: 1, }; // pass the configuration object with the updated 'schemaVersion' to createRealmContext() const {RealmProvider} = createRealmContext(config);
class Person extends Realm.Object<Person> { _id!: string; firstName!: string; age!: number; static schema: ObjectSchema = { name: 'Person', properties: { _id: 'string', firstName: 'string', age: 'int', }, }; } const config: Realm.Configuration = { schema: [Person], // Increment the 'schemaVersion', since 'lastName' has been removed from the schema. // The initial schemaVersion is 0. schemaVersion: 1, }; // pass the configuration object with the updated 'schemaVersion' to createRealmContext() const {RealmProvider} = createRealmContext(config);
为属性重命名
如需重命名对象属性,请更改对象模式中的属性名称,然后使用递增的模式版本,以及更新现有对象以使用新属性名称的迁移功能创建域配置。
迁移不允许您直接重命名属性。相反,您可以使用更新的名称创建新属性,从旧属性复制值,然后删除旧属性。
例子
默认使用模式版本0
的 Realm 具有Person
对象类型。 原始模式具有firstName
和lastName
字段。 您稍后确定Person
类应使用组合的fullName
字段,并删除单独的firstName
和lastName
字段。
要迁移 Realm 以符合更新的Person
模式,请创建一个配置对象并将 Realm 的模式版本设置为fullName
1
,并定义一个迁移函数,根据现有的firstName
和lastName
属性。 最后,将配置对象传递给createRealmContext()
方法。
class Person extends Realm.Object { static schema = { name: 'Person', properties: { _id: 'string', // rename the 'firstName' and 'lastName' property, to 'fullName' // in the schema fullName: 'string', age: 'int', }, }; } const config = { schema: [Person], // Increment the 'schemaVersion', since 'fullName' has replaced // 'firstName' and 'lastName' in the schema. // The initial schemaVersion is 0. schemaVersion: 1, onMigration: (oldRealm, newRealm) => { // only apply this change if upgrading schemaVersion if (oldRealm.schemaVersion < 1) { const oldObjects = oldRealm.objects(Person); const newObjects = newRealm.objects(Person); // loop through all objects and set the fullName property in the // new schema for (const objectIndex in oldObjects) { const oldObject = oldObjects[objectIndex]; const newObject = newObjects[objectIndex]; newObject.fullName = `${oldObject.firstName} ${oldObject.lastName}`; } } }, }; // pass the configuration object with the updated 'schemaVersion' and // 'migration' function to createRealmContext() const {RealmProvider} = createRealmContext(config);
class Person extends Realm.Object<Person> { _id!: string; fullName!: string; age!: number; static schema: ObjectSchema = { name: 'Person', properties: { _id: 'string', // rename the 'firstName' and 'lastName' property, to 'fullName' // in the schema fullName: 'string', age: 'int', }, }; } class OldObjectModel extends Realm.Object<OldObjectModel> { _id!: string; firstName!: string; lastName!: string; age!: number; static schema: ObjectSchema = { name: 'Person', properties: { _id: 'string', firstName: 'string', lastName: 'string', }, }; } const config: Realm.Configuration = { schema: [Person], // Increment the 'schemaVersion', since 'fullName' has replaced // 'firstName' and 'lastName' in the schema. // The initial schemaVersion is 0. schemaVersion: 1, onMigration: (oldRealm: Realm, newRealm: Realm) => { // only apply this change if upgrading schemaVersion if (oldRealm.schemaVersion < 1) { const oldObjects: Realm.Results<OldObjectModel> = oldRealm.objects(OldObjectModel); const newObjects: Realm.Results<Person> = newRealm.objects(Person); // loop through all objects and set the fullName property in the // new schema for (const objectIndex in oldObjects) { const oldObject = oldObjects[objectIndex]; const newObject = newObjects[objectIndex]; newObject.fullName = `${oldObject.firstName} ${oldObject.lastName}`; } } }, }; // pass the configuration object with the updated 'schemaVersion' and // 'migration' function to createRealmContext() const {RealmProvider} = createRealmContext(config);
修改属性类型
要修改属性的类型,则将要修改的字段的属性类型设置为新的数据类型。然后,设置配置对象的 schemaVersion
和 migration
回调函数。
注意
同步域 仅支持非破坏性变更 (breaking change),以确保较旧的客户端可以与较新的客户端同步。也就是说,同步域不支持修改模式的属性类型。
例子
默认使用模式版本0
的 Realm 具有Person
对象类型。 原始模式具有属性类型为int
_id
您稍后决定Person
类的_id
字段的类型应为ObjectId
,并更新模式。
要迁移 realm 以符合已更新 Person
模式,则创建 Configuration
对象并将 realm 的模式版本设置为 1
,然后定义迁移函数以将整数类型转换为 Object ID
类型。最后,将该配置对象传递给 createRealmContext()
方法。
class Person extends Realm.Object { static schema = { name: 'Person', properties: { // update the data type of '_id' to be 'objectId' within the schema _id: 'objectId', firstName: 'string', lastName: 'string', }, }; } const config = { schema: [Person], // Increment the 'schemaVersion', since the property type of '_id' // has been modified. // The initial schemaVersion is 0. schemaVersion: 1, onMigration: (oldRealm, newRealm) => { if (oldRealm.schemaVersion < 1) { const oldObjects = oldRealm.objects(Person); const newObjects = newRealm.objects(Person); // loop through all objects and set the _id property // in the new schema for (const objectIndex in oldObjects) { const oldObject = oldObjects[objectIndex]; const newObject = newObjects[objectIndex]; newObject._id = new Realm.BSON.ObjectId(oldObject._id); } } }, }; // Pass the configuration object with the updated // 'schemaVersion' and 'migration' function to createRealmContext() const {RealmProvider} = createRealmContext(config);
class Person extends Realm.Object<Person> { _id!: Realm.BSON.ObjectId; firstName!: string; lastName!: string; age!: number; static schema: ObjectSchema = { name: 'Person', properties: { // Update the data type of '_id' to be 'objectId' within the schema. _id: 'objectId', firstName: 'string', lastName: 'string', }, }; } // `OldObjectModel` is only used for type injection for `oldRealm`. It is // not related to the `Person` object model. interface OldObjectModel { _id: Realm.BSON.ObjectId; firstName: string; lastName: string; age: number; } const config: Realm.Configuration = { schema: [Person], // Increment the 'schemaVersion', since the property type of '_id' // has been modified. // The initial schemaVersion is 0. schemaVersion: 1, onMigration: (oldRealm: Realm, newRealm: Realm) => { if (oldRealm.schemaVersion < 1) { const oldObjects: Realm.Results<OldObjectModel> = oldRealm.objects(Person); const newObjects: Realm.Results<Person> = newRealm.objects(Person); // Loop through all objects and set the _id property // in the new schema. for (const objectIndex in oldObjects) { const oldObject = oldObjects[objectIndex]; const newObject = newObjects[objectIndex]; newObject._id = new Realm.BSON.ObjectId(oldObject._id); } } }, }; // Pass the configuration object with the updated // 'schemaVersion' and 'migration' function to createRealmContext(). const {RealmProvider} = createRealmContext(config);