Android Room:如何迁移列重命名?
Android Room: How to Migrate Column Renaming?
问题
我的应用程序崩溃了,因为我没有正确处理迁移。 我正在寻找一种解决方案来迁移我 table 中 1 列的名称。
在我的项目中,我有一个名为“content”的房间 table,具有 Double 属性“archivedCount'。在最新版本的应用程序中,属性 archivedCount 属性被重命名为 dismissCount,类型仍为 Double.
原始内容模型
@Entity(tableName = "content")
data class Content(@PrimaryKey var id: String, var archiveCount: Double) : Parcelable {...}
新内容模型
@Entity(tableName = "content")
data class Content(@PrimaryKey var id: String, var dismissCount: Double) : Parcelable {...}
尝试的解决方案
在阅读了 Google 开发技术推广工程师的解释 Understanding migrations with Room 后,我尝试了她在 post 部分 具有复杂架构更改的迁移[=45] 中概述的解决方案=] 这需要制作原始 table 的副本,删除旧的 table,然后重命名新创建的 table.
使用下面的方法,此行会出现运行时错误:database.execSQL("INSERT INTO content_new (id, dismissCount) SELECT id, archiveCount FROM users");
因为我已经清除了应用程序的缓存,所以旧的 table 不再存在。
我可以在不重新创建整个列的情况下更新单个列吗?table?
static final Migration MIGRATION_1_2 = new Migration(1, 2) {
@Override
public void migrate(SupportSQLiteDatabase database) {
// Create the new table
database.execSQL(
"CREATE TABLE content_new (id TEXT, dismissCount REAL, PRIMARY KEY(id))");
// Copy the data
database.execSQL("INSERT INTO content_new (id, dismissCount) SELECT id, archiveCount FROM users");
// Remove the old table
database.execSQL("DROP TABLE content");
// Change the table name to the correct one
database.execSQL("ALTER TABLE content_new RENAME TO content");
}
};
有一个不用迁移的解决方案——使用ColumnInfo:
data class Content(@PrimaryKey var id: String, @ColumnInfo(name = "archiveCount") var dismissCount: Double) : Parcelable{...}
数据库列仍将是 archiveCount
,但在 Kotlin 中 属性 将被重命名。
解决方案
感谢@TimBiegeleisen 的指导,我们发现 Android implementation of SQLite 3.19 for API 27 and 28 has not yet upgraded to the version 3.25 SQLite which allows this feature outlined in this Whosebug post.
一旦 Android 升级这样的命令以更改 table 列将是可能的:database.execSQL("ALTER TABLE content RENAME COLUMN archiveCount TO dismissCount")
问题
我的应用程序崩溃了,因为我没有正确处理迁移。 我正在寻找一种解决方案来迁移我 table 中 1 列的名称。
在我的项目中,我有一个名为“content”的房间 table,具有 Double 属性“archivedCount'。在最新版本的应用程序中,属性 archivedCount 属性被重命名为 dismissCount,类型仍为 Double.
原始内容模型
@Entity(tableName = "content")
data class Content(@PrimaryKey var id: String, var archiveCount: Double) : Parcelable {...}
新内容模型
@Entity(tableName = "content")
data class Content(@PrimaryKey var id: String, var dismissCount: Double) : Parcelable {...}
尝试的解决方案
在阅读了 Google 开发技术推广工程师的解释 Understanding migrations with Room 后,我尝试了她在 post 部分 具有复杂架构更改的迁移[=45] 中概述的解决方案=] 这需要制作原始 table 的副本,删除旧的 table,然后重命名新创建的 table.
使用下面的方法,此行会出现运行时错误:database.execSQL("INSERT INTO content_new (id, dismissCount) SELECT id, archiveCount FROM users");
因为我已经清除了应用程序的缓存,所以旧的 table 不再存在。
我可以在不重新创建整个列的情况下更新单个列吗?table?
static final Migration MIGRATION_1_2 = new Migration(1, 2) {
@Override
public void migrate(SupportSQLiteDatabase database) {
// Create the new table
database.execSQL(
"CREATE TABLE content_new (id TEXT, dismissCount REAL, PRIMARY KEY(id))");
// Copy the data
database.execSQL("INSERT INTO content_new (id, dismissCount) SELECT id, archiveCount FROM users");
// Remove the old table
database.execSQL("DROP TABLE content");
// Change the table name to the correct one
database.execSQL("ALTER TABLE content_new RENAME TO content");
}
};
有一个不用迁移的解决方案——使用ColumnInfo:
data class Content(@PrimaryKey var id: String, @ColumnInfo(name = "archiveCount") var dismissCount: Double) : Parcelable{...}
数据库列仍将是 archiveCount
,但在 Kotlin 中 属性 将被重命名。
解决方案
感谢@TimBiegeleisen 的指导,我们发现 Android implementation of SQLite 3.19 for API 27 and 28 has not yet upgraded to the version 3.25 SQLite which allows this feature outlined in this Whosebug post.
一旦 Android 升级这样的命令以更改 table 列将是可能的:database.execSQL("ALTER TABLE content RENAME COLUMN archiveCount TO dismissCount")