Room数据库手动迁移报错:category表索引缺失如何解决?
解决Room手动迁移中category表缺失index_category_parentId索引的问题
核心原因
Room自动生成表结构时,会根据CategoryEntity类中的@Index注解创建对应索引。手动迁移时必须手动通过SQL创建该索引,否则Room的结构校验会因"预期存在索引但实际缺失"而失败。
正确的手动迁移实现方式
你需要在Migration的migrate方法中,通过SQL语句创建索引,有两种可选写法:
方式1:创建表时同时定义索引
在创建category表的SQL中直接声明索引:
val MIGRATION_X_Y = object : Migration(旧版本号, 新版本号) { override fun migrate(database: SupportSQLiteDatabase) { database.execSQL(""" CREATE TABLE `category` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `parentId` INTEGER, INDEX `index_category_parentId` (`parentId`) ) """.trimIndent()) } }
方式2:先建表,再单独创建索引
如果已经创建了表,可单独执行索引创建语句:
val MIGRATION_X_Y = object : Migration(旧版本号, 新版本号) { override fun migrate(database: SupportSQLiteDatabase) { // 先创建category表 database.execSQL(""" CREATE TABLE `category` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `parentId` INTEGER ) """.trimIndent()) // 再创建非唯一索引 database.execSQL("CREATE INDEX IF NOT EXISTS `index_category_parentId` ON `category`(`parentId`);") } }
关键注意事项
- 索引名称必须严格匹配:Room自动生成的索引命名规则是
index_<表名>_<列名>,这里必须用index_category_parentId,不能自定义名称,否则校验仍会失败。 - 非唯一索引无需额外关键字:默认创建的索引就是非唯一的,不需要添加
UNIQUE关键字,和你实体类中@Index(unique = false)(默认值)的定义对应。
最后将这个Migration实例添加到Room.databaseBuilder的addMigrations方法中即可。
内容的提问来源于stack exchange,提问作者alexandre9865
相关产品推荐
相关产品推荐

