【发布时间】:2021-06-02 15:55:00
【问题描述】:
我在 iOS 和 Android 上使用 Realm Swift 和 Realm-java。我需要实现数据库迁移以更新数据库中的值。 在 Swift 上,迁移按如下方式完成:currentVersion -> latestVersion。在 Android 上:v1 -> v2 -> latestVersion。
以下示例在 iOS 上显示迁移 0 -> 1 和 1 -> 2:
- 0 -> 1 = V1:创建一个新的奇幻电影类别(由 两部电影已经存在于数据库中)
- 1 -> 2 = V2:添加新的 创造了神奇类别的电影
迁移 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 迁移一样运行。在查看文档和不同的票后,我找不到解决方案。您有解决问题的解决方案或新架构吗?
注意:解决方案必须始终为我提供迁移数据库架构的可能性
【问题讨论】:
标签: android swift realm realm-migration