[英]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.