Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Migrate Not Null table column into Null in Android Room database

I'm new to android room library. I need to migrate a Not Null column to Null, But room migration only allow ADD or RENAME in ALTER table query. How do execute a column migration query?

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

I need to change table structure into

@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 cannot verify the data integrity. Looks like you've changed schema but forgot to update the version number. You can simply fix this by increasing the version number.

like image 741
Naveen Nagarajan Avatar asked Aug 07 '19 10:08

Naveen Nagarajan


People also ask

How we can do migration in room DB?

You can use AutoMigrationSpec to give Room the additional information that it needs to correctly generate migration paths. Define a static class that implements AutoMigrationSpec in your RoomDatabase class and annotate it with one or more of the following: @DeleteTable. @RenameTable.

How do I insert a non null field in an existing table?

You can add a not null column at the time of table creation or you can use it for an existing table. In the above table, we have declared Id as int type that does not take NULL value. If you insert NULL value, you will get an error. Here is the query to add a not null column in an existing table using alter command.


1 Answers

You need to run a migration since SQLite doesn't allow column constraint modification.

For that migration you need to create a new temp table and copy all your previous data to it, then delete the old table and rename the temp one to the needed table name.

If you have a scheme directory, you can find your exact creation SQL query which you should copy on your migration (I just figured it out from a scheme of mine and could not be 100% correct):

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")
    }
}
like image 170
axierjhtjz Avatar answered Nov 01 '22 16:11

axierjhtjz