请注意,我来自.NET背景,我熟悉Entity Framework。
因此,在EF迁移中,会为您生成实际迁移。基本上,您在POCO对象中指定所需的更改。添加新迁移时,它会在数据库和POCO对象之间进行差异,并生成迁移脚本。你几乎不用看它。
所以使用Android Room,我发现自己必须手工完成这些迁移。并且有一些规则意味着系统崩溃,除非您手工移植将模式完全置于状态Room认为它应该基于POJO对象。
对我来说,这似乎是一项繁琐而又危险的任务,可以实现自动化(就像EF迁移一样)。所以我的问题是,是否有工具或其他东西会自动进行这些迁移?如果没有,关于如何安全或有效地进行这些迁移的指导原则是什么?
答案 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 的回答进行操作并生成模式。
然后使用 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`)");
}
};