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

更改对象模型 - Node.js SDK

在此页面上

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

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

模式版本是指打开 Realm 时可以选择性地包含在 Realm 配置中的递增整数。如果客户端应用程序在打开 Realm 时未指定版本号,则该 Realm 默认采用 0 版本。

重要

单调递增版本

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

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

提示

在开发期间绕过迁移

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

切勿将此标记设为 true 的应用发布到生产环境。

每当您打开模式版本高于该 Realm 当前版本的现有 Realm 时,Realm 都会运行您定义的迁移函数。 该函数可以访问 Realm 的版本号,并以增量方式更新 Realm 中的对象以符合新模式。

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

注意

修改同步 Realm 的模式属性

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

要将属性添加到模式,请将新属性添加到对象的类,并设置Realm 配置对象schemaVersion

例子

使用模式版本1的域具有附带firstNamelastName属性的Person对象类型。 开发者决定向Person类添加一个age属性。

为了迁移 Realm 以符合更新的Person模式,开发者将 Realm 的模式版本设置为2

const Person = {
name: 'Person',
properties: {
firstName: 'string',
lastName: 'string',
age: 'int'
}
}
const realm = await Realm.open({
schema: [Person],
schemaVersion: 2
});

要从模式中删除属性,请从对象的类中删除该属性,并设置Realm 配置对象schemaVersion 。 删除属性不会影响现有对象。

例子

使用模式版本 1 的 Realm 有附带 weight 属性的 Dog 对象类型。开发者决定从模式中删除该属性。

为了迁移 Realm 以符合更新的Dog模式,开发者将 Realm 的模式版本设置为2

const realm = await Realm.open({
schema: [Dog],
schemaVersion: 2
});

要重命名对象属性,请在对象模式中更改属性名称,然后使用递增的模式版本迁移函数打开域 ,该函数更新现有对象以使用新的属性名称。

迁移不允许您直接重命名属性。 相反,您可以使用更新的名称创建新属性,从旧属性复制值,然后删除旧属性。

例子

使用模式版本1的 Realm 具有Person对象类型。 原始模式具有firstNamelastName字段。 开发者稍后决定Person类应使用组合的fullName字段,并删除单独的firstNamelastName字段。

为了迁移 Realm 以符合更新的Person模式,开发者将 Realm 的模式版本设置为2 ,并定义一个迁移函数以根据现有的firstNamelastName属性设置fullName的值。

Realm.open({
schema: [Person],
schemaVersion: 2,
onMigration: (oldRealm, newRealm) => {
// only apply this change if upgrading to schemaVersion 2
if (oldRealm.schemaVersion < 2) {
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}`;
}
}
}
});

重要

同步 Realm

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

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

注意

同步 Realm仅支持非重大更改,以确保较旧的客户端可以与较新的客户端同步。 这意味着同步 Realm 不支持修改模式的属性类型。

例子

使用模式版本1的域具有Dog对象类型。 原始模式具有属性类型为Object ID _id 随后,开发者决定Dog类的_id字段的类型应为string ,并更新模式。

为了迁移 Realm 以符合更新的Dog模式,开发者将 Realm 的模式版本设置为2 ,并定义一个迁移函数以将Object ID类型转换为string类型。

const realm = await Realm.open({
schema: [Dog],
schemaVersion: 2,
onMigration: (oldRealm, newRealm) => {
if(oldRealm.schemaVersion < 2){
const oldObjects = oldRealm.objects('Dog');
const newObjects = newRealm.objects('Dog');
// 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 = oldObject._id.toHexString();
}
}
},
});

后退

关系和嵌入式对象