android - 如何执行更好的 SwiftRealm 迁移价值
问题描述
我在 iOS 和 Android 上使用 Realm Swift 和 Realm-java。我需要实现数据库迁移以更新数据库中的值。在 Swift 上,迁移按如下方式完成:currentVersion -> latestVersion。在 Android 上:v1 -> v2 -> latestVersion。
以下示例显示 iOS 上的迁移 0 -> 1 和 1 -> 2:
- 0 -> 1 = V1:创建一个新的奇幻电影类别(由数据库中已有的两部电影组成)
- 1 -> 2 = V2:在创建的 Fantastic 类别中添加新电影
迁移 0 -> 1 :
/// Function to migrate version 0 to version 1.
/// Create Fantastic film category and associated
///
/// - Parameter migration: Migration instance.
static func migrateFrom0To1(_ migration: Migration) {
// Film to add for Fantastic category.
let existingFilmToAdd: [String] = ["STAR_WARS", "HARRY_POTTER"]
// Get stored films.
var filmToSet: [MigrationObject] = []
migration.enumerateObjects(ofType: Film.className()) { _, filmDb in
let key = filmDb!["filmKey"] as! String
if existingFilmToAdd.contains(key) {
filmToSet.append(filmDb!)
}
}
// Create Fiction Category.
let fantasticCategory = migration.create(Category.className())
fantasticCategory["categoryKey"] = "FANTASTIC"
fantasticCategory["name"] = "Fantastic"
fantasticCategory["films"] = filmToSet
}
迁移 0/1 -> 2
/// Function to migrate version 0 to version 1.
/// Create Fantastic film category and associated
///
/// - Parameter migration: Migration instance.
static func migrateFrom0To1(_ migration: Migration) {
// Film to add for Fantastic category.
let existingFilmToAdd: [String] = ["STAR_WARS", "HARRY_POTTER"]
// Create Superman Film
let superman = migration.create(Film.className())
superman["filmKey"] = "SUPERMAN"
superman["name"] = "Superman"
superman["time"] = 2
// Get stored films.
var filmToSet: [MigrationObject] = []
migration.enumerateObjects(ofType: Film.className()) { _, filmDb in
let key = filmDb!["filmKey"] as! String
if existingFilmToAdd.contains(key) {
filmToSet.append(filmDb!)
}
}
filmToSet.append(superman)
// Create Fiction Category.
let fantasticCategory= migration.create(Category.className())
fantasticCategory["categoryKey"] = "FANTASTIC"
fantasticCategory["name"] = "Fantastic"
fantasticCategory["films"] = filmToSet
}
/// Function to migrate version 1 to version 2.
/// Add film in Fantastic Category
///
/// - Parameter migration: Migration instance.
static func migrateFrom1To2(_ migration: Migration) {
// Create Superman Film
let superman = migration.create(Film.className())
superman["filmKey"] = "SUPERMAN"
superman["name"] = "Superman"
superman["time"] = 2
// Get stored films.
var filmToSet: [MigrationObject] = []
// Update Fantastic film
migration.enumerateObjects(ofType: Category.className()) { _, migrationCategory in
let categoryKey = migrationMarket!["categoryKey"] as! String
if categoryKey == "FANTASTIC" {
let oldFilm = migrationCategory!["films"] as! List
for film in oldFilm {
filmsToSet.append(film)
}
filmsToSet.append(superman)
migrationCategory!["films"] = filmsToSet
}
}
}
如果应用程序已经安装在V1中,将执行迁移1 -> 2,很简单,这个迁移创建一个新的超人电影并将其添加到之前存储到数据库中的神奇类别中。
如果是第一次安装: 0 -> 2 将被执行。Fantastic Category 在 0 -> 1 中创建,但在迁移 1 -> 2 中尚不可用,因为迁移尚未完成。我必须修改函数 0 -> 1 迁移函数来创建超人电影并在创建时添加到 Fantastic Category。
这个例子很简单,因为有简单的数据,但是当我们有更多的价值要添加和修改时,它会使迁移变得越来越复杂。
在 Android 上没有问题,迁移会一个接一个,因为在每个迁移函数结束时,数据库中的数据都是可用的。swift 上的迁移实现起来越来越复杂。
我想让 Swift 迁移像 Android 迁移一样运行。在查看文档和不同的票后,我找不到解决方案。您有解决问题的解决方案或新架构吗?
注意:该解决方案必须始终为我提供迁移数据库架构的可能性
解决方案
您可以使用类似的东西来迁移您的领域。
Realm.Configuration.defaultConfiguration = Realm.Configuration(schemaVersion: 2,
migrationBlock: { (migration, oldSchemaVersion) in
migrate(oldScema: oldSchemaVersion, migration: migration)
})
在 migrate(oldScema:, migration:) 函数中,您可以检查旧架构版本并添加相应的操作。前任:
func migrate(oldScema: Int, migration: Migration) {
if oldScema < 1 {
// Migrate 0 -> 1
}
if oldScema < 2 {
// Migrate 1 -> 2
}
// etc for other migrations
}
推荐阅读
- c# - 可以为空的 Guid 的 Dapper 问题?类型
- c# - 如何让 Reinforced.Typings 生成“导出接口”或“导出枚举”作为输出,而不将其包装在模块中?
- javascript - 在此用例中 document.write() 的更好替代方案
- c++ - 如何在宏中定义的字符串文字上调用 fmt::literals::operator""_format?
- node.js - 将管道(exiftool 和 imagemagick)bash 命令解构为单个命令
- php - ajax 加载简码作为响应
- javascript - Discord.js 嵌入标题和缩略图未设置
- reactjs - 我的路线没有从函数传递到 APP
- azure - Azure ExpressRoute 网关区域冗余网关 ARM Tempate
- java - 在法语 java apache 中配置双变音器