如何从 Flutter 资产文件夹中的现有数据库中读取数据,我遇到了错误
How do I read data from a existing database in the assets folder on Flutter, I am stuck with errors
我正在尝试从数据库中读取数据,该数据库已经在外部创建并放置在我项目的资产文件夹中。我已经安静地检查了一些教程来构建代码。这里只是将我的资产文件夹中的数据库复制到应用程序文档目录,并尝试使用 rawQuery 方法获取(调试打印到控制台)列 "father" 中的数据计数,我的 table 名称是 "items".
我收到一条错误消息,没有这样的 table。所以我猜我的数据库助手 class.
上有一个损坏的代码
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;
}
}
我参考了 Mr. 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;
}
我仍然不明白为什么它不能与 opendatabase
的 oncreate
语句一起使用,但没有问题,因为它在文档中描述:https://github.com/tekartik/sqflite/blob/master/sqflite/doc/opening_asset_db.md
我正在尝试从数据库中读取数据,该数据库已经在外部创建并放置在我项目的资产文件夹中。我已经安静地检查了一些教程来构建代码。这里只是将我的资产文件夹中的数据库复制到应用程序文档目录,并尝试使用 rawQuery 方法获取(调试打印到控制台)列 "father" 中的数据计数,我的 table 名称是 "items". 我收到一条错误消息,没有这样的 table。所以我猜我的数据库助手 class.
上有一个损坏的代码 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;
}
}
我参考了 Mr. 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;
}
我仍然不明白为什么它不能与 opendatabase
的 oncreate
语句一起使用,但没有问题,因为它在文档中描述:https://github.com/tekartik/sqflite/blob/master/sqflite/doc/opening_asset_db.md