【问题标题】:Realm migration introducing primary key引入主键的领域迁移
【发布时间】:2019-12-19 22:24:19
【问题描述】:

目前,我的 Realm 数据库包含 MyData 对象的普通数组:

class MyData: Object {
    @objc dynamic var name = ""
    @objc dynamic var age = 0
}

例如,它可能包含

[
    ["Alice", 12],
    ["Bob", 13],
    ["Alice", 22],
    ["Carolina", 13],
    ["Bob", 20]
]

我将对其进行重新设计,以使 name 独一无二,同时保持最大的 age

[
    ["Alice", 22],
    ["Bob", 20],
    ["Carolina", 13]
]

另外,我想将name 设为主键以避免将来重复。

所以我将类描述更改为

class MyData: Object {
    @objc dynamic var name = ""
    @objc dynamic var age = 0
    override static func primaryKey() -> String? {
        return "name"
    }
}

现在我需要提供一个迁移块:

let config = Realm.Configuration(
    schemaVersion: 1,
    migrationBlock: { migration, oldSchemaVersion in
        switch oldSchemaVersion {
        case 0:
           migration.enumerateObjects(ofType: MyData.className()) { (oldObject, newObject) in
            // how to do it?
        }
        default:
            break
    }
})

我不明白在枚举块中做什么。在我的示例中,我有五个“旧”对象(没有主键),我将有三个“新”对象(有主键),那么如何进行这种转换?

【问题讨论】:

    标签: ios swift realm realm-migration


    【解决方案1】:

    您是否只是尝试增加架构版本并将属性 deleteRealmIfMigrationNeeded 添加到 true ?

    Realm.Configuration.defaultConfiguration = Realm.Configuration(
        schemaVersion: 2,
        migrationBlock: { migration, oldSchemaVersion in },
        deleteRealmIfMigrationNeeded: true
    )
    

    编辑:

    抱歉,这不是真的,因为您只需要保留最年长的人,因此请尝试使用领域迁移对象的delete 方法:

    let config = Realm.Configuration(
    schemaVersion: 1,
    migrationBlock: { migration, oldSchemaVersion in
        switch oldSchemaVersion {
        case 0:
           var objects: [String: Any] = []
           migration.enumerateObjects(ofType: MyData.className()) { 
           (oldObject, newObject) in
               if let age = oldObject["age"] as? Int, age > objects[oldObject["name"]] {
                   migration.delete(oldObject["name"])
                   objects[oldObject["name"]] = oldObject
               } else {
                   migration.delete(oldObject)
               }
    
           }
        default:
            break
        }
    })
    

    https://realm.io/docs/swift/latest/api/Classes/Migration.html#/s:FC10RealmSwift9Migration6deleteFCS_13DynamicObjectT_

    【讨论】:

    • deleteRealmIfMigrationNeeded 在我的情况下不是一个选项,因为它会导致用户重新登录和其他糟糕的用户体验
    • 是的对不起,我编辑我的答案。尝试使用migration.delete 并仅删除目标对象。
    【解决方案2】:
    func realmConfiguration(schemaVersion: UInt64) {
           let config = Realm.Configuration(schemaVersion: schemaVersion,
                                            migrationBlock: { _, oldSchemaVersion in
                                                if oldSchemaVersion < schemaVersion {}
           })
           Realm.Configuration.defaultConfiguration = config
       }
    

    在appDelegate中调用这个函数

    //Bump the schemaVersion when ever you need migration
    realmConfiguration(schemaVersion: 2)
    

    【讨论】:

    • 我了解迁移的一般模式。我的问题是关于我想从没有主键的结构数组迁移到唯一(就主键而言)结构数组的具体情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-29
    • 2017-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多