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

Flutter Sqflite报错DatabaseException:MST_University表不存在问题

问题分析与解决

核心问题

你遇到的no such table: MST_University错误,本质是代码没有正确将assets里的预打包数据库复制到应用目录,导致打开的是一个全新的空数据库,自然不存在目标表。

具体错误点

  1. Assets路径拼写错误:代码中join('assests/database', 'pharmacy2.db')里的assests是拼写错误,正确应为assets,这会导致无法加载到assets中的数据库文件。
  2. 数据库初始化顺序错误:你先调用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目录下的数据库文件。
  • 调整初始化顺序:在database getter中先调用copyPasteAssetFileToRoot,确保复制完成后再打开数据库,避免打开空库。
  • 优化存在性检查:用await File(path).exists()替代FileSystemEntity.typeSync,异步检查更符合Flutter的异步规范。
  • 添加空安全处理:将_database的类型从var改为Database?,避免空安全警告。

额外注意事项

  1. 确保pubspec.yaml中已正确配置assets路径:
flutter:
  assets:
    - assets/database/pharmacy2.db
  1. 如果预打包数据库的版本号低于代码中设置的version:2,需要在openDatabase中实现onUpgrade回调,处理表结构的升级逻辑,否则会触发数据库升级错误。
  2. 测试前建议卸载旧应用重新安装,避免残留的空数据库文件影响测试结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 22:16:16