【问题标题】:What is the best way to generate Android Room Migrations?生成 Android 房间迁移的最佳方法是什么?
【发布时间】:2018-04-06 11:30:29
【问题描述】:

请注意,我来自熟悉 Entity Framework 的 .NET 背景。

因此,在 EF 迁移中,会为您生成实际的迁移。基本上,您在 POCO 对象中指定您想要的更改。添加新迁移时,它会在数据库和 POCO 对象之间进行比较并生成迁移脚本。你几乎不需要看它。

所以使用 Android Room,我发现我必须自己手工制作这些迁移。并且有一些规则意味着系统崩溃,除非您手工制作的迁移将架构完全置于 Room 认为它应该基于 POJO 对象的状态。

对我来说,这似乎是一项可以自动化的乏味且有风险的任务(就像 EF 迁移已经做到的那样)。所以我的问题是,是否有工具或其他东西可以自动进行这些迁移?如果没有,关于如何安全或有效地进行这些迁移的一些指导方针是什么?

【问题讨论】:

    标签: android entity-framework orm android-room


    【解决方案1】:

    我不确定今天是否有专门针对 Room 的这样的工具,但我几乎不怀疑,因为 Room 的稳定版本是在几个月前发布的。

    可以生成的一件小事是用于创建表的 SQL 语句。 只需添加:

    javaCompileOptions {
        annotationProcessorOptions {
            arguments = ["room.schemaLocation":
                                 "$projectDir/schemas".toString()]
        }
    }
    

    到你的 build.gradle 中的 android/defaultConfig 和 JSON with complete schemas will be generated

    要安全地进行这些迁移,您可以对它们进行全面测试 - 这已经很好地描述了 here

    关于效率,我建议创建像 Migration(1, 4) 这样的直接迁移

    【讨论】:

    • 谢谢。 json 输出中的表创建语句非常有用。不要忘记在@Database注解中确保exportSchema = true(默认为true),否则不会生成json文件。
    【解决方案2】:

    android 房间迁移是有问题的,因为即使列顺序不同也会显示迁移失败。但由于 sqlite 的限制,无法进行列类型更改等。按照 Michal 的回答执行并生成模式。

    然后使用JSON diff tool 来查看它如何生成您的特定表格。

    如果差异很容易,请在迁移脚本中执行必要的 alter 命令。我几乎放弃了这样做,而是按照我的新版本期望的方式创建一个新表,从旧表中复制数据,删除它,然后重命名正确创建的表。这是一些代码:

        static final Migration MIGRATION_3_4 = new Migration(3, 4) {
        @Override
        /**
         * Instead of trying to read the owl droppings of the error message, simply go to the schemas directory
         * and do a table copy of the before and after.  Look for the table creation in the updated schema number
         * then do an insert by doing a select * from the old
         * then remove the old and rename the new
         */
        public void migrate(SupportSQLiteDatabase _db) {
            _db.execSQL("CREATE TABLE IF NOT EXISTS crew2 (`crewId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `shortName` TEXT, `isCaptain` TEXT)");
            _db.execSQL("INSERT INTO crew2(crewid,name,shortname) SELECT * FROM crew_table");
            _db.execSQL("DROP TABLE crew_table");
            _db.execSQL("ALTER TABLE crew2 RENAME TO crew_table");
            _db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_crew_table_shortName` ON `crew_table` (`shortName`)");
    
        }
    };
    

    【讨论】:

      猜你喜欢
      • 2019-08-20
      • 1970-01-01
      • 2020-04-15
      • 2013-04-09
      • 2010-09-15
      • 2020-05-08
      • 2010-09-13
      • 1970-01-01
      • 2016-08-09
      相关资源
      最近更新 更多