我如何从Flutter上Assets文件夹中的现有数据库中读取数据,我陷入了错误

时间:2020-01-01 16:29:02

标签: flutter sqflite

我正在尝试从已经在外部制作的数据库中读取数据,并将其放在我项目的Assets文件夹中。我已经安静地检查了一些教程来构建代码。这里只是将我的资产文件夹中的数据库复制到应用程序文档目录,并尝试使用rawQuery方法获取(父代)列中“父亲”列中的数据计数,我的表名为“ items”。 我收到一个错误消息,说没有这样的桌子。因此,我猜我的数据库助手类中的代码损坏了。

  static DatabaseHelper _databaseHelper; // Singleton DatabaseHelper
  static Database _database; // Singleton Database
  static String _path;

  DatabaseHelper._createInstance(); // Named constructor to create instance of DatabaseHelper

  factory DatabaseHelper() {
    if (_databaseHelper == null) {
      _databaseHelper = DatabaseHelper
          ._createInstance(); // This is executed only once, singleton object
    }
    return _databaseHelper;
  }

  Future<Database> get database async {
    if (_database == null) {
      _database = await initializeDatabase();
    }
    return _database;
  }

  Future<Database> initializeDatabase() async {
    // Get the directory path for both Android and iOS to store database.
    Directory directory = await getApplicationDocumentsDirectory();
    _path = directory.path + 'bomdb.sqlite';

    // Open/create the database at a given path
    var bomDatabase = await openDatabase(
        _path, version: 1, onCreate: _createDb);
    return bomDatabase;
  }

  void _createDb(Database db, int newVersion) async {
    ByteData data = await rootBundle.load('assets/bomdb.sqlite');
    List<int> bytes =
    data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
    debugPrint('Database is in path:  ' + _path);
    await new File(_path).writeAsBytes(bytes);
  }

  Future<int> sampleData() async {
    Database db = await this.database;
    List<Map<String, dynamic>> x = await db.rawQuery(
        'SELECT COUNT(father) FROM items');
    var res = await db.rawQuery('SELECT COUNT(father) FROM items');
    int result = Sqflite.firstIntValue(x);
    debugPrint(result.toString());
    return result;
  }
}

1 个答案:

答案 0 :(得分:1)

我参考了Tommie C先生提供的sqflite文档,我将initializeDatabase更改为以下内容,并删除了此处不需要的_createDb函数:

Future<Database> initializeDatabase() async {
var databasesPath = await getDatabasesPath();
var path = join(databasesPath, "bomdb.sqlite");

// Check if the database exists
var exists = await databaseExists(path);

if (!exists) {
  // Should happen only the first time you launch your application
  print("Creating new copy from asset");

  // Make sure the parent directory exists
  try {
    await Directory(dirname(path)).create(recursive: true);
  } catch (_) {}

  // Copy from asset
  ByteData data = await rootBundle.load(join("assets", "bomdb.sqlite"));
  List<int> bytes =
      data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);

  // Write and flush the bytes written
  await File(path).writeAsBytes(bytes, flush: true);
} else {
  print("Opening existing database");
}
// open the database
var bomDataTable = await openDatabase(path, readOnly: true);

return bomDataTable;
}

我仍然不知道为什么它不能与oncreate的{​​{1}}语句一起使用,但是在文档https://github.com/tekartik/sqflite/blob/master/sqflite/doc/opening_asset_db.md

中对此却没有问题。
相关问题