You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Room数据库V1迁V2遇SQL语法错误,缺失1.json schema文件如何解决?

问题分析与解决方案

核心原因:SQLite版本兼容性问题

不是缺失1.json导致的错误。1.json的作用是供Room做schema校验和自动迁移,和手动编写的迁移SQL执行无关。

报错的根本原因是:ALTER TABLE Mango RENAME COLUMN carbs TO carbohydrate 是SQLite 3.25.0及以上版本才支持的语法,但部分旧Android设备搭载的SQLite版本低于该版本,无法识别这个语法,因此触发syntax error。

兼容低版本SQLite的迁移方案

需要用SQLite全版本支持的语法完成字段重命名,步骤如下:

  1. 创建与新版本表结构一致的临时表
  2. 将旧表数据迁移到临时表(映射字段关系)
  3. 删除旧表
  4. 将临时表重命名为原表名

对应的迁移代码替换原来的MIGRATION_1_2:

val MIGRATION_1_2 = object : Migration(1, 2) {
    override fun migrate(database: SupportSQLiteDatabase) {
        // 1. 创建临时表,结构与版本2的Mango一致
        database.execSQL("""
            CREATE TABLE temp_mango (
                id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
                carbohydrate REAL NOT NULL DEFAULT 0.0
            )
        """.trimIndent())
        
        // 2. 迁移旧表数据到临时表,映射carbs到carbohydrate
        database.execSQL("""
            INSERT INTO temp_mango (id, carbohydrate)
            SELECT id, carbs FROM mango
        """.trimIndent())
        
        // 3. 删除旧表
        database.execSQL("DROP TABLE mango")
        
        // 4. 重命名临时表为原表名
        database.execSQL("ALTER TABLE temp_mango RENAME TO mango")
    }
}

额外注意事项

  • 确认版本2的Mango实体类中,字段已经改为carbohydrate:
    @Entity(tableName="mango")
    data class Mango(
        @PrimaryKey(autoGenerate = true) val id: Int =0,
        val carbohydrate: Float = 0f
    ){...}
    
  • 保持exportSchema = true,后续版本迭代时,Room会自动生成schema文件,便于迁移校验和自动迁移功能的使用。

内容的提问来源于stack exchange,提问作者DeKekem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 00:25:19