繁体   English   中英

如何更新版本数据库 SQFLite flutter?

[英]How to update version database SQFLite flutter?

我需要在我的本地数据库中创建新表并删除其他表,但是仅更改数据库版本是行不通的,因为它没有创建我需要的新表。

以同样的方式我已经尝试过 onUpgrade 但它没有用

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

  }


  initDB()async {
    Directory documentDirectory = await getApplicationDocumentsDirectory();
    String path = join( documentDirectory.path, 'DB.db' );
     var ouDb =  await openDatabase(path, version: 2,onCreate: onCreate, onUpgrade: onUpgrade);
     return ouDb;
    }

  FutureOr<void> onCreate(Database db, int version) async {

      await db.execute('CREATE TABLE nameTable0...');



      db.execute("DROP TABLE IF EXISTS NameTable1");
      db.execute("DROP TABLE IF EXISTS NameTable2");



  }

  FutureOr<void> onUpgrade(Database db, int oldVersion, int newVersion) async{
      if (oldVersion < newVersion) {
        await db.execute('CREATE TABLE NameTable3 ...');
      }
      //onCreate(db, newVersion); 
  }

您需要使用onUpgrade

initDb() async {
    Directory documentDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentDirectory.path, 'maindb.db');
    var ourDb = await openDatabase(path, version: 2, onCreate: _onCreate, onUpgrade: _onUpgrade);
    return ourDb;
  }

  // UPGRADE DATABASE TABLES
  void _onUpgrade(Database db, int oldVersion, int newVersion) {
    if (oldVersion < newVersion) {
      // you can execute drop table and create table
      db.execute("ALTER TABLE tb_name ADD COLUMN newCol TEXT;");
    }
  }

我想它会帮助你...

Future<Database> openDatabase(String path,
    int version,
    {OnDatabaseConfigureFn? onConfigure,
      OnDatabaseCreateFn? onCreate,
      OnDatabaseVersionChangeFn? onUpgrade,
      OnDatabaseVersionChangeFn? onDowngrade,
      OnDatabaseOpenFn? onOpen,
      bool readOnly = false,
      bool singleInstance = true}) {
  final options = OpenDatabaseOptions(
      version: 4,
      onConfigure: onConfigure,
      onCreate: _createDb,
      onUpgrade: _upgradeDb,
      onDowngrade: onDowngrade,
      onOpen: onOpen,
      readOnly: readOnly,
      singleInstance: singleInstance);
  return databaseFactory.openDatabase(path, options: options);
}

在代码中的任何位置调用它。

尝试添加 Future 作为返回类型并从查询中删除分号。 这段代码对我有用。

// UPGRADE DATABASE TABLES
Future _onUpgrade(Database db, int oldVersion, int newVersion) async {  
  if (oldVersion < newVersion) {
    // you can execute drop table and create table
    db.execute("ALTER TABLE tb_name ADD COLUMN newCol TEXT");
  }
}

我看到很多解释如何在openDatabaseonUpgrade中执行以下检查的答案:

 if (oldVersion < newVersion) {
      await db.execute('CREATE TABLE CUSTOMER....');
 }

这在执行您的第一次数据库升级(即版本 1 到 2)时会起作用,但在执行您的第二次(比如 2 到 3)时会失败,因为表“CUSTOMER”已经创建。 所以你需要逻辑只调用升级一次。 此外,您可能使用的是数据库版本 10,而用户使用的是版本 5,因此您只需要处理 6、7、8、9 和 10 的升级。下面是我为处理这些情况而构建的逻辑:

  static Future<Database?> getDatabase() async {

    if (_dbInstance == null) {
      var databasesPath = await getDatabasesPath();
      String path = join(databasesPath, _databaseName);

      _dbInstance = await openDatabase(path, version: _databaseVersion,
          
      onUpgrade: (Database db, int oldVersion, int newVersion) async {
        //
        //Iterate from the current version to the latest version and execute SQL statements
        for (int version = oldVersion; version < newVersion; version++) {
          await _performDBUpgrade(db, version + 1);
        }
      }, 

      onCreate: (Database db, int newVersion) async {
        //
        //Start from version 1 to current version and create DB
        for (int version = 0; version < newVersion; version++) {
          await _performDBUpgrade(db, version + 1);
        }
      });
    }

    return _dbInstance;
  }

  //Call to upgrade the database. [upgradeToVersion] is the version of SQL statements that should be
  //executed.  A version of 1 is the initial creation of the database.   Anything higher would
  //be an upgrade of the database.  This function should be called once for every version upgrade.
  //For example, if current version is 1 and user is now performing an update and new version is
  //5, then this function should be called 4 times (from `onUpgrade`), where [upgradeToVersion] would be passed a 2, 3, 4 and 5.
  
  static Future<void> _performDBUpgrade(Database db, int upgradeToVersion) async {
    switch (upgradeToVersion) {
      //Upgrade to V1 (initial creation)
      case 1:
        await _dbUpdatesVersion_1(db);
        break;

      //Upgrades for V2
      case 2:
        //await _dbUpdatesVersion_2(db);
        break;
    }
  }

  ///Database updates for Version 1 (initial creation)
  static Future<void> _dbUpdatesVersion_1(Database db) async {
      await db.execute('CREATE TABLE Customer...)');
  }
 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM