Android Studio 预打包数据库在Room AndroidKotlin中具有无效架构

gfttwv5a  于 11个月前  发布在  Android
关注(0)|答案(2)|浏览(157)

我试图从资产文件夹SQL DB中获取数据,但出现以下错误:

java.lang.IllegalStateException: Pre-packaged database has an invalid schema: recipetype(com.example.finddishrecipe.room.RecipeEntity).
Expected:
TableInfo{name='recipetype', columns={name=Column{name='name', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='undefined'}, image=Column{name='image', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='undefined'}, id=Column{name='id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='undefined'}}, foreignKeys=[], indices=[]}
Found:
TableInfo{name='recipetype', columns={id=Column{name='id', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='undefined'}, name=Column{name='name', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='undefined'}, image=Column{name='image', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='undefined'}}, foreignKeys=[], indices=[]}

字符串
这是我的实体代码:

@Entity(tableName = "recipetype")

data class RecipeEntity(
    @PrimaryKey

    @ColumnInfo(name = "id")
    val id: Int,

    @ColumnInfo(name = "name")
    val name: String,

    @ColumnInfo(name = "image")
    val image: String
)

niknxzdl

niknxzdl1#

根据预期的模式,所有列都应该具有非空约束。在创建表时通过添加NOT NULL约束将它们定义为非空值,如下所示:

CREATE TABLE "recipetype" ( "id" INTEGER NOT NULL, "name" TEXT NOT NULL, "image" TEXT NOT NULL, PRIMARY KEY("id" AUTOINCREMENT) )

字符串
也可以将实体类列设置为空值。
列的顺序不重要。

jei2mxaa

jei2mxaa2#

确保预打包的数据库与Room期望的数据库匹配的最简单方法是:
1.创建@Entity注解类,然后
1.将@Database注解的类(抽象)与@Database注解的entities参数中定义的@Entity注解的类(es)一起添加,然后
1.成功编译项目(CTRL +F9)。
1.使用Android View定位java(生成)文件夹,然后
1.找到与@Database注解类同名但后缀为Impl的类,然后
1.找到RightAllTables方法,然后为每个表(@Entity注解类)
1.复制Room为表生成的SQL,以便在您正在使用的SQLite工具中创建表。
1.此SQL是EXACTLYRoom期望的,因此无需尝试预测Room的底层规则。

  • 注意忽略room_master表,Room将处理它的创建
  • 如果需要,也可以相应地创建其他组件,例如视图和索引。

如果你有一个相对接近的现有数据库,那么你可以使用SQLite工具来转换定义,沿着行:
1.ALTER现有表以RENAME它。
1.CREATE使用生成的java中的SQL创建实际的表。
1.使用重命名的原始表将数据加载到新创建的实际表中(通常这可以像INSERT INTO actual_table SELECT * FROM renamed_existing_table一样简单,显然相应地命名表名)
1.可选地DROP重命名的表
1.可选地VACUUM数据库(释放未使用的页面)
或者,您可以使用PrePackagedDatabase回调的overidden onOpen方法来转换数据库,方法与复制资产时转换表的方法类似。

  • 与此答案类似使用压缩的预填充数据库,

相关问题