Flutter Sqflite报错DatabaseException:MST_University表不存在问题
问题分析与解决
核心问题
你遇到的no such table: MST_University错误,本质是代码没有正确将assets里的预打包数据库复制到应用目录,导致打开的是一个全新的空数据库,自然不存在目标表。
具体错误点
- Assets路径拼写错误:代码中
join('assests/database', 'pharmacy2.db')里的assests是拼写错误,正确应为assets,这会导致无法加载到assets中的数据库文件。 - 数据库初始化顺序错误:你先调用
database获取数据库实例,但此时还没执行copyPasteAssetFileToRoot,导致openDatabase创建了一个空数据库,而非复制过来的预打包库。
修复步骤与代码
修复后的完整代码
import 'dart:developer'; import 'dart:io'; import 'package:flutter/services.dart'; import 'package:path_provider/path_provider.dart'; import 'package:sqflite/sqflite.dart'; import 'package:path/path.dart'; class DataBaseHelper { static Database? _database; DataBaseHelper._privateConstructor(); static final DataBaseHelper instance = DataBaseHelper._privateConstructor(); Future<Database> get database async { if (_database != null) { log("返回已存在的数据库实例"); return _database!; } log("开始初始化新数据库"); // 先复制assets数据库到应用目录,再初始化 await copyPasteAssetFileToRoot(); _database = await _initDatabase(); return _database!; } Future<Database> _initDatabase() async { Directory appDocDir = await getApplicationDocumentsDirectory(); String databasePath = join(appDocDir.path, 'pharmacy2.db'); return await openDatabase( databasePath, version: 2, // 如果预打包数据库版本低于当前设置的version,可在这里添加onUpgrade逻辑 // onUpgrade: (db, oldVersion, newVersion) { // // 执行表结构更新操作 // }, ); } Future<void> copyPasteAssetFileToRoot() async { Directory documentsDirectory = await getApplicationDocumentsDirectory(); String path = join(documentsDirectory.path, "pharmacy2.db"); // 检查数据库文件是否已存在 if (!await File(path).exists()) { log("开始复制assets中的数据库文件"); // 修正assets路径拼写错误 ByteData data = await rootBundle.load(join('assets/database', 'pharmacy2.db')); List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes); await File(path).writeAsBytes(bytes); log("数据库文件复制完成"); } else { log("数据库文件已存在,无需复制"); } } Future<void> getAllUniversity() async { Database db = await instance.database; var result = await db.query("MST_University"); log(result.toString()); } }
关键修改说明
- 修正路径拼写:将
assests改为assets,确保能正确读取assets目录下的数据库文件。 - 调整初始化顺序:在
databasegetter中先调用copyPasteAssetFileToRoot,确保复制完成后再打开数据库,避免打开空库。 - 优化存在性检查:用
await File(path).exists()替代FileSystemEntity.typeSync,异步检查更符合Flutter的异步规范。 - 添加空安全处理:将
_database的类型从var改为Database?,避免空安全警告。
额外注意事项
- 确保
pubspec.yaml中已正确配置assets路径:
flutter: assets: - assets/database/pharmacy2.db
- 如果预打包数据库的版本号低于代码中设置的
version:2,需要在openDatabase中实现onUpgrade回调,处理表结构的升级逻辑,否则会触发数据库升级错误。 - 测试前建议卸载旧应用重新安装,避免残留的空数据库文件影响测试结果。
内容的提问来源于stack exchange,提问作者Jeet Karena
相关产品推荐
相关产品推荐

