Docs 菜单
Docs 主页
/ /
Atlas Device SDKs
/ /

更改对象模型 — React Native SDK

在此页面上

  • 模式版本
  • 迁移
  • 添加属性
  • 删除属性
  • 为属性重命名
  • 修改属性类型

注意

修改同步 Realm 的模式属性

以下页面演示了如何修改本地域的模式属性。 了解如何修改同步域的模式属性。

更新对象模式时,必须递增模式版本并执行迁移。

如果模式更新操作添加了可选属性或删除了属性,则 Realm 可自动执行迁移。您只需递增 schemaVersion

对于更复杂的模式更新,您须在 migration 函数中手动指定迁移逻辑。此操作可能包括以下更改:

  • 添加必须使用默认值填充的必要属性

  • 合并字段

  • 重命名字段

  • 更改字段的类型

  • 从对象转换为嵌入式对象

提示

在开发期间绕过迁移

在开发或调试应用程序时,您可能更愿意删除而不是迁移 Realm。 使用BaseConfiguration.deleteRealmIfMigrationNeeded 属性,以便在模式不匹配而需要迁移时自动删除数据库。

切勿将此属性设为 true 的应用发布到正式上线环境中。

模式版本可标识 Realm 模式在某个时间点的状态。Realm 会跟踪每个 Realm 的模式版本,并使用该信息将每个 Realm 中的对象映射到正确的模式。

架构版本为一系列升序整数,而您可将其包含在 Realm 配置中。如果客户端应用程序未指定版本号,Realm 则默认采用 0 版本。

重要

单调递增版本

迁移必须将域更新到更高的模式版本。如果客户端应用程序使用的模式版本低于该域的当前版本,或是指定的模式版本与该域的当前版本相同但包含不同模式,域则会引发错误。

迁移是一种将 Realm 及其包含的任何对象从一个模式版本更新到较新版本的函数。 迁移允许您随时更改对象模式,以适应新功能和重构。

创建模式版本高于域当前版本的配置时,Realm 会运行您定义的迁移函数。该函数可访问域的版本号并以递增方式更新域中的对象以符合新模式。

Realm 会自动迁移某些更改(例如,新的和已删除的属性),但不会自动为新属性设置值,除非更新后的对象模式制定了默认值。您可在迁移函数中定义其他逻辑,以进一步自定义属性值。

要将某一属性添加到模式,请将该新属性添加到对象的类并设置 Configuration 对象的 schemaVersion

例子

使用模式版本0 (默认值)的 Realm 具有附带firstNamelastName属性的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对象类型。 原始模式具有firstNamelastName字段。 您稍后确定Person类应使用组合的fullName字段,并删除单独的firstNamelastName字段。

要迁移 Realm 以符合更新的Person模式,请创建一个配置对象并将 Realm 的模式版本设置为fullName 1 ,并定义一个迁移函数,根据现有的firstNamelastName属性。 最后,将配置对象传递给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);

重要

同步 Realm

已同步域 仅支持非中断性(也称为累加性)更改,以确保较旧的客户端仍可与新客户端同步。由于完整重命名要求您删除旧属性,因此无法在不要求进行客户端重置的情况下重命名已同步属性。相反,可考虑添加已重命名的属性,而不删除旧属性。或者,使用 mapTo 以便以现有内部名称来存储数据,但允许代码使用其他名称。

要修改属性的类型,则将要修改的字段的属性类型设置为新的数据类型。然后,设置配置对象的 schemaVersionmigration 回调函数。

注意

同步域 仅支持非破坏性变更 (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);

后退

关系和嵌入式对象