【问题标题】:How do you upgrade a flutter app with sqlite database?如何使用 sqlite 数据库升级 Flutter 应用程序?
【发布时间】:2020-11-30 11:04:31
【问题描述】:

我有一个使用 SQLITE 数据库的颤振应用程序。 我想发布应用商店和 Google Play 商店中应用的新版本更新。

新版本将有新的列和新的表。

在我的应用程序中包含哪些高级步骤,以便应用程序能够 a) 从现有数据库中复制所有现有用户记录 b) 将这些粘贴到新数据库中 - 升级后

当然,我可以将我的所有记录放在一个动态列表中 - 这是我所做的,但是我使用什么触发器,以便当用户升级到新版本(通过 App Store 或 google play store)我们可以优雅地将现有数据库中的所有用户数据复制到新版本吗?

【问题讨论】:

    标签: flutter dart upgrade


    【解决方案1】:

    来自sqflite documentation

    TL:DR

    迁移示例

    这是一个数据库架构迁移的简单示例,其中:

    将一列添加到现有表中 添加了一个表格

    // Our database path
    String path;
    // Our database once opened
    Database db;
    

    第一版

    第一个版本创建一个带有名称列的 Company 表。

    /// Create tables
    void _createTableCompanyV1(Batch batch) {
      batch.execute('DROP TABLE IF EXISTS Company');
      batch.execute('''CREATE TABLE Company (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT
    )''');
    }
    
    // First version of the database
    db = await factory.openDatabase(path,
        options: OpenDatabaseOptions(
            version: 1,
            onCreate: (db, version) async {
              var batch = db.batch();
              _createTableCompanyV1(batch);
              await batch.commit();
            },
            onDowngrade: onDatabaseDowngradeDelete));
    

    第二版

    假设我们要添加一个引用公司实体的新表 Employee。我们还想在 Company 实体中添加新的列描述。

    我们在onCreate 中处理新数据库的创建,并在onUpgrade 中处理架构迁移。另外由于我们想使用外键约束,我们在onConfigure.中配置我们的访问权限

    /// Let's use FOREIGN KEY constraints
    Future onConfigure(Database db) async {
      await db.execute('PRAGMA foreign_keys = ON');
    }
    
    /// Create Company table V2
    void _createTableCompanyV2(Batch batch) {
      batch.execute('DROP TABLE IF EXISTS Company');
      batch.execute('''CREATE TABLE Company (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT,
        description TEXT
    )''');
    }
    
    /// Update Company table V1 to V2
    void _updateTableCompanyV1toV2(Batch batch) {
      batch.execute('ALTER TABLE Company ADD description TEXT');
    }
    
    /// Create Employee table V2
    void _createTableEmployeeV2(Batch batch) {
      batch.execute('DROP TABLE IF EXISTS Employee');
      batch.execute('''CREATE TABLE Employee (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT,
        companyId INTEGER,
        FOREIGN KEY (companyId) REFERENCES Company(id) ON DELETE CASCADE
    )''');
    }
    
    // 2nd version of the database
    db = await factory.openDatabase(path,
        options: OpenDatabaseOptions(
            version: 2,
            onConfigure: onConfigure,
            onCreate: (db, version) async {
              var batch = db.batch();
              // We create all the tables
              _createTableCompanyV2(batch);
              _createTableEmployeeV2(batch);
              await batch.commit();
            },
            onUpgrade: (db, oldVersion, newVersion) async {
              var batch = db.batch();
              if (oldVersion == 1) {
                // We update existing table and create the new tables
                _updateTableCompanyV1toV2(batch);
                _createTableEmployeeV2(batch);
              }
              await batch.commit();
            },
            onDowngrade: onDatabaseDowngradeDelete));
    

    当您更改应用程序架构时,您必须重新启动您的应用程序。除非您正确关闭当前打开的数据库,否则 Flutter 热重载将不起作用。

    【讨论】:

    • 谢谢!所以,如果我理解正确,我需要在我们动态创建新模式的地方添加 onUpgrade 参数? IE。例如,我无法使用 SQLITEStudio 创建新数据库。必须使用 CREATE TABLE 语法创建新模式???
    • 是的,您需要添加 onUpgrade 不确定 sqlstudio 问题,但您可以尝试一下并告诉我
    • 升级后我们需要对其他表进行新升级...我们会在 onUpgrade 上删除当前查询/方法并用新的替换它吗?...不会混淆一段时间后,我们看到一些编辑,并且当它实际工作并执行所需的工作时,可能是作为数据库中的代码的全新表?
    猜你喜欢
    • 2013-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-14
    • 2011-05-13
    相关资源
    最近更新 更多