更新数据模型
在此页面上
使用 Atlas Device Sync 开发应用程序时,您可能需要在某些时候更改模式,例如当您需要:
为已同步对象添加新属性
从已同步对象中移除一个属性
更改属性中存储的类型
将可选属性更新为必需属性
为了更容易理解模式更改如何影响应用程序,我们将模式更改描述为“重大”更改与“非重大”更改。
Atlas App Services 提供对同步 Realm 的非重大模式更改,允许旧客户端与新客户端同步。
然而,破坏性模式更改需要一些计划和工作,应尽可能避免。
重大更改
重大模式更改很困难,因为较旧的客户端(尚未更新到新代码和模式的客户端)仍然需要通过旧模式定义访问数据。更新的客户端需要支持新的模式更改。
注意
通过 Atlas App Services 用户界面进行重大更改
由于破坏性模式更改需要特殊处理,因此 App Services 不支持通过 App Services CLI 进行这些更改或使用 GitHub 自动部署。取而代之的是,您应当在 App Services 用户界面中进行破坏性更改。
重大变更与非重大变更快速参考
重大变更是您在服务器端模式中所做的更改,需要额外的操作来处理。服务器端模式的重大变更要求您在后端终止同步,然后重新启用同步。重大的模式变更会导致客户端无法打开 realm,或者当服务器端文档无法同步到客户端应用程序时出现数据丢失。它们会阻止应用程序从客户端重置中自动恢复。
非重大更改是您可以在服务器端模式或对象模型中进行的更改,无需在应用程序中进行额外处理。这也称为累计更改,会自动应用于同步 Realm。
注意
对客户端进行非重大变更可能需要进行迁移
当您仅对服务器端模式进行非重大更改时,无需执行其他操作。但是,如果随后尝试将这些更改应用于客户端对象模型,则可能需要执行迁移。 如果客户端设备具有现有 Realm 文件,则必须执行迁移。有关详细信息,请参阅您首选 SDK 中的“修改对象模式”页面。
下图显示了可以进行的模式更改类型以及执行更改所经历的过程。下表和以下章节对每项更改进行了更详细的解释。
![模式变更的流程图](/zh-cn/docs/atlas/app-services/static/f59f6def582d413fcee3be7694694400/67d36/schema_changes.webp)
此表汇总了每种类型的更改,以及它是重大更改还是非重大更改。
变更类型 | 服务器端模式 | 客户端对象模型 |
---|---|---|
不间断 | 不间断 | |
不间断 | 不间断 | |
不间断 | 不间断 | |
不间断 | 不间断 | |
重大 | 不间断 | |
重大 | 不间断 | |
间断* | 间断* | |
间断* | 间断* | |
重大 | 重大 | |
重大 | 重大 |
开发模式和破坏性更改
适用于 2023 年 9 月 13 日之后创建的 App Services 应用程序。
对于在 9 月 13、2023 之后创建的处于开发模式的Atlas App Services应用,可以对客户端代码和同步对象模式进行重大更改。
有关在开发模式中进行重大更改的详细信息,请参阅开发模式。
开发模式不适合生产使用。如果您使用开发模式,请确保在将应用程序迁移到生产环境之前将其禁用。
添加对象类型
您可以将对象类型添加到服务器端模式或客户端对象模型中,而无需执行任何其他处理。
如果要将一个对象类型同时添加到服务器端模式和客户端对象模型,您可以将该对象类型添加到对象模型,并使用开发模式让 App Services 处理服务器端模式更新。或者,您可以手动将该对象类型添加到模型和模式中。
注意
这些更改可能会触发重新同步
当添加新的对象类型时,我们会检索集合的文档并将它们重新插入 App Services 以获取新值。这是预期行为,但在此进程正在进行时,它确实会导致传播更改暂时停止。
为属性添加默认值
您可以在对象的必需属性上添加默认值。 当您将缺少此必需属性的 Atlas 文档插入到集合中时,Realm 客户端会将该属性设置为默认值。但是,Atlas 文档上的同一属性将保持为空,直到客户端更改该属性或直接在 Atlas 中更新文档。
有关默认值在修改现有 Atlas 文档时有何帮助的更多信息,请参阅添加必需属性。
警告
确保默认值类型和属性类型相同
默认字段没有类型验证。如果默认字段的类型和属性的类型不同,则错误将指示文档缺少必填字段。
添加必需的属性
您可以向客户端的对象模型添加必需属性,并使用开发模式让 App Services 推断服务器端模式更新。或者,您可以手动将必需属性添加到客户端模型和 Atlas 模式中。但是,您应考虑将属性设置为可选,以避免修改现有 Atlas 文档。
注意
模式子集中缺少的必需属性将默认为零
客户端可以使用不包含必需属性的模式子集打开 Realm。当文档同步时,服务器会使用零值或空白值(如 0、"" 或 0.0,具体取决于属性类型)填充缺少必填值的字段。
修改现有 Atlas 文档
添加新的必需属性时,您必须使用新属性更新现有文档,否则它们不会同步到客户端。这可能会给客户端用户留下数据已丢失的印象。如需解决此问题,请向每个受影响的文档添加新属性并为其填充值。更新文档以匹配客户端模式后,它们将同步到客户端应用程序。
添加新的必需属性时,App Services 会根据更新的模式检索具有新值的集合文档。App Services 遍历这些文档并重新插入文档以获取新值。 这是预期行为,但在此进程正在进行时,它确实会导致传播更改暂时停止。
重要
App Services 使用 __realm_sync.unsynced_documents
集合来跟踪未同步的文档。添加必需属性时,重新同步进程可能会导致此集合超过100 、 000文档的限制。在这种情况下,您有两个选择:
终止并重新启用 sync ,即使您所做的更改是非重大更改。
请联系支持部门并请求暂时增加不同步的文档限制。
添加可选属性
如果要将一个可选属性同时添加到服务器端模式和客户端对象模型,您可以将该可选属性添加到对象模型,并使用开发模式让 App Services 处理服务器端模式更新。或者,您可以手动将该可选属性添加到模型和模式中。
注意
这些更改可能会触发重新同步
添加新的可选属性时,我们会根据更新的模式检索具有新值的集合文档。我们遍历这些文档,并将它们重新插入 App Services 以获取新值。 这是预期行为,但在此进程正在进行时,它确实会导致传播更改暂时停止。
删除对象类型
从客户端的对象模型中删除一个对象属于非重大更改。从服务器端模式中删除该对象则属于重大更改。因此,建议仅从客户端对象模型中删除对象类型,而在服务器端模式中继续予以保留。
删除属性
您可以从客户端对象模型中删除可选或必需的属性,而在服务器端模式中继续保留该属性。这是对该对象模型的非重大更改。
从服务器端模式中删除属性属于重大更改。因此,我们建议您仅从客户端对象模型删除属性,在服务器端模式中继续保留该属性。
为了保持向后兼容性,从客户端对象模型中删除属性不会从数据库中删除该属性。相反,新对象会保留已删除的属性,并且 App Services 会将其值设置为适当的空值,例如:对于可为空的属性,设置为 null
;对于整数值,设置为 0;或者对于字符串值,设置为空字符串。
更改对象名称
同时更改服务器端模式和客户端对象模型中的对象名称是一项重大更改。但是,某些 SDK 提供了将新对象名称映射到模式中现有名称的 API。它允许您在客户端上重命名对象,但不更改服务器上的对象名称。这样可以避免触发迁移。以下 SDK 支持对象名称映射:
Kotlin
爪哇
.网
Flutter
如果不能选择名称映射,可考虑实施合作集合策略,即保留现有集合和模式,并使用新模式创建新集合。
如果您选择更改对象的名称而不是使用合作伙伴集合策略,则必须终止同步,手动更新模式,然后重新启用同步。此外,客户端应用程序必须执行客户端重置才能恢复同步。在默认客户端重置模式下,客户端会尝试在重置前恢复任何未同步的更改。
注意
“开发模式”不会自动为破坏性更改更新模式。
更改属性名称
同时更改服务器端模式和客户端对象模型中的属性名称是一项重大更改。但是,某些 SDK 提供了将新属性名称映射到模式中现有名称的 API。它允许您在客户端上重命名属性,但不更改服务器上的属性名称。这样可以避免触发迁移。以下 SDK 支持属性名称映射:
警告
更新现有文档
如果在服务器端模式中更改某个属性的名称,则必须使用该新属性名称更新现有文档,否则它们不会同步到客户端。这可能会给客户端用户留下数据已丢失的印象。
如果不能选择名称映射,可考虑实施合作集合策略,即保留现有集合和模式,并使用新模式创建新集合。
如果您选择更改属性的名称而不是使用合作伙伴集合策略,则必须终止同步、手动更新模式并重新启用同步。此外,客户端应用程序必须执行客户端重置才能恢复同步。在默认客户端重置模式下,客户端会尝试在重置前恢复任何未同步的更改。
当终止并重新启用同步时,您还必须更新现有 Atlas 文档,以使它们能够与客户端应用程序同步。如果没有这种额外的处理,这些文档将不会同步,并且客户端中可能会显示数据已丢失。您可以通过两种方式解决此问题:
更改每个文档中的旧字段名称以匹配新模式
向每个文档添加一个名称与新模式匹配的新字段,并将旧字段中的值复制到其中
进行这些更改后,相应的文档将同步到客户端应用程序。
更改属性类型但保留名称
更改属性类型是对服务器端模式和客户端对象模型的重大更改。
警告
更新现有文档
如果在服务器端模式中更改某个属性的类型,则必须使用该新属性类型更新现有文档,否则它们不会同步到客户端。这可能会给客户端用户留下数据已丢失的印象。
与其更改属性类型,不如考虑实施合作伙伴集合策略,即保留现有集合和模式,并使用新模式创建一个新集合。
如果您选择更改属性的类型而不是使用合作伙伴集合策略,则必须终止同步、手动更新模式并重新启用同步。此外,客户端应用程序必须执行客户端重置才能恢复同步。在默认客户端重置模式下,客户端会尝试在重置前恢复任何未同步的更改。
注意
“开发模式”不会自动为破坏性更改更新模式。
当终止并重新启用同步时,您还必须更新现有 Atlas 文档,以使它们能够与客户端应用程序同步。如果没有这种额外的处理,这些文档将不会同步,并且客户端中可能会显示数据已丢失。您可以通过两种方式解决此问题:
更改每个文档中的旧字段类型以匹配新模式
向每个文档添加一个类型与新模式匹配的新字段,并将旧字段中的值复制到其中,并转换其类型
进行这些更改后,相应的文档应再次同步到客户端应用程序。
将属性状态更改为可选或必需
在可选和必需之间更改属性的状态,是对服务器端模式和客户端对象模型的重大变更。
警告
更新现有文档
如果在服务器端模式中更改某个属性的状态,则必须使用该新属性类型更新现有文档,否则它们不会同步到客户端。这可能会给客户端用户留下数据已丢失的印象。
与其更改属性状态,不如考虑实施合作伙伴集合策略,即保留现有集合和模式,并使用新模式创建一个新集合。
如果您选择更改属性的状态而不是使用合作伙伴集合策略,则必须终止同步、手动更新模式并重新启用同步。此外,您的客户端应用程序必须执行客户端重置才能恢复同步。在默认客户端重置模式下,客户端会尝试在重置之前恢复任何未同步的更改。
注意
“开发模式”不会自动为破坏性更改更新模式。
使用合作伙伴集合策略
伙伴集合是包含与原始集合相同数据的集合,但具有新的模式定义。伙伴集合使用数据库触发器来确保数据双向流动,也就是说当一个集合被写入时,另一个集合也会被写入(带有新模式所需的数据修改)。
要使用合作伙伴集合策略实施重大模式变更,请参阅实施重大模式更改。