测试 Flutter 本地 sqflite 数据库 onUpgrade 并且应用更新后没有数据显示

Posted

技术标签:

【中文标题】测试 Flutter 本地 sqflite 数据库 onUpgrade 并且应用更新后没有数据显示【英文标题】:Testing Flutter local sqflite database onUpgrade and no data shown after app update 【发布时间】:2021-06-22 08:53:17 【问题描述】:

我想更新一个已经在 Google Play 上发布的应用程序,但事先我想测试一下本地 sqlite 数据库是否会在更新后保留它的所有数据,因为它存储用户添加的内容。

首先,我在旧版本的数据库中添加了一些内容,然后对其进行了更新。当我通过内部测试更新应用程序时,它没有显示任何数据,就好像它会创建一个空的新数据库一样。

db 路径是否可能已更改?如何检查? 会不会是旧的数据库被覆盖了?

还有什么我应该注意的吗?因为我只在数据库中添加了几列,并没有更改任何有关数据库初始化和数据库路径的代码。

使用的包:sqflite: 2.0.0+3 path: 1.8.0

数据库 dart 文件中的代码 sn-p :

    import 'package:path/path.dart';
    import 'package:sqflite/sqflite.dart';
    import 'package:sqflite/sqlite_api.dart';
  
    class DatabaseHelper

        /// ------- name variables ----------------
        static final _dbName = 'userTasks.db';
        static final _dbVersion = 2;                
        static final _tableName = 'myTasks';

        /// ------- table column Names -------------
        static final columnID = 'id';
        static final columnName = 'name';
        static final columnContent = 'content';
        static final columnType = 'type';
        static final columnDescription = 'description';
        static final columnFavorite = 'favorite';

        /// -------- DataBase initialization ---------
        DatabaseHelper._privateConstructor();
        static final DatabaseHelper instance = DatabaseHelper._privateConstructor();

        static Database _database;
        Future<Database> get database async
          if(_database !=null)  return _database;

          _database = await _initiateDatabase();
          return _database;
        

        _initiateDatabase () async

          Directory directory = await getApplicationDocumentsDirectory();
          String path = join(directory.path,_dbName);
          return await openDatabase(path, version: _dbVersion, onCreate: _onCreate, onUpgrade: _onUpgrade);

        

        /// ---------------    _onCreate() getting called on fresh install(no previous DB)  -----------------

        Future _onCreate(Database db, int version)
          db.execute(
              '''
              CREATE TABLE $_tableName( 
              $columnID INTEGER PRIMARY KEY,
              $columnName TEXT,
              $columnContent TEXT NOT NULL,
              $columnType TEXT NOT NULL,
              $columnDescription TEXT NOT NULL,
              $columnFavorite INTEGER)
              '''
          );
        

        /// ---------------    _onUpgrade() getting called on _dbVersion versionChange  -----------------

        Future _onUpgrade(Database db, int oldVersion, int newVersion) 
          db.execute(''' ALTER TABLE $_tableName ADD COLUMN $columnDescription TEXT''');
          db.execute(''' ALTER TABLE $_tableName ADD COLUMN $columnFavorite INTEGER DEFAULT 0 ''');
        


提前致谢!

【问题讨论】:

一个很好的创建数据库表的方法是添加CREATE TABLE IF NOT EXISTS ...,以防同名表已经存在 感谢您的建议,现在我至少可以确定它不会覆盖/替换旧数据库 【参考方案1】:

我不确定getApplicationDocumentsDirectory,但如果您使用getDatabasesPath 或只是一个没有路径的名称,并且如果您启用了自动备份 (https://developer.android.com/guide/topics/data/autobackup),它应该可以工作。

第一个测试可以在没有 google play 的情况下完成,只需保留您发布的每个 apk(即使您使用 bundle,最好也构建并保留 apk),以便您可以测试 2 个版本之间的正确迁移.

【讨论】:

我按照您的建议进行了测试 - 使用 apks。我尝试使用 getDatabasePath 以及仅使用数据库名称。我很确定它现在只是在另一个位置创建了一个数据库。当我卸载应用程序并安装较旧的 apk 时,它会打开以显示以前存储的所有旧数据,但是当我使用较新版本的 apk 更新它时,它不会显示任何旧数据。它只让我创建新条目。有什么想法可以进一步研究吗?【参考方案2】:

您可以更改数据库版本并刷新应用程序

看看 android:allowBackup="false" android:fullBackupOnly="false" https://developer.android.com/guide/topics/manifest/application-element

并查看此

Flutter how to backup and restore sqflite database?

【讨论】:

以上是关于测试 Flutter 本地 sqflite 数据库 onUpgrade 并且应用更新后没有数据显示的主要内容,如果未能解决你的问题,请参考以下文章

Flutter中的Sqflite,使用两个数据库(附件)

Flutter sqflite 打开现有数据库

Flutter 将数据插入数据库 sqflite

Flutter 应用中提供程序与 sqflite 的集成

Flutter Provider 和 sqflite 集成

Flutter:如何使用SQFlite存储的数据?