Flutter桌面端使用Drift导入资产SQLite数据库失败求助
Flutter桌面端用Drift导入现有SQLite资产库并查询记录
先确认依赖与资产配置
在pubspec.yaml中添加所需依赖,同时注册你的SQLite资产文件:
dependencies: flutter: sdk: flutter drift: ^2.14.0 drift_native: ^2.14.0 path_provider: ^2.1.2 path: ^1.8.3 dev_dependencies: flutter_test: sdk: flutter build_runner: ^2.4.8 drift_dev: ^2.14.0 flutter: assets: - assets/main_table_data_table.db
修正后的Drift数据库代码
你之前的代码缺少表实体定义和代码生成环节,这是Drift的核心要求。以下是完整可运行的代码(请根据你的实际表结构修改字段):
import 'package:drift/drift.dart'; import 'dart:io'; import 'package:drift/native.dart'; import 'package:flutter/services.dart'; import 'package:path_provider/path_provider.dart'; import 'package:path/path.dart' as p; // 对应你SQLite数据库中的表结构,字段名、类型必须完全匹配 class MainTables extends Table { IntColumn get id => integer().autoIncrement()(); TextColumn get name => text()(); // 这里添加你数据库中其他字段,比如 IntColumn get age => integer()(); } part 'database_model.g.dart'; @DriftDatabase(tables: [MainTables]) class MyDatabase extends _$MyDatabase { MyDatabase() : super(_openConnection()); @override int get schemaVersion => 1; // 查询表中所有记录的方法 Future<List<MainTable>> getAllRecords() async { return select(mainTables).get(); } } LazyDatabase _openConnection() { return LazyDatabase(() async { final dbFolder = await getApplicationDocumentsDirectory(); final targetFile = File(p.join(dbFolder.path, 'main_table.db')); if (!await targetFile.exists()) { // 从assets读取数据库文件并复制到应用目录 final assetData = await rootBundle.load(p.join('assets', 'main_table_data_table.db')); final bytes = assetData.buffer.asUint8List( assetData.offsetInBytes, assetData.lengthInBytes, ); await targetFile.writeAsBytes(bytes, flush: true); print('数据库已从assets复制'); } else { print('打开本地已存在的数据库'); } // 返回桌面端兼容的NativeDatabase连接 return NativeDatabase(targetFile); }); }
生成Drift必要代码
在终端运行以下命令,生成database_model.g.dart文件(Drift依赖该文件实现数据库操作):
flutter pub run build_runner build
在页面中查询并展示记录
创建页面初始化数据库,调用查询方法并展示数据:
import 'package:flutter/material.dart'; import 'database_model.dart'; class DatabaseDisplayPage extends StatefulWidget { const DatabaseDisplayPage({super.key}); @override State<DatabaseDisplayPage> createState() => _DatabaseDisplayPageState(); } class _DatabaseDisplayPageState extends State<DatabaseDisplayPage> { late MyDatabase _database; List<MainTable> _records = []; @override void initState() { super.initState(); _initDatabase(); } Future<void> _initDatabase() async { _database = MyDatabase(); _records = await _database.getAllRecords(); setState(() {}); } @override void dispose() { _database.close(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('所有记录')), body: _records.isEmpty ? const Center(child: CircularProgressIndicator()) : ListView.builder( itemCount: _records.length, itemBuilder: (context, index) { final record = _records[index]; return ListTile( title: Text(record.name), subtitle: Text('ID: ${record.id}'), // 根据你的字段添加更多展示内容 ); }, ), ); } }
关键注意事项
- 表实体类
MainTables必须和你现有SQLite数据库的表结构完全匹配,包括字段名、数据类型,否则查询会失败。 - 确保assets中的数据库文件名和代码中引用的一致,且
pubspec.yaml已正确注册该资产。 - 桌面端无需额外配置FFI,Drift的
NativeDatabase原生支持Windows、macOS、Linux平台。
内容的提问来源于stack exchange,提问作者Haider IO
相关产品推荐
相关产品推荐

