記錄一下Room數據庫遷移過程中遇到的問題。要遷移Room數據庫,只要需要實現androidx.room.migration.Migration即可。
下面記錄三種情況
- 修改表的結構
object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
// 創建新的臨時表
database.execSQL("CREATE TABLE publish_post_bean_new (uid TEXT NOT NULL DEFAULT '' ,value TEXT NOT NULL DEFAULT '' ,time INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(time))")
// 複製數據
database.execSQL("INSERT INTO publish_post_bean_new (uid, value,time) SELECT uid, value ,strftime('%s','now')*1000 FROM publish_post_bean")
// 刪除表結構
database.execSQL("DROP TABLE publish_post_bean")
// 臨時表名稱更改
database.execSQL("ALTER TABLE publish_post_bean_new RENAME TO publish_post_bean")
}
}
說明:publish_post_bean
增加了一個time
的字段,並且修改了主鍵的類型,先創建了一個臨時表,再複製數據,其中複製過程中用strftime('%s','now')
來獲取當前的時間。
- 只是增加字段
object : Migration(2, 3) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE publish_post_bean ADD COLUMN article TEXT NOT NULL DEFAULT '' ")
database.execSQL("ALTER TABLE publish_post_bean ADD COLUMN type INTEGER NOT NULL DEFAULT 0 ")
}
}
- 創建新表
object : Migration(3, 4) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE tag_history_bean (tagId TEXT NOT NULL DEFAULT '' ,uid TEXT NOT NULL DEFAULT '' ,value TEXT NOT NULL DEFAULT '' ,time INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(time))")
}
}
以上要注意的是,需要字段的時候,需要添加字段是否是null是否有默認值,比如:NOT NULL DEFAULT ''
,與你自己定義的bean類型一致。同時可以設置fallbackToDestructiveMigrationOnDowngrade
來回退數據庫升級時發生錯誤。