[英]Room is not updating schema of the database
我有下表:
@JsonClass(generateAdapter = true)
@Entity(tableName = "lexeme")
data class Lexeme(
@PrimaryKey
@ColumnInfo(typeAffinity = ColumnInfo.INTEGER)
val id: Long,
val form: String,
val formNoAccent: String,
val formUtf8General: String,
val reverse: String,
val number: Int?,
val description: String?,
val noAccent: String?,
val consistentAccent: String?,
val frequency: String?,
val hyphenations: String?,
val pronunciations: String?,
val stopWord: String?,
val compound: String?,
val modelType: String?,
val modelNumber: String?,
val restriction: String?,
val staleParadigm: String?,
val notes: String?,
val hasApheresis: String?,
val hasApocope: String?,
val createDate: String?,
val modDate: String?
)
無論我要做什么, id
、 form
、 formNoAccent
和formUtf8General
都沒有設置為Not Null
並且id
沒有設置為affinity = 3
,我已經嘗試過 Int 和 Long。
我正在嘗試將數據庫預加載到我的應用程序中,但出現以下錯誤:
Expected:
TableInfo{name='lexeme', columns={hyphenations=Column{name='hyphenations', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, staleParadigm=Column{name='staleParadigm', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, modDate=Column{name='modDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, notes=Column{name='notes', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, hasApheresis=Column{name='hasApheresis', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, description=Column{name='description', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, consistentAccent=Column{name='consistentAccent', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, formNoAccent=Column{name='formNoAccent', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, noAccent=Column{name='noAccent', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, modelType=Column{name='modelType', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, reverse=Column{name='reverse', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, compound=Column{name='compound', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, hasApocope=Column{name='hasApocope', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, frequency=Column{name='frequency', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, number=Column{name='number', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, formUtf8General=Column{name='formUtf8General', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, form=Column{name='form', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, restriction=Column{name='restriction', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, modelNumber=Column{name='modelNumber', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, id=Column{name='id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}, stopWord=Column{name='stopWord', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, pronunciations=Column{name='pronunciations', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, createDate=Column{name='createDate', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
Found:
TableInfo{name='lexeme', columns={hyphenations=Column{name='hyphenations', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, staleParadigm=Column{name='staleParadigm', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, modDate=Column{name='modDate', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, notes=Column{name='notes', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, hasApheresis=Column{name='hasApheresis', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, description=Column{name='description', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, consistentAccent=Column{name='consistentAccent', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, formNoAccent=Column{name='formNoAccent', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, noAccent=Column{name='noAccent', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, modelType=Column{name='modelType', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, reverse=Column{name='reverse', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, compound=Column{name='compound', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, hasApocope=Column{name='hasApocope', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, frequency=Column{name='frequency', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, number=Column{name='number', type='integer', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, formUtf8General=Column{name='formUtf8General', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, form=Column{name='form', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, restriction=Column{name='restriction', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, modelNumber=Column{name='modelNumber', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, id=Column{name='id', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, stopWord=Column{name='stopWord', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, pronunciations=Column{name='pronunciations', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, createDate=Column{name='createDate', type='text', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
確保找到預期匹配的最簡單方法是使用 Room 生成的 SQL 在您用於創建預打包數據庫的工具中創建表。
SQL 可以通過在創建所有實體后編譯項目並將它們添加到使用@Database 注釋的 class 中的實體列表中來找到。
編譯后查看 java(生成)並找到與帶有 @Database 后綴的class 同名的 class 名稱。 在 class 內部將有一個名為createAllTables的方法,該方法具有 SQL 用於所有表、視圖、索引,對於 FTS 表,它具有房間期望的觸發器。
使固定
您必須確保預打包數據庫中的表(找到的)與 SQL 中的表匹配(預期的)。
假設您已經發現了所有差異,那么您可以嘗試將 Lexeme class 更改為:-
@JsonClass(generateAdapter = true)
@Entity(tableName = "lexeme")
data class Lexeme(
@PrimaryKey
//@ColumnInfo(typeAffinity = ColumnInfo.INTEGER) //<<<<< effectively removed
val id: String, //<<<<< changed to be TEXT
val form: String,
val formNoAccent: String?, //<<<<< changes to be NOT NULL
val formUtf8General: String?, //<<<<< changes to be NOT NULL
val reverse: String,
val number: Int?,
val description: String?,
val noAccent: String?,
val consistentAccent: String?,
val frequency: String?,
val hyphenations: String?,
val pronunciations: String?,
val stopWord: String?,
val compound: String?,
val modelType: String?,
val modelNumber: String?,
val restriction: String?,
val staleParadigm: String?,
val notes: String?,
val hasApheresis: String?,
val hasApocope: String?,
val createDate: String?,
val modDate: String?
)
如果您在預打包的數據庫中有大量數據,那么您可以使用 SQL 來(如果您沒有數據或數據很少,則只需刪除詞位表並按照步驟 2 創建):-
重命名詞位表,例如
ALTER TABLE lexeme RENAME TO lexeme_old;
使用 SQL 為從生成的 java 復制的詞位表創建詞位。
將數據從 lexeme_old 表復制到 lexeme 表,例如
INSERT INTO lexeme (SELECT * FROM lexeme_old);
使用DROP TABLE IF EXISTS lexeme_old
lexeme_old 表
可選擇使用 SQL VACUUM;
關閉數據庫,退出工具,啟動工具,打開/連接數據庫檢查更改是否已應用,關閉數據庫然后將預打包的數據庫復制到應用程序。
如果您確實獲得了 SQLITE_MISMATCH,那么您可以執行以下操作之一:-
val id: Long
更改為val id: String
並刪除行@ColumnInfo(typeAffinity = ColumnInfo.INTEGER)
。:-
INSERT INTO lexeme (`form`,`formNoAccent`,`formUtf8General`,`reverse`,`number`,`description`,`noAccent`,`consistentAccent`,`frequency`,`hyphenations`,`pronunciations`,`stopWord`,`compound`,`modelType`,`modelNumber`,`restriction`,`staleParadigm`,`notes`,`hasApheresis`,`hasApocope`.`createDate`,`modDate`) SELECT `form`,`formNoAccent`,`formUtf8General`,`reverse`,`number`,`description`,`noAccent`,`consistentAccent`,`frequency`,`hyphenations`,`pronunciations`,`stopWord`,`compound`,`modelType`,`modelNumber`,`restriction`,`staleParadigm`,`notes`,`hasApheresis`,`hasApocope`.`createDate`,`modDate` FROM lexeme_old;
上述步驟可以在您使用/確實用於創建預打包數據庫的任何工具中進行。
另一種選擇是使用prePackagedDarabaseCallback
即時進行更改。 這是一個使用回調的示例,它實際上執行上述步驟,只需進行一些更改。 但是,它是用 java 編寫的,並且還需要至少 Room 版本 2.4.0-beta02(建議使用 2.4.0,因為它現在已經發布)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.