簡體   English   中英

房間沒有更新數據庫的架構

[英]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?
)

無論我要做什么, idformformNoAccentformUtf8General都沒有設置為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?
)
  • 注意我沒有嘗試以上
  • 您可能需要進行其他更改以適應,請特別注意id列,因為 id 不會像預期的那樣生成。
  • 我個人不建議嘗試將實體(預期)與現有表(發現)匹配。 所以我建議考慮以下因素來調整預打包的數據庫以適應實體:-

如果您在預打包的數據庫中有大量數據,那么您可以使用 SQL 來(如果您沒有數據或數據很少,則只需刪除詞位表並按照步驟 2 創建):-

  1. 重命名詞位表,例如

    ALTER TABLE lexeme RENAME TO lexeme_old;

  2. 使用 SQL 為從生成的 java 復制的詞位表創建詞位。

  3. 將數據從 lexeme_old 表復制到 lexeme 表,例如

    INSERT INTO lexeme (SELECT * FROM lexeme_old);

  4. 使用DROP TABLE IF EXISTS lexeme_old lexeme_old 表

  5. 可選擇使用 SQL VACUUM;

  6. 關閉數據庫,退出工具,啟動工具,打開/連接數據庫檢查更改是否已應用,關閉數據庫然后將預打包的數據庫復制到應用程序。

  • 請注意,由於 id 列是 TEXT,因此如果任何值不是有效的整數,那么您將收到 SQLITE_MISMATCH 錯誤。

如果您確實獲得了 SQLITE_MISMATCH,那么您可以執行以下操作之一:-

  1. 將 id 列從val id: Long更改為val id: String並刪除行@ColumnInfo(typeAffinity = ColumnInfo.INTEGER)
  2. 將步驟 3 中使用的 SQL 更改為

:-

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;
  • 請注意 SQL 尚未檢查,將其視為原則上的。

上述步驟可以在您使用/確實用於創建預打包數據庫的任何工具中進行。

另一種選擇是使用prePackagedDarabaseCallback即時進行更改。 這是一個使用回調的示例,它實際上執行上述步驟,只需進行一些更改。 但是,它是用 java 編寫的,並且還需要至少 Room 版本 2.4.0-beta02(建議使用 2.4.0,因為它現在已經發布)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM