生成Android Room Migrations的最佳方法是什么?

时间:2018-04-06 11:30:29

标签: android entity-framework orm android-room

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

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

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

对我来说,这似乎是一项繁琐而又危险的任务,可以实现自动化(就像EF迁移一样)。所以我的问题是,是否有工具或其他东西会自动进行这些迁移?如果没有,关于如何安全或有效地进行这些迁移的指导原则是什么?

2 个答案:

答案 0 :(得分:0)

我不确定今天是否有专门用于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)

答案 1 :(得分:0)

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

schema location

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

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

    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`)");

    }
};