【问题标题】:Get realm old schema version during RealmConfiguration build在 RealmConfiguration 构建期间获取领域旧架构版本
【发布时间】:2019-08-22 20:58:51
【问题描述】:

在我当前的项目中,我们为不同的海豚有五个不同的领域实例。主要的架构版本现在是 5,我们希望摆脱它并完全干净地启动下一个(架构版本 6),因为我们启动了应用程序的 2.0.0 版本并且有一些主要的数据库更改。

问题是,有没有办法在构建新配置之前检查领域实例的旧架构版本?

我们已经尝试使用realmDeleteIfMigrationNeeded() 定义特定架构版本来删除领域,并为后续版本提供迁移类。这种方法的问题是,当用户的应用程序版本低于指定的模式版本并更新到具有更高版本的应用程序版本时,因此我们需要迁移异常。

我还在 realm, check schema versionhttps://github.com/realm/realm-java/issues/2645https://github.com/realm/realm-java/issues/6049 找到了一个可能的解决方案,先执行 'val realm = DynamicRealm.getInstance(realmConfiguration)' 然后 'getSchemaVersion()' 但我们真的不知道如何这可能会起作用,因为当您实际必须设置架构版本时,您必须提供“RealmConfiguration”。

我将尝试澄清我的问题,我们有以下获取领域实例的方法

private val realmConfiguration = buildRealmConfiguration(realmInstance)

private fun buildRealmConfiguration(realmInstance: RealmInstance):
    RealmConfiguration {

    return realmInstance.run {
        val realmBuilder = RealmConfiguration.Builder()
            .name(getName())
            .schemaVersion(schemaVersion.toLong())

        if (this == RealmInstance.IN_MEMORY) {
            realmBuilder.inMemory()
        } else {
            getMigration(realmBuilder, this)
        }

        realmBuilder.build()
    }

fun getInstance(): Realm {
    return Realm.getInstance(realmConfiguration)
}
enum class RealmInstance(val instance: String, val schemaVersion: Int) {

    MAIN_DB(instance = "main_db", schemaVersion = 5),
    DB2(instance = "db2", schemaVersion = 1),
    ...

    fun getName() = instance

    fun getMigration(
        realmBuilder: RealmConfiguration.Builder, 
        realmInstance: RealmInstance
    ) {

        when (realmInstance) {

            MAIN_DB -> {
                /*
                Variable used to delete main_db Realm during migration from app version 1.x.x to version 2.0.0 due to a mayor schema change
                */
                val migrateToAppVersion2 = realmInstance.schemaVersion <= 4

                realmBuilder.apply {
                    modules(mainDbModule())
                    if (deleteRealm) {
                        deleteRealmIfMigrationNeeded()
                    } else {
                        migration(realmMigration!!)
                    }
                }
            }
...

理想的情况是在调用“getMigration()”之前检查数据库的实际架构版本,如果旧的架构版本属于应用程序的 v1.x.x,我们可以始终删除领域。

【问题讨论】:

    标签: android kotlin realm


    【解决方案1】:

    您可以使用RealmMigration 实现来检查新旧版本:

    public class CustomRealmMigration implements RealmMigration {
    
        @Override
        public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
            //do what you want
        }
    }
    

    并将其添加到您的 RealmConfiguration builder 中:

    RealmConfiguration.Builder()
    //...
    .migration(new CustomRealmMigration())
    //...
    .build()
    

    【讨论】:

    • 我们已经使用RealmMigration 进行迁移(请参阅RealmIntanceclass 中的getMigration() 方法),但这并不是我们正在寻找的重点。通过迁移,我们无法使用 deleteRealm() 删除领域实例(它尚未构建)
    • 如果我们想通过硬方式删除它们(通过删除数据库文件夹中的领域文件),我们将需要一个 context 来搜索文件(我个人认为 context 不应该在没有非常合理的动机的情况下从一个班级传到另一个班级)我要求一个更有创意的解决方案。
    • 你不能只删除 RealmMigration 中的所有旧实体吗?这很乏味,但它会起作用;)
    • 您的意思是从架构中删除它们?这不应该意味着我们必须再次添加它们吗?如果你不是这个意思,我们怎么做?我想将实际的构建器传递给迁移类,构建配置并在必要时使用getRealmDirectory() 查找和删除所有实例数据库,但不知道它是否会起作用或是否是一个好习惯跨度>
    • 如果我得到了你想要的:如果架构版本是 X,你想删除所有内容以重新开始。如果是这样,您可以删除此处解释的每个类stackoverflow.com/a/36723295/1243048,然后创建所有新类。我错了吗?
    【解决方案2】:

    您可以通过DynamicRealm.getInstance(realmConfiguration) 打开 Realm 以查看架构版本。如果小于6,关闭动态Realm,然后调用Realm.deleteRealm(realmConfiguration)

    【讨论】:

    • 我之前实际上看到过这个答案,正如我在问题描述中提到的那样,这种方法的问题是你必须生成一个 Realm 实例(在这种情况下是动态的)但你必须提供一个' realmConfiguration',您必须在其中设置版本。这不是说当你得到它的架构版本时,它会返回你刚刚在配置中设置的那个吗?
    • 我认为 DynamicRealm 实际上并不关心您的架构版本属性,因为 Dynamic Realm 不进行架构验证。但是 Realm 文件本身确实有一个模式版本,它应该返回那个
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多