如何将 Not Null 表列迁移到 Android Room 数据库中的 Null

Posted

技术标签:

【中文标题】如何将 Not Null 表列迁移到 Android Room 数据库中的 Null【英文标题】:How to Migrate Not Null table column into Null in Android Room database 【发布时间】:2019-12-14 22:48:04 【问题描述】:

我是 android 房间库的新手。我需要将 Not Null 列迁移到 Null, 但是房间迁移只允许在 ALTER 表查询中添加或重命名。如何执行列迁移查询?

@Entity(tableName = "vehicle_detail")
data class VehicleDetailsEntity(
    @PrimaryKey(autoGenerate = true)
    val vehicleClientId: Long = 0,
    val vehicleId: String,
    val updatedOn: Date,
    val updatedBy: String
)

我需要把表结构改成

@Entity(tableName = "vehicle_detail")
data class VehicleDetailsEntity(
    @PrimaryKey(autoGenerate = true)
    val vehicleClientId: Long = 0,
    val vehicleId: String,
    val updatedOn: Date?,
    val updatedBy: String?
)

java.lang.IllegalStateException: Room 无法验证数据完整性。看起来您已更改架构但忘记更新版本号。您可以通过增加版本号来解决此问题。

【问题讨论】:

SQLite - alter a table's column type?的可能重复 【参考方案1】:

您需要运行迁移,因为 SQLite 不允许修改列约束。

对于该迁移,您需要创建一个新的临时表并将所有以前的数据复制到其中,然后删除旧表并将临时表重命名为所需的表名。

如果您有一个方案目录,您可以找到您应该在迁移时复制的确切创建 SQL 查询(我只是从我的一个方案中找出来的,不可能 100% 正确):

val MIGRATION_1_2: Migration = object : Migration(1, 2) 
    override fun migrate(database: SupportSQLiteDatabase) 
        // Create the new table
        database.execSQL(
            "CREATE TABLE IF NOT EXISTS VehicleDetailsEntityTmp (vehicleId TEXT NOT NULL, updatedOn TEXT, updatedBy TEXT,vehicleClientId INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL )"
        )

        // Copy the data
        database.execSQL(
            "INSERT INTO VehicleDetailsEntityTmp (vehicleId, updatedOn, updatedBy ,vehicleClientId) SELECT vehicleId, updatedOn, updatedBy ,vehicleClientId FROM VehicleDetailsEntity ")

        // Remove the old table
        database.execSQL("DROP TABLE VehicleDetailsEntity")

        // Change the table name to the correct one
        database.execSQL("ALTER TABLE VehicleDetailsEntityTmp RENAME TO VehicleDetailsEntity")
    

【讨论】:

以上是关于如何将 Not Null 表列迁移到 Android Room 数据库中的 Null的主要内容,如果未能解决你的问题,请参考以下文章

将NOT NULL列插入现有表

如何使用 pyspark 将 null 分配给配置单元表列

使用迁移更改表列的默认值

将 Vue 2 迁移到 Vue 3,typeError: Vue is not a constructor

完整性约束违规:19 NOT NULL 约束因迁移表中没有的内容而失败

在现有表中插入 NOT NULL 列