繁体   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