(Android) Room数据库迁移不会改变数据库。

4

我需要更新SQLite-Database,因此我创建了一个迁移。 在逐步调试此迁移时,没有错误,但是我发现只有“日志文件已更新”。 更改从未提交到数据库中,我真的不明白我做错了什么,所以也许有人可以给出建议?

我有一个名为'image'的表,需要创建一个名为'attachment'的表。之后,我需要将所有数据从'image'移动到'attachment',处理/转换一些数据,最后删除表'image'。

以下是我的实现:

1. 我将库添加到项目中

    implementation android.arch.persistence.room:runtime:1.0.0
    implementation android.arch.persistence.room:compiler:1.0.0

2. 创建迁移

    val MIGRATION_2_3: Migration = object : Migration(2, 3) {
    override fun migrate(database: SupportSQLiteDatabase) {

    // create table 'attachment'
    database.execSQL("CREATE TABLE attachment (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, extenal_id INTEGER NOT NULL, userId TEXT, createdDateTime TEXT, displayFileName TEXT, fileExtension TEXT NOT NULL, noData INTEGER, identifier TEXT, commentText TEXT, localBaseFileName TEXT, dirty INTEGER NOT NULL, task_id TEXT NOT NULL, attachmentType INTEGER NOT NULL)")

    // migrate data from table 'image' to 'attachment'
    val cursor = database.query("SELECT * FROM image")
    cursor.moveToFirst()
    while (!cursor.isAfterLast) {

        // get stored values
        val image_id = cursor.getInt(0)
        val externalId = cursor.getLong(1)
        val customIdentifier = cursor.getString(2)
        val createdAt = cursor.getString(3)
        val imageType = cursor.getString(4)
        val commentText = cursor.getString(5)
        val createdBy = cursor.getString(6)
        // cursor.getString(7)/ / not used anymore
        val imageName = cursor.getString(8)
        val dirty = cursor.getInt(9)
        val task_id = cursor.getString(10)
        // cursor.getString(11) // not used anymore 

        // create migration only for availably images
        if (!imageName.isNullOrEmpty()) {

            // get file extension or 'unknown' if not known
            val fileExtension = MimeTypeMap.getSingleton().getExtensionFromMimeType(imageType) ?: "unknown"

            val contentValues = ContentValues()
            contentValues.put("id", image_id)
            contentValues.put("external_id", externalId)
            contentValues.put("userId", createdBy)
            contentValues.put("createdDateTime", createdAt)
            contentValues.put("displayFileName", imageName)
            contentValues.put"fileExtension", fileExtension)
            contentValues.put"noData", false)
            contentValues.put("identifier", customIdentifier)
            contentValues.put("commentText", commentText)
            contentValues.put("localBaseFileName", imageName.split("_")[0])
            contentValues.put("dirty", dirty)
            contentValues.put("task_id", task_id)
            contentValues.put("attachmentType", DatabaseManager.ATTACHMENT_TYPE_IMAGE)

            // insert new data
            database.insert("attachment", SQLiteDatabase.CONFLICT_REPLACE, contentValues)
        }

        // load next entry
        cursor.moveToNext()
    }
    cursor.close()

    // delete old table 'image'
    // database.execSQL("DROP TABLE image")



}

3. 添加了数据库实现的迁移

     Room
            .databaseBuilder(context, Database::class.java, "my_db.db")
            .fallbackToDestructiveMigration()
            .addMigrations(MIGRATION_2_3)
            .build()

当我运行代码时,迁移会顺利执行没有报错。但是在迁移后,只有'journal'文件被更新了,数据库本身并没有被更新!?
我漏掉了什么吗?我不理解..... ¯\_(ツ)_/¯
1个回答

1

我真是太丢人了...

所以,这是我的解决方案或者说是出了什么问题 ;)

我总是通过迁移过程进行调试,并在迁移完成后终止进程...结果就像上面描述的那样。

至少我只需要再走一步就能看到,我实体类中的附件有不同的实现方式,而创建表的 SQL 语句也不同...

'id' 字段已使用以下属性创建:

id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL

然而,在实体类中这个属性是可空的!

所以,我学到的是: 现在我明白了,迁移不会抛出异常,因为表的创建是正确的,错误只会在新的初始加载过程中出现,因为只有那时才能检测到差异。

我不明白为什么日志在迁移后没有直接合并到数据库中,但好吧,这只是 Android 上更奇怪的事情之一 ;)

我希望这能帮助到某些人。


2
我也处于类似的情况,但我不知道这个答案在说什么。 - lasec0203

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接