database - flutter 中的Sqlite迁移

标签 database sqlite flutter migration sqflite

我正在使用 flutter SQflite 在 flutter 中存储数据,到目前为止我没有问题。现在我想用它更新我的应用程序和数据库。到目前为止,我只是用新数据库替换旧数据库。但是现在有一些表我想保留数据(用户数据)。如何替换某些表并保留其他表? (到目前为止表结构没有变化)
编辑:我正在使用 SQLite 的 DB 浏览器在 flutter 之外创建和填充数据库(当然,应用程序数据中的用户除外)

     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 参数的代码。

  • 基于中等文章,但不使用“sqlite_migration”包
    例如,我正在初始化一个包含 id 和 first_name 列的用户表。
    // 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 将运行 map 的第二个脚本
  • 如果用户刚刚安装了应用程序
    onCreate 将执行 map 的两个脚本。
  • 关于database - flutter 中的Sqlite迁移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61749660/

    相关文章:

    php - Facebook 登录和 MySQL

    mysql - 具有最佳插入/秒性能的数据库?

    sql - 数据库表设计问题

    database - 仅使用MySQL命令备份MySQL数据库

    sql - 如何在 postgresql 中创建类似于 oracle 的只读 View ?

    c++ - 如何为 SQLite 表中的树建立索引?

    android - 服务中的 startManagingCursor()?

    firebase - 如何在flutter中有效地访问firestore引用字段的数据?

    flutter CupertinoActionSheet : how to define Variable number of actions

    dart - 从 Flutter 记录大字符串