通过正确使用onUpgrade回调升级数据库

时间:2019-06-09 13:58:28

标签: database flutter dart callback sqflite

我正在从网站(JSON)提取数据并将其保存在数据库中。这很好。但是,每次从Internet上获取的数据发生更改时,我都希望使用新的版本号升级数据库。为此,我认为最好的方法是删除表,升级数据库编号版本并重新创建表,然后再用新数据填充表(至少有一种方法可以只插入新记录,而仅更新具有更改)。

我看到可以用sqflite插件在数据库上进行onUpgrade回调来完成。

因此,我使用Helper方法创建了一个init(),用于打开数据库。 但是,我不知道何时调用onUpgrade回调。实际上,在下面的代码中,version始终为1。

我想有一种初始化数据库的方法:

  • 如果不存在则创建它,或者
  • 如果未指定编号版本(如此类),则打开当前版本,或者
  • 通过自动增加版本号(例如通过调用database.upgrade())来升级到新版本。

您认为使用唯一方法可以做到吗?还是需要将其拆分为两种方法?如果是,则onUpgrade回调有什么意义?

class DBHelper {
  // Private constructor
  DBHelper._privateConstructor();

  // Get an instance of DBHelper
  static final DBHelper _dbHelper = DBHelper._privateConstructor();

  // Getter to get the instance of the DBHelper
  factory DBHelper() => _dbHelper;

  static Database _database;

  Future<Database> get database async {
    if (_database != null) return _database;
    // lazily instantiate the db the first time it is accessed
    _database = await init();
    return _database;
  }

  Future<Database> init() async {
    print("DBHelper: init database");
    // Get a location using path_provider
    String path = await getDBPath();
    // I THINK ALL HAPPENS HERE
    return await openDatabase(path, version: 1, onCreate: _onCreate, onUpgrade: _onUpgrade);
  }

  void _onCreate(Database db, int version) async {
    print("DBHelper: _onCreate called");
    // When creating the db, create the table
    _createTable();
  }

  void _onUpgrade(Database db, int oldVersion, int newVersion) async{
    print("DBHelper: _onUpgrade called");
    try {
      await db.transaction((Transaction txn) async {
        await txn.execute("DROP TABLE TABLE_NAME");
      });
    } catch (e) {
      print("Error : " + e.toString());
    }
    _createTable();
  }

  void _createTable() async {
    Database db = await database;
    try {
      await db.transaction((Transaction txn) async {
        await txn.execute("CREATE TABLE TABLE_NAME ("
            "TABLE_ID INTEGER PRIMARY KEY AUTOINCREMENT,"
            "TABLE_INT INTEGER,"
            "TABLE_TEXT TEXT,");");
      });
    } catch (e) {
      print("Error : " + e.toString());
    }
  }
}

最佳

1 个答案:

答案 0 :(得分:0)

sqflite中的数据库版本控制与Android中已完成的操作匹配,其中版本是具有特定架构的应用程序特定版本的常量。 onCreate/onUpgrade通常在应用程序生命周期内仅被调用一次。无论如何,除非您关闭并重新打开数据库,否则它不会被调用。参见https://github.com/tekartik/sqflite/blob/master/sqflite/doc/migration_example.md

因此,我要说的是,现在存在的用户版本不符合您的需求。因此,在您的方案中,我不会使用此值,也不会使用onUpgrade。但是,您可以定义自己的单例值(即您自己的版本系统),并在数据库打开时在事务中删除/创建表。没有什么可以阻止您这样做的。