gpt4 book ai didi

android - 房间 : How to automigrate DB for new table?

转载 作者:行者123 更新时间:2023-12-05 00:02:04 25 4
gpt4 key购买 nike

我想对我的房间数据库做一个简单的更改:添加一个新表。
我的房间版本是:2.4.1根据https://medium.com/androiddevelopers/room-auto-migrations-d5370b0ca6eb ,这个任务应该很容易使用自动迁移。
这是我的数据库类的相关部分在迁移之前的样子:

@Database(
entities = [FlashCard::class, Pool::class],
version = 2
)
abstract class DB : RoomDatabase() {
...
对于迁移,我将该部分更改为:
@Database(
entities = [FlashCard::class, Pool::class, FlashCardRunEvent::class],
version = 3,
autoMigrations = [
AutoMigration (from = 2, to = 3)
]
)
abstract class DB : RoomDatabase() {
...
这一切都编译得很好。应用程序一直运行到第一次与数据库交互。
然后,应用程序崩溃了,我在日志中得到了这个:
Caused by: java.lang.IllegalStateException: Migration didn't properly handle: FlashCardRunEvent(com.ravenala.flashy.room.FlashCardRunEvent).
Expected:
TableInfo{name='FlashCardRunEvent', columns={newBox=Column{name='newBox', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, flashCardId=Column{name='flashCardId', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, timeStampInSeconds=Column{name='timeStampInSeconds', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}, id=Column{name='id', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='null'}, oldBox=Column{name='oldBox', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
Found:
TableInfo{name='FlashCardRunEvent', columns={}, foreignKeys=[], indices=[]}
我不知道该怎么做。 “预期”和“发现”之间的差异是怎么回事。我曾希望房间能简单地看到新表,从中生成一个方案并创建表。像这次这样为简单迁移编写 SQL 语句的时代还没有结束吗?

最佳答案

What's up with that difference between "Expected" and "Found"


预期的是根据 Room 处理通过 @Database 注释中的实体参数定义的类的模式。
Found 是打开数据库时在数据库中找到的架构,在您的情况下是在自动迁移之后。
报告它找到了 TableInfo{name='FlashCardRunEvent', columns={}, foreignKeys=[], indices=[]}表示 FlasCardRunEvent 自动迁移后表不存在。

I had hoped room would simply see the new table, generate a scheme out of it and create the table. Are the times of writing SQL statements for simple migrations as this one not over?


为什么从您提供的代码中不明显。当然 AutoMigration 具有创建新表的能力(已经用一个简单的场景对此进行了测试)。

It all compiles fine.


您检查构建日志是否有任何警告?这些(如果有的话)可能是关于正在发生的事情的线索。

Why Room is not creating the table


一个猜测 :-
您没有因忘记某些东西(例如未将 FlashCardRunEvent 实体添加到 @Database 注释中的实体列表中定义的实体)运行而无意中绕过迁移,从而将版本提高到版本 3;然后纠正遗漏并在版本 3 时运行?
  • 也许尝试从 3-4 添加一个 AutoMigration 然后运行。

  • 否则我不确定。查看生成的 java(通过 Android View 可见),例如:-
    enter image description here
    这应该是这样的: -
    class AppDatabase_AutoMigration_2_3_Impl extends Migration {
    public AppDatabase_AutoMigration_2_3_Impl() {
    super(2, 3);
    }

    @Override
    public void migrate(@NonNull SupportSQLiteDatabase database) {
    database.execSQL("CREATE TABLE IF NOT EXISTS `FlashCardRunEvent` (`id` INTEGER, `newBox` INTEGER NOT NULL, `flashCardId` INTEGER NOT NULL, `timeStampInSeconds` INTEGER NOT NULL, `oldBox` INTEGER NOT NULL, PRIMARY KEY(`id`))");
    }
    }
  • 您只需要单个 execSQL,因为您只是添加单个表。

  • 此外,在生成的 java 中,您期望在 DB_Impl 的 createAllTables 方法类中还包含 FlashCardRunEvent 表的 CREATE TABLE。
    从上面可以看出,代码是从测试派生的,尽管它具有不同的初始表,但迁移 2-3 添加了 FlashCardRunEvent 表(通过从 预期 构建实体类),即:-
    @Entity
    data class FlashCardRunEvent(
    /*
    TableInfo{name='FlashCardRunEvent',
    columns={
    newBox=Column{name='newBox', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'},
    flashCardId=Column{name='flashCardId', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'},
    timeStampInSeconds=Column{name='timeStampInSeconds', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'},
    id=Column{name='id', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='null'},
    oldBox=Column{name='oldBox', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0, defaultValue='null'}},
    foreignKeys=[], indices=[]}
    */
    @PrimaryKey
    val id: Long?,
    val newBox: Long,
    val flashCardId: Long,
    val timeStampInSeconds: Long,
    val oldBox: Long
    )
    测试成功创建表。一个明显的区别是我编码了 exportSchema = true在@Database 注释中而不是依赖它默认为true。
    运行测试并创建 FlasCardRunEvent 表:-
    enter image description here

    关于android - 房间 : How to automigrate DB for new table?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71002284/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com