Flutter Sqflite单数据库创建多表报错问题求助
问题原因
当ContactsSqfLiteHelper首次打开laneDane.db时,数据库不存在,因此执行它的onCreate方法创建了联系人表。后续AddTxnSqfLiteHelper再打开同一个数据库时,由于数据库已存在,它的onCreate不会被触发,导致交易表从未创建,最终插入操作时提示找不到表。
解决方案
方法1:统一数据库初始化,一次性创建所有表
将两张表的创建逻辑集中到同一个onCreate方法中,确保数据库首次创建时就生成所有需要的表。推荐抽离出全局的数据库管理类,避免重复初始化逻辑:
import 'package:sqflite/sqflite.dart' as sql; import 'package:path/path.dart' as path; class GlobalDBHelper { static Database? _database; static const _dbName = 'laneDane.db'; static const _dbVersion = 1; static Future<Database> get database async { if (_database != null) return _database!; final dir = await sql.getDatabasesPath(); final dbPath = path.join(dir, _dbName); _database = await sql.openDatabase( dbPath, version: _dbVersion, onCreate: _createAllTables, ); return _database!; } static Future<void> _createAllTables(Database db, int version) async { // 创建联系人表 await db.execute( 'CREATE TABLE contacts (id integer primary key autoincrement, user_id integer not null, name TEXT NOT NULL, profile_pic TEXT NULL, phone_id TEXT NOT NULL)'); // 创建交易表 await db.execute( 'CREATE TABLE transactions (id integer primary key autoincrement, user_id integer not null, category_id integer NULL, user_contact_id TEXT NOT NULL, type TEXT NOT NULL, amount DOUBLE NOT NULL)'); } }
之后修改两个业务Helper的插入方法,使用全局类获取数据库实例:
ContactsSqfLiteHelper的插入方法:
static Future<int> insert(Map<String, dynamic> data) async { final db = await GlobalDBHelper.database; return await db.insert('contacts', data); }
AddTxnSqfLiteHelper的插入方法:
static Future<int> insert(Map<String, dynamic> data) async { final db = await GlobalDBHelper.database; return await db.insert('transactions', data); }
方法2:通过onUpgrade补建缺失表(适用于已有旧数据库的场景)
如果设备上已经存在仅含联系人表的数据库,不想删除旧数据,可以通过升级数据库版本,在onUpgrade中补建交易表:
- 将数据库版本号从原数值(比如1)提升至更高版本(比如2)
- 添加
onUpgrade回调创建交易表:
static Future<Database> get database async { if (_database != null) return _database!; final dir = await sql.getDatabasesPath(); final dbPath = path.join(dir, _dbName); _database = await sql.openDatabase( dbPath, version: 2, // 升级版本号 onCreate: _onCreate, onUpgrade: _upgradeDatabase, ); return _database!; } static Future<void> _upgradeDatabase(Database db, int oldVersion, int newVersion) async { if (oldVersion < 2) { // 补建交易表 await db.execute( 'CREATE TABLE transactions (id integer primary key autoincrement, user_id integer not null, category_id integer NULL, user_contact_id TEXT NOT NULL, type TEXT NOT NULL, amount DOUBLE NOT NULL)'); } }
注意事项
- 测试前可卸载App清除旧数据库,或调用
sql.deleteDatabase(dbPath)手动删除,确保新初始化逻辑生效 - 所有操作同一数据库的Helper类,必须使用相同的数据库版本号,否则会触发版本冲突错误
内容的提问来源于stack exchange,提问作者Abdul raheem
相关产品推荐
相关产品推荐

