【问题标题】:Android Room populate database with new data after migration?Android Room 在迁移后用新数据填充数据库?
【发布时间】:2019-11-25 15:38:31
【问题描述】:

我已经在 Play Store 中发布了一个应用程序,它使用 onCreate 回调中的数据预填充 Room 数据库。从 JSON 文件中读取数据并将其放入数据库。一切都适用于从 JSON 文件再次将数据输入数据库(将新记录添加到表中)。

这是我的 RoomDatabase create 方法:

private fun create(context: Context): MyDatabase {
        val MIGRATION_1_2 = object : Migration(1, 2) {
            override fun migrate(database: SupportSQLiteDatabase) {
                database.execSQL("ALTER TABLE dogs ADD COLUMN language TEXT")
            }
        }
        return Room.databaseBuilder(
            context.applicationContext,
            MyDatabase::class.java,
            DB_NAME
        )
            .addMigrations(MIGRATION_1_2)
            // prepopulate the database after onCreate was called
            .addCallback(object : RoomDatabase.Callback() {
                override fun onCreate(db: SupportSQLiteDatabase) {
                    super.onCreate(db)
                    GlobalScope.launch {
                        getInstance(context)?.let { DatabaseUtils.prepopulateDatabase(context, it) }
                    }
                }
            })
            .build()
    }

有没有一种简单的方法可以在不手动编写数百个 SQL 请求的情况下做到这一点? 或者,如果有办法删除整个数据库并使用全新数据创建一个新数据库,也许对我来说也是一种选择。

在此先谢谢大家 ;)

【问题讨论】:

    标签: android database sqlite database-migration android-room


    【解决方案1】:

    您可以使用 fallbackToDestructiveMigration 删除/清除以前的数据库。

    database = Room.databaseBuilder(context.getApplicationContext(),
                        UsersDatabase.class, "Sample.db")
                .fallbackToDestructiveMigration()
                .build();
    

    参考这篇谷歌文章Understanding migrations with Room中的场景3

    【讨论】:

    • 但是本文中的场景 3 说:“所以现在,我们的应用程序没有崩溃,但我们丢失了所有数据。所以请确保这是您特别希望处理迁移的方式。”。这是否意味着数据库将是空的,或者它将被重新创建,并且在第一次访问时将再次调用回调“onCreate”并且将再次使用新数据预先填充数据库?
    • @MrVasilev - 它会清除并且不会预先填充。你来测试一下怎么样??
    • 是的,这也是一个很好的问题,如何测试来自 Play 商店的更新,因为当尝试在模拟器中测试新版本时,只需说“你已经有一个带有这个包的应用程序你想卸载它?”然后卸载应用程序并重新安装,这不是 Play 商店的真正更新,对吧? :)
    • @MrVasilev - 您可以上传最新的 alpha 版本并添加特定用户进行测试。因此您将能够以这种方式进行测试。这是链接developers.google.com/actions/deploy/release-environments 在生产中首先向 1% 的用户进行阶段性部署,而不是 10% 的用户,依此类推。
    【解决方案2】:

    也许这是最简单的方法:

    private const val IS_DB_RECREATED = "is_database_recreated"
    
    class App : Application(), HasActivityInjector {
    
        override fun onCreate() {
            super.onCreate()
            val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
            val isDBRecreated = sharedPreferences.getBoolean(IS_DB_RECREATED, false)
    
            if (!isDBRecreated) {
                deleteDatabase(MyDatabase.DB_NAME)
                sharedPreferences.edit().putBoolean(IS_DB_RECREATED, true).apply()
            }
        }
    }
    

    所有数据将从数据库中丢失,但当新数据库第一次访问时,它将被预先填充,我也可以更改方案。

    【讨论】:

      猜你喜欢
      • 2021-11-29
      • 2021-06-04
      • 2020-03-22
      • 1970-01-01
      • 1970-01-01
      • 2020-04-05
      • 2012-09-26
      • 1970-01-01
      • 2019-04-08
      相关资源
      最近更新 更多