Flutter应用更新时,如何迁移SQLite数据库至新结构并保留数据?
Flutter SQLite 新增列且保留旧数据的迁移方案
核心思路
通过SQLite的ALTER TABLE语句新增列,配合sqflite的版本升级机制,在不删除旧表的前提下完成结构更新,全程保留原有数据。
具体步骤
升级数据库版本号
在初始化数据库的openDatabase方法中,将version参数从原有数值(比如1)提升到新的版本(比如2)。SQLite会通过版本号差异自动触发升级逻辑。实现
onUpgrade回调处理结构变更
在openDatabase的onUpgrade回调里,根据旧版本号判断是否需要执行新增列操作,直接用ALTER TABLE语句添加列D即可。
完整代码示例
import 'package:sqflite/sqflite.dart'; import 'package:path/path.dart'; Future<Database> initDatabase() async { final dbPath = await getDatabasesPath(); final path = join(dbPath, 'your_app.db'); return await openDatabase( path, version: 2, // 版本号从1升级到2 onCreate: (db, version) { // 首次创建表的语句(包含原有的A、B、C列) return db.execute( 'CREATE TABLE target_table(id INTEGER PRIMARY KEY AUTOINCREMENT, A TEXT, B INTEGER, C REAL)', ); }, onUpgrade: (db, oldVersion, newVersion) async { // 仅当旧版本小于2时执行新增列操作 if (oldVersion < 2) { // 新增列D,这里设置为TEXT类型并允许为空,可根据需求修改类型和约束 await db.execute('ALTER TABLE target_table ADD COLUMN D TEXT DEFAULT NULL'); // 如果需要给已有数据的D列批量赋值,可在此添加UPDATE语句 // 示例:await db.execute('UPDATE target_table SET D = A || "_suffix"'); } }, ); }
注意事项
- 确保
ALTER TABLE语句符合SQLite语法:如果列需要默认值,要保证默认值与列类型匹配;如果不允许为空,需确保已有数据能被正确填充或设置合理默认值。 - 若新增列需要基于原有数据计算生成,可在
ALTER TABLE之后执行UPDATE语句批量赋值,避免手动修改每条数据。 - 测试阶段务必备份旧数据库,验证升级后原有数据完整、新增列正常可用。
内容的提问来源于stack exchange,提问作者Ammar Mohamed
相关产品推荐
相关产品推荐

