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全版本支持的语法完成字段重命名,步骤如下:
- 创建与新版本表结构一致的临时表
- 将旧表数据迁移到临时表(映射字段关系)
- 删除旧表
- 将临时表重命名为原表名
对应的迁移代码替换原来的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
相关产品推荐
相关产品推荐

