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

Room数据库迁移表结构不匹配,如何修复该问题?

Room数据库迁移表结构不匹配问题修复

问题详情

迁移时触发Room表结构校验失败,预期与实际role表结构对比:

Expected:
TableInfo{name='role', columns={title=Column{name='title', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, id=Column{name='id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}}, foreignKeys=[], indices=[]}
Found:
TableInfo{name='role', columns={id=Column{name='id', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='null'}, title=Column{name='title', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}

核心差异:

  • 预期中id和title均带NOT NULL约束,实际表中两者均无该约束
  • 打印出的列顺序不一致(此为无关干扰项)

当前使用的实体类:

@TypeConverters(RoomConverters::class)
@Entity(tableName = "role")
class RoleRoom(
    @PrimaryKey val id: Int = 0,
    val title: String
)

迁移类中的建表SQL:

database.execSQL("CREATE TABLE IF NOT EXISTS `role` (`id` INTEGER, `title` TEXT, PRIMARY KEY(`id`))")

问题原因

  1. 非空约束不匹配:Kotlin中Int、无默认值的String都是非空类型,Room会自动为这些字段生成NOT NULL约束;但迁移SQL未声明该约束,导致实际表结构与预期不符。
  2. 列顺序干扰:TableInfo中的columns是无序Map,打印顺序由Map遍历逻辑决定,和实体类属性顺序、实际表列顺序无关,不会引发校验失败。

修复方案

1. 修正新建表的SQL

如果是首次创建该表,直接修改迁移SQL,添加非空约束:

database.execSQL("CREATE TABLE IF NOT EXISTS `role` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, PRIMARY KEY(`id`))")

2. 修复已存在的旧表

如果旧表已经创建且数据已存在,需先确保表中id和title字段无NULL值,再执行ALTER语句添加约束:

-- 先处理NULL数据(示例:将NULL替换为默认值)
database.execSQL("UPDATE `role` SET `id` = 0 WHERE `id` IS NULL")
database.execSQL("UPDATE `role` SET `title` = '' WHERE `title` IS NULL")

-- 添加非空约束
database.execSQL("ALTER TABLE `role` MODIFY COLUMN `id` INTEGER NOT NULL")
database.execSQL("ALTER TABLE `role` MODIFY COLUMN `title` TEXT NOT NULL")

3. 长期注意事项

后续编写迁移SQL时,必须严格对齐实体类的字段约束:

  • 非空类型(Kotlin不带?的类型)对应SQL的NOT NULL
  • 主键字段默认带NOT NULL约束,无需额外声明但也可明确写出
  • 默认值需和实体类的默认参数保持一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 21:25:43