简体   繁体   English

桌子上的房间异常:预打包的数据库具有无效的架构

[英]Room exception on table: Pre-packaged database has an invalid schema

my task is to migrate the current architecture of our app (using Cupboard) to Room and I am encountering some issues on the very first piece of work, which is migrating the database objects, written in Java for now (Cupboard only supports Java), to make them work with Room.我的任务是将我们应用程序的当前架构(使用 Cupboard)迁移到 Room,我在第一项工作中遇到了一些问题,即迁移数据库对象,目前用 Java 编写(Cupboard 仅支持 Java),让他们与 Room 一起工作。 This is an example:这是一个例子:

public class ItemDb {

public Long _id;
public String type;
public String subtype;
public long scheduledTime;
public int iteration;
public String data1;
public String data2;
public String data3;

and this is how it looks like in the database:这就是它在数据库中的样子:

在此处输入图像描述

What I've done with this entity is creating an @Entity class in Kotlin to be used in Room and it looks like this:我对这个实体所做的是在 Kotlin 中创建一个@Entity class 以在 Room 中使用,它看起来像这样:

@Entity(tableName = "ItemDb")
data class ItemDb(
        @PrimaryKey(autoGenerate = true)
        val _id: Long? = 0,
        val type: String,
        val subtype: String,
        val scheduledTime: Long,
        val iteration: Int,
        val data1: String? = null,
        val data2: String? = null,
        val data3: String? = null
)

Whenever I try to query the database I get this exception:每当我尝试查询数据库时,都会出现此异常:

Pre-packaged database has an invalid schema: ItemDb(com.example.room.model.items.ItemDb).预打包数据库的架构无效:ItemDb(com.example.room.model.items.ItemDb)。 Expected: TableInfo{name='ItemDb', columns={scheduledTime=Column{name='scheduledTime', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, subtype=Column{name='subtype', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, data3=Column{name='data3', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, data2=Column{name='data2', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, data1=Column{name='data1', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, iteration=Column{name='iteration', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, _id=Column{name='_id', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='null'}, type=Column{name='type', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=预期:TableInfo{name='ItemDb',columns={scheduledTime=Column{name='scheduledTime',type='INTEGER',affinity='3',notNull=true,primaryKeyPosition=0,defaultValue='null'}, subtype=Column{name='subtype', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=0, defaultValue='null'}, data3=Column{name='data3', type=' TEXT',affinity='2',notNull=false,primaryKeyPosition=0,defaultValue='null'},data2=Column{name='data2',type='TEXT',affinity='2',notNull=false, primaryKeyPosition=0,defaultValue='null'},data1=Column{name='data1',type='TEXT',affinity='2',notNull=false,primaryKeyPosition=0,defaultValue='null'},迭代=列{name='iteration',type='INTEGER',affinity='3',notNull=true,primaryKeyPosition=0,defaultValue='null'},_id=Column{name='_id',type='INTEGER' ,affinity='3',notNull=false,primaryKeyPosition=1,defaultValue='null'},type=Column{name='type',type='TEXT',affinity='2',notNull=true,primaryKeyPosition= 0, defaultValue='null'}}, foreignKeys=[], indices= []} Found: TableInfo{name='ItemDb', columns={scheduledTime=Column{name='scheduledTime', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, subtype=Column{name='subtype', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, data3=Column{name='data3', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, data2=Column{name='data2', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, data1=Column{name='data1', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, iteration=Column{name='iteration', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, _id=Column{name='_id', type='integer', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='null'}, type=Column{name='type', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], ind []} 找到:TableInfo{name='ItemDb',columns={scheduledTime=Column{name='scheduledTime',type='INTEGER',affinity='3',notNull=false,primaryKeyPosition=0,defaultValue='null '}, subtype=Column{name='subtype', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, data3=Column{name='data3', type='TEXT',affinity='2',notNull=false,primaryKeyPosition=0,defaultValue='null'},data2=Column{name='data2',type='TEXT',affinity='2',notNull =false,primaryKeyPosition=0,defaultValue='null'},data1=Column{name='data1',type='TEXT',affinity='2',notNull=false,primaryKeyPosition=0,defaultValue='null'} , 迭代=Column{name='iteration', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, _id=Column{name='_id', type= 'integer',affinity='3',notNull=false,primaryKeyPosition=1,defaultValue='null'},type=Column{name='type',type='TEXT',affinity='2',notNull=false , primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], ind ices=[]}冰=[]}

By comparing the twos I can see that some fields are expected to be marked notNull but they seem to be marked nullable instead even though the Kotlin class is declaring the fields as notNull by avoid using the nullable ?通过比较两者,我可以看到一些字段预计将被标记为notNull但它们似乎被标记为可为nullable即使Kotlin notNull通过避免使用可为空的? . .

What am I doing wrong?我究竟做错了什么? If you need more information regarding the architecture of the Database I can provide them easily.如果您需要有关数据库架构的更多信息,我可以轻松地提供它们。 Thanks!谢谢!

In the error message, the "expected" schema is what Room created from your Kotlin declaration of ItemDb .在错误消息中,“预期”架构是 Room 从您的 Kotlin 声明中创建的ItemDb It correctly shows type , subType , scheduledTime and iteration as non-null columns, with all others nullable.它正确地将typesubTypescheduledTimeiteration显示为非空列,所有其他列都可以为空。

I've not used Cupboard and am presuming it creates a database from your ItemDb Java declaration.我没有使用过 Cupboard,并且假设它会根据您的ItemDb Java 声明创建一个数据库。 The "found" schema, which reports the schema for the prepackaged Cupboard database, indicates that when Cupboard created the database, all columns were declared nullable (ie without NOT NULL). “找到”模式报告预打包的 Cupboard 数据库的模式,表明当 Cupboard 创建数据库时,所有列都被声明为可为空(即没有 NOT NULL)。

To use the prepackaged database, you will need to perform a migration step that will create a new table with NOT NULL specified for the applicable fields.要使用预打包的数据库,您需要执行迁移步骤,该步骤将创建一个新表,其中为适用字段指定了NOT NULL You then need to copy all the rows from the ItemDb table in the prepackaged database to the new table, with some table re-names (see example below).然后,您需要将预打包数据库中 ItemDb 表中的所有行复制到新表中,并重新命名一些表(参见下面的示例)。

The create-statement for the new table will be something like this:新表的创建语句将如下所示:

CREATE TABLE new_ItemDb (_id INTEGER PRIMARY KEY AUTOINCREMENT,
    type INTEGER NOT NULL, subType INTEGER NOT NULL, scheduledTime INTEGER NOT NULL,
    iteration INTEGER NOT NULL, data1 TEXT, data2 TEXT, data3 TEXT)

The migration operations can be modeled after this example copied from the documentation for migrations :迁移操作可以根据从迁移文档复制的示例进行建模:

// Migration from 2 to 3, Room 2.2.0
val MIGRATION_2_3 = object : Migration(2, 3) {
    override fun migrate(database: SupportSQLiteDatabase) {
        database.execSQL("""
                CREATE TABLE new_Song (
                    id INTEGER PRIMARY KEY NOT NULL,
                    name TEXT,
                    tag TEXT NOT NULL DEFAULT ''
                )
                """.trimIndent())
        database.execSQL("""
                INSERT INTO new_Song (id, name, tag)
                SELECT id, name, tag FROM Song
                """.trimIndent())
        database.execSQL("DROP TABLE Song")
        database.execSQL("ALTER TABLE new_Song RENAME TO Song")
    }
}

Before investing the time making the code changes described above, you could confirm my analysis by temporarily changing your Kotlin definition of ItemDb to make all fields nullable, then retrying your use of the prepackaged database.在花时间进行上述代码更改之前,您可以通过临时更改 ItemDb 的ItemDb定义以使所有字段可为空来确认我的分析,然后重试使用预打包的数据库。 I would expect the import to succeed.我希望导入成功。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Room 数据库预打包数据库的架构无效 - Room database Pre-packaged database has an invalid schema Android Room 预打包数据库存在无效架构错误 - Android Room Pre-packaged database has an invalid schema error Room 报错:预打包的数据库对 FTS 表的架构无效 - Room gives error: pre-packaged database has an invalid schema for FTS Table 例外:预先打包的数据库具有无效的架构 - Exception: Pre-packaged database has an invalid schema Android Room 给出错误“预打包的数据库具有无效的架构”但导出的架构是正确的 - Android Room giving error "Pre-packaged database has an invalid schema" but exported schema is correct 房间数据库迁移失败,预打包数据库的架构无效 - Room Database Migration fails with Pre-packaged database has an invalid schema 在 Room 中实现一对多时,预打包数据库有一个无效的模式错误 - Pre-packaged database has an invalid schema Error, when implementing one-to-many in Room 预填充我的房间时,预打包的数据库的架构无效 - Pre-packaged database has an invalid schema when prepopulating my room 预打包的数据库存在无效架构错误 - Pre-packaged database has an invalid schema error 预打包的数据库有一个无效的模式,顺序混淆 - Pre-packaged database has an invalid schema, order mixed up
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM