从SQLite迁移到会议室:迁移未正确处理表

时间:2019-10-21 11:28:09

标签: android database database-migration android-room

所以我当时使用SQLite数据库,现在我决定将其迁移到Room,而不进行更改。这就是我的房间模型

@Entity(tableName = "documents")
data class Document(
    @PrimaryKey(autoGenerate = true)
    val docID: Int,
    val path: String,
    val filename: String,
    val dateCreated: Long = MAX_VALUE,
)

这是我用来在房间之前创建表的查询:

"CREATE TABLE IF NOT EXISTS documents (docID INTEGER PRIMARY KEY ASC, path TEXT NOT NULL unique, filename TEXT NOT NULL, dateCreated LONG DEFAULT MAX_VALUE)"

此外,我创建了一个新的迁移到数据库的最终版本,该迁移使用的是房间,因为我不想更改表中的任何内容,所以将其留空。

private val MIGRATION_9_10: Migration = object : Migration(9, 10) {
    override fun migrate(database: SupportSQLiteDatabase) {

    }
}

因此,当我最终在具有数据库的先前版本(9)的设备上运行它时,会引发异常:

java.lang.IllegalStateException: Migration didn't properly handle: documents.
Expected: TableInfo{name='documents', columns={path=Column{name='path', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, filename=Column{name='filename', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, dataCreated=Column{name='dataCreated', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, docID=Column{name='docID', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}}, foreignKeys=[], indices=[]}

Found: TableInfo{name='documents', columns={path=Column{name='path', type='STRING', affinity='1', notNull=true, primaryKeyPosition=0, defaultValue='null'}, filename=Column{name='filename', type='STRING', affinity='1', notNull=true, primaryKeyPosition=0, defaultValue='null'}, dataCreated=Column{name='dataCreated', type='LONG', affinity='1', notNull=false, primaryKeyPosition=0, defaultValue='9223372036854775807'}, docID=Column{name='docID', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}}, foreignKeys=[], indices=[]}

路径和文件名字段的类型之间存在差异,应该是 TEXT ,但实际上是 STRING ,还有dateCreated的类型,即预期为 INTEGER ,但实际上为 LONG 。对我来说有趣的部分是dateCreated早于类型,现在仍然很久。我尝试添加一个迁移,如下所示:

private val MIGRATION_9_10: Migration = object : Migration(9, 10) {
    override fun migrate(database: SupportSQLiteDatabase) {
        val tableDocumentsTemp = "documents_temp"
        database.execSQL("ALTER TABLE documents RENAME TO $tableDocumentsTemp")
        database.execSQL("CREATE TABLE documents (docId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, path STRING NOT NULL, filename STRING NOT NULL, dateCreated LONG DEFAULT $MAX_VALUE)")
        database.execSQL("INSERT INTO documents (docId, path, filename, dateCreated) SELECT docId, path, filename, dateCreated FROM $tableDocumentsTemp")
        database.execSQL("DROP TABLE $tableDocumentsTemp")
        }
    }
}

但这没什么区别。

有人对我如何解决有任何想法吗?

1 个答案:

答案 0 :(得分:1)

编写会议室数据库迁移代码时,必须将TEXT用于字符串,将INTEGER用于长数据类型。

private val MIGRATION_9_10: Migration = object : Migration(9, 10) {
override fun migrate(database: SupportSQLiteDatabase) {
    val tableDocumentsTemp = "documents_temp"
    database.execSQL("CREATE TABLE $tableDocumentsTemp (docId INTEGER NOT NULL, path TEXT NOT NULL, filename TEXT NOT NULL, dateCreated INTEGER DEFAULT $MAX_VALUE NOT NULL, PRIMARY KEY(docId))")
    database.execSQL("INSERT INTO $tableDocumentsTemp (docId, path, filename, dateCreated) SELECT docId, path, filename, dateCreated FROM documents")
    database.execSQL("DROP TABLE documents")
    database.execSQL("ALTER TABLE $tableDocumentsTemp RENAME TO documents")
    }
 }
}