领域版本迁移重命名属性不存在

Posted

技术标签:

【中文标题】领域版本迁移重命名属性不存在【英文标题】:Realm version Migration renaming property not existed 【发布时间】:2017-07-04 06:04:21 【问题描述】:

您好,我有 Realm 迁移,但遇到错误

下面是我的情况错误场景

第一

我有一个简单的User 模型,schemeVersion 0(默认)

class User: Object 
    dynamic var username = ""
    dynamic var date = NSDate()

在版本 1 中添加 date2

class User: Object 
    dynamic var username = ""
    dynamic var date = NSDate()
    dynamic var date2 = NSDate()

并迁移

Realm.Configuration.defaultConfiguration = Realm.Configuration(
        schemaVersion: 1,
        migrationBlock:  migration, oldSchemaVersion in
            // We haven’t migrated anything yet, so oldSchemaVersion == 0
            if oldSchemaVersion < 1 
                migration.enumerateObjects(ofType: RealmUser.className(),  (oldObject, newObject) in
                    newObject!["date2"] = oldObject!["date"] as! NSDate
                )
            

在版本 3 中添加 date3 并在版本 4 中将 date3 重命名为 date 4

class User: Object 
    dynamic var username = ""
    dynamic var date = NSDate()
    dynamic var date2 = NSDate()
    dynamic var date4 = NSDate()

并迁移

Realm.Configuration.defaultConfiguration = Realm.Configuration(
        schemaVersion: 4,
        migrationBlock:  migration, oldSchemaVersion in
            // We haven’t migrated anything yet, so oldSchemaVersion == 0
            if oldSchemaVersion < 1 
                migration.enumerateObjects(ofType: RealmUser.className(),  (oldObject, newObject) in
                    newObject!["date2"] = oldObject!["date"] as! NSDate
                )
            

            if oldSchemaVersion < 2 
                migration.enumerateObjects(ofType: RealmUser.className(),  (oldObject, newObject) in
                    newObject!["date3"] = oldObject!["date2"] as! NSDate
                )
            

            if oldSchemaVersion < 3 
                migration.renameProperty(onType: User.className(), from: "date3", to: "date4")
            

当我按顺序迁移 0 -> 1 -> 2 -> 3 -> 4 时工作正常

但是当从 0 版本迁移到 4 版本时会导致 fatal error: 'try!' expression unexpectedly raised an error

"Cannot rename property 'User.date3' because it does not exist."

在这种情况下,我如何将 0 ~ 3 版本迁移到 4 而没有上述不存在的例外?

【问题讨论】:

【参考方案1】:

如果 schemaVersion 3 仅具有“date3”,则必须单独处理版本 3(我不知道 schemaVersion 2 中发生了什么)。而且您不能将 oldObject["date2"] 插入 newObject["date3"],因为 newObject 没有 date3 作为错误。迁移的目的是使旧方案与当前方案相匹配。在你的项目中尝试一下,它对我有用!

 Realm.Configuration.defaultConfiguration = Realm.Configuration(
       schemaVersion: 4, 
       migrationBlock:  migration, oldSchemaVersion in
       migration.enumerateObjects(ofType: User.className(),  (oldObject, newObject) in
           if oldSchemaVersion < 1 
               newObject?["date2"] = oldObject!["date"] as! NSDate
           
           // use newObject["date2"] instead of oldObject["date2"] for schemaVerion 0
           if oldSchemaVersion < 2 
               newObject?["date4"] = newObject?["date2"] as! NSDate
           
      )
      // separate version 3 for "date3"
      if oldSchemaVersion == 3 
          migration.renameProperty(onType: User.className(), from: "date3", to: "date4")
      
)

我建议你使用一次 func enumerateObjects。您不需要每次都获取所有对象。我希望它会起作用!

【讨论】:

它节省了我的时间谢谢:)【参考方案2】:

您需要为每个属性进行迁移,这些属性将存在于您的架构的最终版本中但不在原始版本中,因为 Realm 需要将此属性添加到您在数据库中已有的所有内容中(这就是迁移所做的 - 它填补漏洞)。为什么要删除有效的代码?您得到 date3 的例外,因为它在模式 0 中不存在,并且您说您想直接从 0 转到 4... 您可以从所有属性的完整定义重新开始,然后从头开始重新加载所有数据迁移,或保留您的工作代码。这没有什么问题。问我任何我没有充分解释的事情。

【讨论】:

我为您想到了另一个选择:如果您可以从已填充的数据库开始,请使用当前数据库的副本(模式 4)作为“版本 0”并删除所有迁移代码。并确保您有在插入(添加)时正确填充 date3 等的代码。

以上是关于领域版本迁移重命名属性不存在的主要内容,如果未能解决你的问题,请参考以下文章

重命名一个目录,确保它不存在

包重命名和错误“活动类不存在”

如果目标文件不存在,则在 Node.js 中异步重命名文件

ColdFusion CFFILE 重命名属性验证错误,属性源的值无效,即使文件存在且路径正确

在dplyr中,如何删除和重命名不存在的列,操作所有名称,并使用字符串命名新变量?

如果文件存在,Powershell 移动项目重命名