在 Room 中未正确处理迁移

时间:2021-02-22 23:12:48

标签: android sqlite migration android-room

我有一个 db 表类,我确实在其中更改了与索引相关的内容。以前的指数是这样的:

@Entity(indices = {@Index(value = {"jobNumber", "jobId"},
        unique = true)})

但是我改成

@Entity(indices = {
        @Index(value = "jobNumber", unique = true), @Index(value = "jobId", unique = true)
})

但是当我尝试迁移时,它给了我类似的问题:

caused by: java.lang.IllegalStateException: Migration didn't properly handle Job

我只需要使用第二种格式。我尝试添加迁移,但似乎不起作用。这是我的代码:

 public static final Migration MIGRATION_4_5 = new Migration(4, 5) {
    @Override
    public void migrate(SupportSQLiteDatabase database) {
        migrateJobTableForIndices(database);
    }
};

private static void migrateJobTableForIndices(SupportSQLiteDatabase database) {
    //create new table
    database.execSQL(
            "CREATE TABLE Job_new (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, jobId INTEGER NOT NULL, " +
                    "jobNumber TEXT)");

    database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS index_Job_new_jobNumber_jobId ON Job_new (jobNumber, jobId)");
    // Copy the data
    database.execSQL(
            "INSERT INTO Job_new (id, jobId, jobNumber) " +
                    "SELECT id, jobId, jobNumber " +
                    "FROM Job");
    // Remove the old table
    database.execSQL("DROP TABLE Job");
    // Change the table name to the correct one
    database.execSQL("ALTER TABLE Job_new RENAME TO Job");
}

有什么方法可以为更新的索引格式添加迁移。任何参考都非常感谢

1 个答案:

答案 0 :(得分:0)

As Room 生成索引名称。您可以导出方案以查看发生了什么。通过在 build.gradle 中添加以下内容:

android {
    ...
    javaCompileOptions {
        annotationProcessorOptions {
            arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
        }
    }

    ...
}

现在进行迁移。

事先您必须关闭 foreign_keys

database.execSQL("PRAGMA foreign_keys=OFF;")

您必须删除现有索引。例如:

database.execSQL("DROP INDEX IF EXISTS `index_Job_jobNumber_jobId`")

那么我建议重命名表。

ALTER TABLE Job RENAME TO Job_old

创建Job

然后创建索引,您将在导出的架构位置中找到该索引。在此示例中,它位于您的 $projectDir/schemas 中。从那里的文件中,您可以看到并复制 Room 如何创建索引并在创建表后添加这些索引的创建。

迁移数据。

删除表。

打开 foreign_keys

database.execSQL("PRAGMA foreign_keys=ON;")