领域迁移引入主键

时间:2019-12-19 22:24:19

标签: ios swift realm realm-migration

当前,我的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
    }
})

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

2 个答案:

答案 0 :(得分: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_

答案 1 :(得分:0)

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)