【发布时间】:2019-12-09 17:13:58
【问题描述】:
我有一个数据库迁移问题
使用:Kotlin,房间
我想将数据库从 1 升级到 3
我已经成功地完成了从 1 到 2 和从 2 到 3 的迁移。
但是,当我尝试从 1 升级到 3 时,查询的 3 迁移结果返回版本 1 的架构。
版本 1:
帐户表
列:地址、类型、id、备忘录
第 2 版:
帐户表
列:地址、类型、路径、备忘
第 3 版:
帐户表
列:地址、类型、路径、备注、订单
private val MIGRATION_1_2: Migration = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.beginTransaction()
try {
database.execSQL("""
CREATE TABLE Account_tmp (
address TEXT NOT NULL, type TEXT, path TEXT, memo TEXT,
PRIMARY KEY(address))""")
database.query("SELECT * FROM Account").use { cursor ->
if (cursor != null && cursor.count > 0) {
while (cursor.moveToNext()) {
val address = cursor.getString(cursor.getColumnIndex("address"))
val type = cursor.getString(cursor.getColumnIndex("type"))
val path = "Id:" + cursor.getInt(cursor.getColumnIndex("id"))
val memo = cursor.getInt(cursor.getColumnIndex("memo"))
val values = ContentValues()
values.put("address", address)
values.put("type", type)
values.put("path", path)
values.put("memo", memo)
database.insert("Account_tmp", SQLiteDatabase.CONFLICT_FAIL, values)
}
}
}
database.execSQL("DROP TABLE IF EXISTS Account")
database.execSQL("ALTER TABLE Account_tmp RENAME TO Account")
database.setTransactionSuccessful()
} finally {
database.endTransaction()
}
}
private val MIGRATION_2_3: Migration = object : Migration(2, 3) {
override fun migrate(database: SupportSQLiteDatabase) {
database.beginTransaction()
try {
database.execSQL("""
CREATE TABLE Account_tmp (
address TEXT NOT NULL, type TEXT, path TEXT, memo TEXT, order TEXT,
PRIMARY KEY(address))""")
database.query("SELECT * FROM Account").use { cursor ->
if (cursor != null && cursor.count > 0) {
while (cursor.moveToNext()) {
val address = cursor.getString(cursor.getColumnIndex("address"))
val type = cursor.getString(cursor.getColumnIndex("type"))
val path = cursor.getString(cursor.getColumnIndex("path")) ************************ // getting error -> because table hasn't path column
val memo = cursor.getInt(cursor.getColumnIndex("memo"))
val values = ContentValues()
values.put("address", address)
values.put("type", type)
values.put("path", path)
values.put("memo", memo)
database.insert("Account_tmp", SQLiteDatabase.CONFLICT_FAIL, values)
}
}
}
database.execSQL("DROP TABLE IF EXISTS Account")
database.execSQL("ALTER TABLE Account_tmp RENAME TO Account")
database.setTransactionSuccessful()
} finally {
database.endTransaction()
}
}
当我尝试将 db 从 1 升级到 3 时,MIGRATION_2_3 中发生异常
而且我在调试的时候,查询结果很尴尬....
private val MIGRATION_1_2: Migration = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.beginTransaction()
try {
database.execSQL("""
CREATE TABLE Account_tmp (
address TEXT NOT NULL, type TEXT, path TEXT, memo TEXT,
PRIMARY KEY(address))""")
database.query("SELECT * FROM Account").use { cursor ->
if (cursor != null && cursor.count > 0) {
while (cursor.moveToNext()) {
val address = cursor.getString(cursor.getColumnIndex("address"))
val type = cursor.getString(cursor.getColumnIndex("type"))
val path = "Id:" + cursor.getInt(cursor.getColumnIndex("id"))
val memo = cursor.getInt(cursor.getColumnIndex("memo"))
val values = ContentValues()
values.put("address", address)
values.put("type", type)
values.put("path", path)
values.put("memo", memo)
database.insert("Account_tmp", SQLiteDatabase.CONFLICT_FAIL, values)
}
}
}
database.execSQL("DROP TABLE IF EXISTS Account")
database.execSQL("ALTER TABLE Account_tmp RENAME TO Account")
database.setTransactionSuccessful()
} finally {
database.endTransaction()
// database.query("SELECT * FROM Account") have {address, type, id, memo} (ver 1 schema) ****** -> why??
}
}
private val MIGRATION_2_3: Migration = object : Migration(2, 3) {
override fun migrate(database: SupportSQLiteDatabase) {
database.beginTransaction()
try {
database.execSQL("""
CREATE TABLE Account_tmp (
address TEXT NOT NULL, type TEXT, path TEXT, memo TEXT, order TEXT,
PRIMARY KEY(address))""")
database.query("SELECT * FROM Account").use { cursor ->
if (cursor != null && cursor.count > 0) {
while (cursor.moveToNext()) {
// cursor's column has {address, type, id, memo} (ver 1 schema), not (address, type, path, memo)(ver 2 schema) -> why??
val address = cursor.getString(cursor.getColumnIndex("address"))
val type = cursor.getString(cursor.getColumnIndex("type"))
val path = cursor.getString(cursor.getColumnIndex("path")) // exception because account table has not path.. still has id column
val memo = cursor.getInt(cursor.getColumnIndex("memo"))
val values = ContentValues()
values.put("address", address)
values.put("type", type)
values.put("path", path)
values.put("memo", memo)
database.insert("Account_tmp", SQLiteDatabase.CONFLICT_FAIL, values)
}
}
}
database.execSQL("DROP TABLE IF EXISTS Account")
database.execSQL("ALTER TABLE Account_tmp RENAME TO Account")
database.setTransactionSuccessful()
} finally {
database.endTransaction()
}
}
我不明白为什么 database.query("SELECT * FROM Account") 返回错误的数据库架构............
甚至,如果我在 rename to query 下面添加无意义的查询,那么我可以成功从 1 版本迁移到 3 版本
private val MIGRATION_1_2: Migration = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.beginTransaction()
try {
database.execSQL("""
CREATE TABLE Account_tmp (
address TEXT NOT NULL, type TEXT, path TEXT, memo TEXT,
PRIMARY KEY(address))""")
database.query("SELECT * FROM Account").use { cursor ->
if (cursor != null && cursor.count > 0) {
while (cursor.moveToNext()) {
val address = cursor.getString(cursor.getColumnIndex("address"))
val type = cursor.getString(cursor.getColumnIndex("type"))
val path = "Id:" + cursor.getInt(cursor.getColumnIndex("id"))
val memo = cursor.getInt(cursor.getColumnIndex("memo"))
val values = ContentValues()
values.put("address", address)
values.put("type", type)
values.put("path", path)
values.put("memo", memo)
database.insert("Account_tmp", SQLiteDatabase.CONFLICT_FAIL, values)
}
}
}
database.execSQL("DROP TABLE IF EXISTS Account")
database.execSQL("ALTER TABLE Account_tmp RENAME TO Account")
database.query("SELECT * FROM Account").use { cursor ->
Log.e(TAG, "MIGRATION_1_2, account size=${cursor.count}")
// If I add this code, Migration from 1 to 3 success!!!!
}
database.setTransactionSuccessful()
} finally {
database.endTransaction()
}
}
为什么??????????????????
我想知道为什么!!!!
请帮帮我
这是我的数据库代码
companion object {
private const val TAG = "TestDatabase"
@Volatile
private var instance: TestDatabase? = null
fun getInstance(context: Context): TestDatabase =
instance ?: synchronized(this) {
instance
?: buildDatabase(context).also { instance = it }
}
private fun buildDatabase(context: Context) =
Room.databaseBuilder(context, TestDatabase::class.java, "test_database.db")
.allowMainThreadQueries()
.addMigrations(MIGRATION_1_2)
.addMigrations(MIGRATION_2_3)
.build()
private val MIGRATION_1_2: Migration = object : Migration(1, 2) {
...
}
private val MIGRATION_2_3: Migration = object : Migration(2, 3) {
...
}
}
【问题讨论】:
标签: android database sqlite kotlin