Flutter使用SQLite新增link字段后报task_table无对应列的数据库异常
问题根因
- 设备本地已存在旧版本生成的
todo_list.db数据库文件,该文件内的task_table表是最初无link字段时创建的,本身不存在link列 - sqflite的核心运行逻辑为:仅当对应路径下的数据库文件不存在、首次创建时,才会执行
onCreate内的建表语句;如果检测到本地已有数据库文件,且传入的版本号与数据库当前存储的版本号一致,不会触发任何结构修改逻辑 - 你修改建表语句新增
link字段后,没有调整数据库版本号,也没有编写表结构迁移逻辑,插入操作携带不存在的link列时直接抛出SQL错误
解决方案
开发测试场景(快速验证,会清空本地旧数据)
- 直接卸载设备上的当前应用,删除残留的旧数据库文件
- 重新安装应用,首次启动时会按最新的建表语句生成带
link列的表结构,即可正常运行
生产兼容场景(保留用户已有数据,符合上线标准)
- 提升数据库版本号,将
openDatabase的版本参数从1改为2 - 新增
onUpgrade迁移回调,针对版本升级场景给旧表补全缺失的link列 - 修改后的核心代码:
Future<Database> _initDb() async { Directory dir = await getApplicationDocumentsDirectory(); String path = dir.path + 'todo_list.db'; final todoListDb = await openDatabase( path, version: 2, // 版本号从1升级为2 onCreate: _createDb, // 新增版本迁移逻辑 onUpgrade: (Database db, int oldVersion, int newVersion) async { // 适配从v1升级到v2的场景,补充缺失的link列 if (oldVersion < 2) { await db.execute('ALTER TABLE $taskTable ADD COLUMN $colLink TEXT'); } }, ); return todoListDb; }
- 后续若继续调整表结构,只需持续递增版本号,在
onUpgrade内补充对应版本区间的表结构变更语句,不要修改已发布的旧版本建表逻辑
额外提示
- 你在
Task类中对status字段的注释存在错误:当前注释写的是// 0 - complete, 1- complete,根据错误日志中传入的参数值,应修正为// 0 - 未完成, 1 - 已完成,避免业务逻辑出错 link字段为空时,toMap()返回的null值可直接被sqflite写入TEXT类型列,无需额外判空处理
内容的提问来源于stack exchange,提问作者beginner_coder
相关产品推荐
相关产品推荐

