(Android) 房间数据库迁移不会更改数据库
(Android) Room database migration doesn't change database
我需要更新 SQLite-Database
所以我创建了一个迁移。
在逐步调试此迁移时,没有错误,但正如我所见,只有“日志文件”已更新。
更改永远不会提交到数据库,我真的不明白我做错了什么,所以也许有人可以提供建议。?
我有一个名为 'image' 的 table,我需要创建一个名为 'attachment' 的 table。之后,我需要将所有数据从 'image' 移动到 'attachment',handle/transform 一些数据,最后删除 table 'image'.
这是我的实现:
1.我将库添加到我的项目
implementation android.arch.persistence.room:runtime:1.0.0
implementation android.arch.persistence.room:compiler:1.0.0
2。创建迁移
val MIGRATION_2_3: Migration = object : Migration(2, 3) {
override fun migrate(database: SupportSQLiteDatabase) {
// create table 'attachment'
database.execSQL("CREATE TABLE attachment (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, extenal_id INTEGER NOT NULL, userId TEXT, createdDateTime TEXT, displayFileName TEXT, fileExtension TEXT NOT NULL, noData INTEGER, identifier TEXT, commentText TEXT, localBaseFileName TEXT, dirty INTEGER NOT NULL, task_id TEXT NOT NULL, attachmentType INTEGER NOT NULL)")
// migrate data from table 'image' to 'attachment'
val cursor = database.query("SELECT * FROM image")
cursor.moveToFirst()
while (!cursor.isAfterLast) {
// get stored values
val image_id = cursor.getInt(0)
val externalId = cursor.getLong(1)
val customIdentifier = cursor.getString(2)
val createdAt = cursor.getString(3)
val imageType = cursor.getString(4)
val commentText = cursor.getString(5)
val createdBy = cursor.getString(6)
// cursor.getString(7)/ / not used anymore
val imageName = cursor.getString(8)
val dirty = cursor.getInt(9)
val task_id = cursor.getString(10)
// cursor.getString(11) // not used anymore
// create migration only for availably images
if (!imageName.isNullOrEmpty()) {
// get file extension or 'unknown' if not known
val fileExtension = MimeTypeMap.getSingleton().getExtensionFromMimeType(imageType) ?: "unknown"
val contentValues = ContentValues()
contentValues.put("id", image_id)
contentValues.put("external_id", externalId)
contentValues.put("userId", createdBy)
contentValues.put("createdDateTime", createdAt)
contentValues.put("displayFileName", imageName)
contentValues.put"fileExtension", fileExtension)
contentValues.put"noData", false)
contentValues.put("identifier", customIdentifier)
contentValues.put("commentText", commentText)
contentValues.put("localBaseFileName", imageName.split("_")[0])
contentValues.put("dirty", dirty)
contentValues.put("task_id", task_id)
contentValues.put("attachmentType", DatabaseManager.ATTACHMENT_TYPE_IMAGE)
// insert new data
database.insert("attachment", SQLiteDatabase.CONFLICT_REPLACE, contentValues)
}
// load next entry
cursor.moveToNext()
}
cursor.close()
// delete old table 'image'
// database.execSQL("DROP TABLE image")
}
}
3。将迁移添加到我的数据库实现
Room
.databaseBuilder(context, Database::class.java, "my_db.db")
.fallbackToDestructiveMigration()
.addMigrations(MIGRATION_2_3)
.build()
当我 运行 调用迁移代码时没有任何错误。但是在迁移之后,只有 'journal' 文件被更新,而不是数据库本身!?
我是不是漏了什么?没看懂........¯\_(ツ)_/¯
真丢脸...
所以,这是我的解决方案或出了什么问题 ;)
我总是通过迁移过程进行调试,并在迁移完成后终止进程....结果如上所述。
至少我只需要更进一步就可以看到,在我的实体上有不同的实现-class 用于附件和 SQL-语句用于创建 table 迁移期间...
已创建字段 'id',属性为:
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL
而实体的这个属性可以为空!
所以,我学到的是:
现在我明白迁移不会抛出异常,因为 table 的创建是正确的,并且错误出现在新的初始加载过程中,因为只有这样才能检测到差异。
我不明白为什么日志在迁移后没有直接合并到数据库,但是好吧,这只是 Android 上的又一件奇怪的事情 ;)
我希望这会对某人有所帮助。
我需要更新 SQLite-Database
所以我创建了一个迁移。
在逐步调试此迁移时,没有错误,但正如我所见,只有“日志文件”已更新。
更改永远不会提交到数据库,我真的不明白我做错了什么,所以也许有人可以提供建议。?
我有一个名为 'image' 的 table,我需要创建一个名为 'attachment' 的 table。之后,我需要将所有数据从 'image' 移动到 'attachment',handle/transform 一些数据,最后删除 table 'image'.
这是我的实现:
1.我将库添加到我的项目
implementation android.arch.persistence.room:runtime:1.0.0
implementation android.arch.persistence.room:compiler:1.0.0
2。创建迁移
val MIGRATION_2_3: Migration = object : Migration(2, 3) {
override fun migrate(database: SupportSQLiteDatabase) {
// create table 'attachment'
database.execSQL("CREATE TABLE attachment (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, extenal_id INTEGER NOT NULL, userId TEXT, createdDateTime TEXT, displayFileName TEXT, fileExtension TEXT NOT NULL, noData INTEGER, identifier TEXT, commentText TEXT, localBaseFileName TEXT, dirty INTEGER NOT NULL, task_id TEXT NOT NULL, attachmentType INTEGER NOT NULL)")
// migrate data from table 'image' to 'attachment'
val cursor = database.query("SELECT * FROM image")
cursor.moveToFirst()
while (!cursor.isAfterLast) {
// get stored values
val image_id = cursor.getInt(0)
val externalId = cursor.getLong(1)
val customIdentifier = cursor.getString(2)
val createdAt = cursor.getString(3)
val imageType = cursor.getString(4)
val commentText = cursor.getString(5)
val createdBy = cursor.getString(6)
// cursor.getString(7)/ / not used anymore
val imageName = cursor.getString(8)
val dirty = cursor.getInt(9)
val task_id = cursor.getString(10)
// cursor.getString(11) // not used anymore
// create migration only for availably images
if (!imageName.isNullOrEmpty()) {
// get file extension or 'unknown' if not known
val fileExtension = MimeTypeMap.getSingleton().getExtensionFromMimeType(imageType) ?: "unknown"
val contentValues = ContentValues()
contentValues.put("id", image_id)
contentValues.put("external_id", externalId)
contentValues.put("userId", createdBy)
contentValues.put("createdDateTime", createdAt)
contentValues.put("displayFileName", imageName)
contentValues.put"fileExtension", fileExtension)
contentValues.put"noData", false)
contentValues.put("identifier", customIdentifier)
contentValues.put("commentText", commentText)
contentValues.put("localBaseFileName", imageName.split("_")[0])
contentValues.put("dirty", dirty)
contentValues.put("task_id", task_id)
contentValues.put("attachmentType", DatabaseManager.ATTACHMENT_TYPE_IMAGE)
// insert new data
database.insert("attachment", SQLiteDatabase.CONFLICT_REPLACE, contentValues)
}
// load next entry
cursor.moveToNext()
}
cursor.close()
// delete old table 'image'
// database.execSQL("DROP TABLE image")
}
}
3。将迁移添加到我的数据库实现
Room
.databaseBuilder(context, Database::class.java, "my_db.db")
.fallbackToDestructiveMigration()
.addMigrations(MIGRATION_2_3)
.build()
当我 运行 调用迁移代码时没有任何错误。但是在迁移之后,只有 'journal' 文件被更新,而不是数据库本身!?
我是不是漏了什么?没看懂........¯\_(ツ)_/¯
真丢脸...
所以,这是我的解决方案或出了什么问题 ;)
我总是通过迁移过程进行调试,并在迁移完成后终止进程....结果如上所述。
至少我只需要更进一步就可以看到,在我的实体上有不同的实现-class 用于附件和 SQL-语句用于创建 table 迁移期间...
已创建字段 'id',属性为:
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL
而实体的这个属性可以为空!
所以,我学到的是: 现在我明白迁移不会抛出异常,因为 table 的创建是正确的,并且错误出现在新的初始加载过程中,因为只有这样才能检测到差异。
我不明白为什么日志在迁移后没有直接合并到数据库,但是好吧,这只是 Android 上的又一件奇怪的事情 ;)
我希望这会对某人有所帮助。