颤振中的方铅矿迁移

我正在使用Ffltter SQflite在Ffltter中存储数据,到目前为止我还没有遇到任何问题。现在我想用它更新我的应用程序和数据库。到目前为止,我只是用新数据库替换旧数据库。但是现在有一些表我想保存在那里的数据(用户数据)。我怎样才能更换一些桌子并保留另一些桌子呢?(目前为止表格结构没有变化) 编辑:我正在使用SQlite的DB浏览器(当然,APP数据中的用户除外)在Ffltter外部创建和填充数据库

     Future<void> initDatabase() async {
    var databasesPath = await getDatabasesPath();
    var path = join(databasesPath, "recipes.db");

// Check if the database exists
    var exists = await databaseExists(path);

    if (!exists) {
      // Should happen only the first time you launch your application
      print("Creating new copy of database from asset");

      // Make sure the parent directory exists
      try {
        await Directory(dirname(path)).create(recursive: true);
      } catch (_) {}

      // Copy from asset
      ByteData data = await rootBundle.load(join("assets", "recipes.db"));
      List<int> bytes =
      data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);

      // Write and flush the bytes written
      await File(path).writeAsBytes(bytes, flush: true);

    } else {
      print("Opening existing database");
    }
// open the database

    db = await openDatabase(path,version: 2, readOnly: false);
  }

解决方案

迁移示例。

在下面的代码中,";openDatabase";方法的顺序如下:

  • 尝试通过参数中提供的链接恢复数据库

  • 如果数据库不存在,则该方法将执行onCreate参数中提供的代码

  • 如果数据库存在,则该方法将检查数据库的版本,并将其与作为参数提供的版本号进行比较。

  • 如果数据库的版本与作为参数提供的版本不对应,则该方法将执行onUpgrade参数的代码。

基于Medium文章,但不使用"sqlite_Migration"包

对于该示例,我正在初始化一个包含id和first_name列的USERS表。

// I use a map for more readability, the key represents the version of the db
  Map<int, String> migrationScripts = {
    1: '''CREATE TABLE users (
              id INTEGER PRIMARY KEY,
              first_name TEXT)
              '''
  };

  Future initDatabase() async {
    // count the number of scripts to define the version of the database
    int nbrMigrationScripts = migrationScripts.length;
    var db = await openDatabase(
      join(await getDatabasesPath(), "database.db"),
      version: nbrMigrationScripts,
      // if the database does not exist, onCreate executes all the sql requests of the "migrationScripts" map
      onCreate: (Database db, int version) async {
        for (int i = 1; i <= nbrMigrationScripts; i++) {
          await db.execute(migrationScripts[i]);
        }
      },
      /// if the database exists but the version of the database is different 
      /// from the version defined in parameter, onUpgrade will execute all sql requests greater than the old version
      onUpgrade: (db, oldVersion, newVersion) async {
        for (int i = oldVersion + 1; i <= newVersion; i++) {
          await db.execute(migrationScripts[i]);
        }
      },
    );
    return db;
  }

现在,如果我要添加LAST_NAME列,我只需在"MigrationScripts"映射中添加SQL查询。

Map<int, String> migrationScripts = {
    1: '''CREATE TABLE users (
              id INTEGER PRIMARY KEY,
              first_name TEXT)
              ''',
    2: 'ALTER TABLE users ADD last_name TEXT'
  };
    如果用户已经具有版本1数据库, onUpgrade将运行地图的第二个脚本

  • 如果用户刚刚安装了应用程序 onCreate将执行地图的两个脚本。

编辑: 包含多个表的用例

Map<int, String> migrationScripts = {
    1: '''CREATE TABLE users (
              id INTEGER PRIMARY KEY,
              first_name TEXT)
              ''',
    2: 'ALTER TABLE users ADD last_name TEXT',
    3: '''CREATE TABLE posts (
              id INTEGER PRIMARY KEY,
              user_id INTEGER,
              content TEXT)
              ''',
    4: 'ALTER TABLE posts ADD title TEXT',
    5: 'ALTER TABLE users ADD age INTEGER'
  };

相关文章