[英]Room exception on table: Pre-packaged database has an invalid schema
我的任務是將我們應用程序的當前架構(使用 Cupboard)遷移到 Room,我在第一項工作中遇到了一些問題,即遷移數據庫對象,目前用 Java 編寫(Cupboard 僅支持 Java),讓他們與 Room 一起工作。 這是一個例子:
public class ItemDb {
public Long _id;
public String type;
public String subtype;
public long scheduledTime;
public int iteration;
public String data1;
public String data2;
public String data3;
這就是它在數據庫中的樣子:
我對這個實體所做的是在 Kotlin 中創建一個@Entity
class 以在 Room 中使用,它看起來像這樣:
@Entity(tableName = "ItemDb")
data class ItemDb(
@PrimaryKey(autoGenerate = true)
val _id: Long? = 0,
val type: String,
val subtype: String,
val scheduledTime: Long,
val iteration: Int,
val data1: String? = null,
val data2: String? = null,
val data3: String? = null
)
每當我嘗試查詢數據庫時,都會出現此異常:
預打包數據庫的架構無效:ItemDb(com.example.room.model.items.ItemDb)。 預期:TableInfo{name='ItemDb',columns={scheduledTime=Column{name='scheduledTime',type='INTEGER',affinity='3',notNull=true,primaryKeyPosition=0,defaultValue='null'}, subtype=Column{name='subtype', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, data3=Column{name='data3', type=' TEXT',affinity='2',notNull=false,primaryKeyPosition=0,defaultValue='null'},data2=Column{name='data2',type='TEXT',affinity='2',notNull=false, primaryKeyPosition=0,defaultValue='null'},data1=Column{name='data1',type='TEXT',affinity='2',notNull=false,primaryKeyPosition=0,defaultValue='null'},迭代=列{name='iteration',type='INTEGER',affinity='3',notNull=true,primaryKeyPosition=0,defaultValue='null'},_id=Column{name='_id',type='INTEGER' ,affinity='3',notNull=false,primaryKeyPosition=1,defaultValue='null'},type=Column{name='type',type='TEXT',affinity='2',notNull=true,primaryKeyPosition= 0, defaultValue='null'}}, foreignKeys=[], indices= []} 找到:TableInfo{name='ItemDb',columns={scheduledTime=Column{name='scheduledTime',type='INTEGER',affinity='3',notNull=false,primaryKeyPosition=0,defaultValue='null '}, subtype=Column{name='subtype', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, data3=Column{name='data3', type='TEXT',affinity='2',notNull=false,primaryKeyPosition=0,defaultValue='null'},data2=Column{name='data2',type='TEXT',affinity='2',notNull =false,primaryKeyPosition=0,defaultValue='null'},data1=Column{name='data1',type='TEXT',affinity='2',notNull=false,primaryKeyPosition=0,defaultValue='null'} , 迭代=Column{name='iteration', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, _id=Column{name='_id', type= 'integer',affinity='3',notNull=false,primaryKeyPosition=1,defaultValue='null'},type=Column{name='type',type='TEXT',affinity='2',notNull=false , primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], ind 冰=[]}
通過比較兩者,我可以看到一些字段預計將被標記為notNull
但它們似乎被標記為可為nullable
,即使Kotlin notNull
通過避免使用可為空的?
.
我究竟做錯了什么? 如果您需要有關數據庫架構的更多信息,我可以輕松地提供它們。 謝謝!
在錯誤消息中,“預期”架構是 Room 從您的 Kotlin 聲明中創建的ItemDb
。 它正確地將type
、 subType
、 scheduledTime
和iteration
顯示為非空列,所有其他列都可以為空。
我沒有使用過 Cupboard,並且假設它會根據您的ItemDb
Java 聲明創建一個數據庫。 “找到”模式報告預打包的 Cupboard 數據庫的模式,表明當 Cupboard 創建數據庫時,所有列都被聲明為可為空(即沒有 NOT NULL)。
要使用預打包的數據庫,您需要執行遷移步驟,該步驟將創建一個新表,其中為適用字段指定了NOT NULL
。 然后,您需要將預打包數據庫中 ItemDb 表中的所有行復制到新表中,並重新命名一些表(參見下面的示例)。
新表的創建語句將如下所示:
CREATE TABLE new_ItemDb (_id INTEGER PRIMARY KEY AUTOINCREMENT,
type INTEGER NOT NULL, subType INTEGER NOT NULL, scheduledTime INTEGER NOT NULL,
iteration INTEGER NOT NULL, data1 TEXT, data2 TEXT, data3 TEXT)
遷移操作可以根據從遷移文檔復制的示例進行建模:
// Migration from 2 to 3, Room 2.2.0
val MIGRATION_2_3 = object : Migration(2, 3) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("""
CREATE TABLE new_Song (
id INTEGER PRIMARY KEY NOT NULL,
name TEXT,
tag TEXT NOT NULL DEFAULT ''
)
""".trimIndent())
database.execSQL("""
INSERT INTO new_Song (id, name, tag)
SELECT id, name, tag FROM Song
""".trimIndent())
database.execSQL("DROP TABLE Song")
database.execSQL("ALTER TABLE new_Song RENAME TO Song")
}
}
在花時間進行上述代碼更改之前,您可以通過臨時更改 ItemDb 的ItemDb
定義以使所有字段可為空來確認我的分析,然后重試使用預打包的數據庫。 我希望導入成功。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.