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

Flutter项目使用Sqflite实现数据库备份的方法咨询及示例请求

Sqflite实现Flutter数据库备份与提取方案

Sqflite完全支持数据库的备份与提取功能,核心逻辑是直接操作SQLite的数据库文件——因为Sqflite本质是基于文件型的SQLite数据库,复制文件即可完成备份,替换文件即可实现恢复。

一、核心实现方案(文件复制法)

1. 数据库备份

通过获取数据库文件路径,将其复制到指定的备份目录(如外部存储),代码示例:

import 'dart:io';
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';

Future<void> backupDatabase() async {
  // 获取应用内数据库存储路径
  String dbDir = await getDatabasesPath();
  File sourceDb = File('$dbDir/your_app_db.db');
  
  // 获取外部存储的文档目录(需权限支持)
  Directory? externalDocsDir = await getExternalStorageDirectory();
  if (externalDocsDir == null) return;

  // 创建备份目录(不存在则递归创建)
  Directory backupDir = Directory('${externalDocsDir.path}/app_db_backups');
  await backupDir.create(recursive: true);

  // 生成带时间戳的备份文件名,避免覆盖
  String timestamp = DateTime.now().millisecondsSinceEpoch.toString();
  File backupFile = File('${backupDir.path}/backup_$timestamp.db');

  // 执行文件复制
  await sourceDb.copy(backupFile.path);
}

2. 数据库恢复提取

将备份文件复制回应用的数据库路径,注意恢复前必须关闭数据库,避免文件占用:

import 'dart:io';
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';

Future<void> restoreDatabase(String backupFilePath) async {
  String dbDir = await getDatabasesPath();
  File targetDb = File('$dbDir/your_app_db.db');

  // 先关闭当前数据库连接,防止文件被锁定
  await closeDatabase();

  // 将备份文件覆盖到目标数据库路径
  await File(backupFilePath).copy(targetDb.path);

  // 重新打开数据库
  await openDatabase(targetDb.path);
}

关键注意事项

  • 权限配置:
    • Android:需在AndroidManifest.xml中添加READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE权限(Android 13+需适配MANAGE_EXTERNAL_STORAGE或分区存储权限)
    • iOS:需在Info.plist中添加NSDocumentFolderUsageDescription说明权限用途
  • 数据库状态:备份前确保无写入操作,避免文件损坏;恢复时必须关闭数据库连接
  • 路径适配:iOS的外部存储路径与Android不同,建议统一使用path_provider库的API获取目录

二、备选方案(数据导出法)

如果不想直接操作文件,可通过SQL查询导出全量数据为JSON/CSV格式,恢复时重新插入数据,适合需要跨格式备份的场景:

数据导出示例

import 'package:sqflite/sqflite.dart';
import 'dart:convert';

Future<String> exportDataToJson() async {
  Database db = await openDatabase('your_app_db.db');
  // 获取所有用户自定义表(排除SQLite系统表)
  List<Map<String, dynamic>> tablesRes = await db.rawQuery(
    "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'"
  );
  List<String> tables = tablesRes.map((e) => e['name'] as String).toList();

  Map<String, List<Map<String, dynamic>>> allData = {};
  for (String table in tables) {
    allData[table] = await db.query(table);
  }

  // 转换为JSON字符串保存
  return jsonEncode(allData);
}

数据恢复示例

import 'package:sqflite/sqflite.dart';
import 'dart:convert';

Future<void> importDataFromJson(String jsonData) async {
  Database db = await openDatabase('your_app_db.db');
  Map<String, List<Map<String, dynamic>>> dataMap = jsonDecode(jsonData);

  Batch batch = db.batch();
  dataMap.forEach((table, rows) {
    for (var row in rows) {
      batch.insert(table, row, conflictAlgorithm: ConflictAlgorithm.replace);
    }
  });
  // 批量提交插入操作
  await batch.commit(noResult: true);
}

三、示例项目结构参考

可以搭建一个极简的功能页面:

  • 两个按钮:「备份数据库」「恢复数据库」
  • 备份按钮点击后自动生成备份文件并提示成功
  • 恢复按钮通过file_picker库让用户选择本地备份文件,执行恢复操作

依赖库建议:sqflite、path_provider、file_picker

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 02:23:29