首页 > 解决方案 > Room 数据库迁移测试中出现“no such table: alarmInfo”的原因是什么?

问题描述

正如标题所说,当我尝试测试数据库迁移时,我得到了这个 SQLiteException。这是完整的错误:

android.database.sqlite.SQLiteException: no such table: alarmInfo (code 1): , while compiling: INSERT INTO SystemIdInfo(work_spec_id, system_id) SELECT work_spec_id, alarm_id AS system_id FROM alarmInfo
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:905)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:516)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1703)
at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1633)
at androidx.sqlite.db.framework.FrameworkSQLiteDatabase.execSQL(FrameworkSQLiteDatabase.java:242)
at androidx.work.impl.WorkDatabaseMigrations$1.migrate(WorkDatabaseMigrations.java:83)
at androidx.room.RoomOpenHelper.onUpgrade(RoomOpenHelper.java:87)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onUpgrade(FrameworkSQLiteOpenHelper.java:133)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:299)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:194)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:96)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:54)
at androidx.room.testing.MigrationTestHelper.openDatabase(MigrationTestHelper.java:238)
at androidx.room.testing.MigrationTestHelper.runMigrationsAndValidate(MigrationTestHelper.java:228)
at com.github.jnuutinen.functional.unit.DatabaseMigrationTest.migrate1To2(DatabaseMigrationTest.kt:36)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at androidx.test.ext.junit.runners.AndroidJUnit4.run(AndroidJUnit4.java:104)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:388)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2099)

以上指向我的代码中的这一行:

helper.runMigrationsAndValidate(DB_NAME, 2, true, MIGRATION_1_2).apply { //error!
    ...
}

我不知道 SystemIdInfo 或 alarmInfo 表是什么,我的应用程序与警报没有任何关系(这是一个非常简单的待办事项应用程序)。我的应用程序中唯一的表是todotodo_list。由于这对我来说似乎很模糊,我认为它一定与我的手机有关,所以我用模拟器尝试了它,但我得到了同样的错误。

这是我的应用程序模块的build.gradle测试依赖项:

dependencies {
    ...
    androidTestImplementation 'androidx.test:core:1.1.0'
    androidTestImplementation 'androidx.test.ext:junit:1.1.0'
    androidTestImplementation 'androidx.test:runner:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
    androidTestImplementation 'androidx.arch.core:core-testing:2.0.0'
    androidTestImplementation 'androidx.room:room-testing:2.1.0-alpha04'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
    androidTestImplementation 'org.hamcrest:hamcrest-library:1.3'
    androidTestImplementation 'androidx.test:rules:1.1.1'
    androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
    ...
}

什么可能导致这种情况?

编辑:这是我的迁移:

    val MIGRATION_1_2 = object : Migration(1, 2) {
        override fun migrate(database: SupportSQLiteDatabase) {
            database.execSQL("ALTER TABLE todo ADD todo_order INTEGER DEFAULT 0 NOT NULL")
        }
    }

这是我的实体类:

@Entity(tableName = "todo", foreignKeys = [ForeignKey(
    entity = TodoList::class,
    parentColumns = ["group_id"],
    childColumns = ["todo_group_id"],
    onUpdate = CASCADE,
    onDelete = CASCADE)])
data class Todo(
    @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "todo_id") val id: Int,
    @ColumnInfo(name = "todo_contents") var contents: String,
    @ColumnInfo(name = "todo_date") val date: Long,
    @ColumnInfo(name = "todo_color") var color: Int,
    @ColumnInfo(name = "todo_order") var order: Int = 0,
    @ColumnInfo(name = "todo_group_id") val todoListId: Int) : Comparable<Todo>
{
    override fun compareTo(other: Todo): Int {
        if (order == other.order) return 0
        if (order < other.order) return -1
        return 1
    }
    override fun toString() = contents
}

@Entity(tableName = "todo_group")
data class TodoList(
    @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "group_id") val id: Int,
    @ColumnInfo(name = "group_name") var name: String,
    @ColumnInfo(name = "group_date") val date: Long)
{
    override fun toString() = name
}

标签: androidsqlitekotlinandroid-room

解决方案


您不小心导入了androidx.work.impl.WorkDatabaseMigrations.MIGRATION_1_2.


推荐阅读