Android Room数据库迁移报SQLiteException: no such column: id错误如何解决
问题根因
你写的版本2→3的迁移SQL存在语法错误:
- 建表
emoji_table的语句中,仅在主键声明中指定了id作为主键,但是字段列表里完全没有定义id列,执行该SQL时自然会抛出no such column: id的报错。 - 全新安装不会触发迁移逻辑,Room会直接根据
EmojiBean实体类的注解生成正确的建表语句,所以全新安装运行正常。 - 跨版本升级(比如从v1/v2升到v4)时会依次执行所有迁移步骤,执行到2→3的建表SQL时就会触发崩溃。
修复方案
第一步:修正2→3迁移的建表SQL
根据你后续3→4迁移要把id重命名为_id的逻辑,说明v3版本的emoji_table设计是包含自增主键id的,补全该字段的定义即可:
Migration migration2_3 = new Migration(2,3) { @Override public void migrate(@NonNull SupportSQLiteDatabase database) { // 补全id字段的定义,设置为自增非空主键 database.execSQL("CREATE TABLE IF NOT EXISTS 'emoji_table' ('id' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,'date' INTEGER NOT NULL,'emoji' INTEGER NOT NULL, 'month' TEXT NOT NULL,'year' TEXT NOT NULL,'day' TEXT NOT NULL,'beanpos' INTEGER NOT NULL);"); } };
如果你的业务设计里不需要id字段,主键是其他字段(比如date),则需要同步修改三处逻辑:
- 把2→3建表语句里的主键声明改为对应字段,删除
id相关内容 - 删掉3→4迁移里重命名
id为_id的SQL - 修正
EmojiBean实体类的@PrimaryKey注解配置,和表结构保持一致
第二步:额外优化建议
- 把
@Database注解中的exportSchema属性改为true,开启数据库结构导出,Room会自动生成每个版本的表结构JSON文件,方便你校验迁移SQL的正确性,避免手写SQL出错。 - 上线前测试所有可能的升级路径:1→4、2→4、3→4,确保所有跨版本升级场景都能正常执行。
内容的提问来源于stack exchange,提问作者mohil vadia
相关产品推荐
相关产品推荐

