Room数据库迁移异常:新增实体升级版本后表结构不符求助
解决Room数据库迁移后目标表未创建的问题
我来帮你梳理几个实用的排查方向,都是处理Room迁移问题时踩过的坑:
先确认迁移逻辑是否正确配置
首先检查你的RoomDatabase子类的@Database注解,有没有把新增的SuperHerosData实体加入entities数组,同时指定正确的版本号和对应的迁移类。比如:@Database( entities = [YourOldEntity::class, SuperHerosData::class], version = 2, // 确保版本号比旧版本高 migrations = [MIGRATION_1_2] ) abstract class AppDatabase : RoomDatabase() { // DAO定义 }然后看迁移类里的SQL语句是否完全匹配预期的表结构,手动写
CREATE TABLE时别漏了字段:val MIGRATION_1_2 = object : Migration(1, 2) { override fun migrate(database: SupportSQLiteDatabase) { database.execSQL(""" CREATE TABLE IF NOT EXISTS `SuperHerosData` ( `id` INTEGER NOT NULL PRIMARY KEY, `name` TEXT, `realName` TEXT, `team` TEXT, `superFriendImage` TEXT ) """.trimIndent()) } }注意如果实体用了
@Entity(tableName = "...")或@ColumnInfo(name = "...")指定了自定义名称,SQL里的表名和列名必须和注解一致。检查实体类的注解是否正确
确认SuperHerosData类上标注了@Entity注解,主键id的@PrimaryKey配置正确(比如@PrimaryKey(autoGenerate = false)如果是手动赋值的话),每个字段的类型和注解都符合预期:@Entity data class SuperHerosData( @PrimaryKey val id: Int, val name: String?, val realName: String?, val team: String?, val superFriendImage: String? )要是某个字段需要非空约束,别忘了加
@ColumnInfo(notNull = true),否则SQL里的字段会默认允许为空。排查迁移是否被正确触发
- 先试试卸载重装APP:有时候旧的数据库文件残留会导致迁移逻辑不执行,清掉旧数据后重新运行,看新表是否正常创建。
- 临时用
fallbackToDestructiveMigration()测试:在构建数据库时添加这个方法,它会销毁旧数据库并重建新的。如果这样操作后表结构正常了,说明你的迁移逻辑肯定有问题,回到第一步仔细检查SQL语句。
检查版本号是否正确升级
别犯低级错误:确认@Database里的version值确实比之前的版本高(比如之前是1,现在必须是2或更高),而且整个项目里没有其他地方定义了冲突的版本号。查看Room的调试日志
打开Logcat,搜索“Room”或者“SQLite”,Room会输出迁移过程的详细日志,比如SQL执行失败的原因、表结构不匹配的具体信息,这些日志能直接帮你定位到底是哪一步出了问题。
内容的提问来源于stack exchange,提问作者Sreekar Ml




