Room refuses loading in ANY data from the pre-packaged database, even if it was created using it's own autogenerated queries

huangapple go评论58阅读模式
英文:

Room refuses loading in ANY data from the pre-packaged database, even if it was created using it's own autogenerated queries

问题

过去4小时里,我一直在努力加载我的预打包数据库,我看了一些帖子,告诉我尝试找到_Impl.java文件,检查那里生成的模式,所以我做了,把我的数据库移到那个模式中,运行SQL查询来加载数据到那个数据库中,再次导入它,然后...再次出现了相同的弹出消息(另外,为什么是弹出消息而不是日志?),为了重现示例,我尝试仅加载一个数据库实体,但什么也没有改变,我没有任何想法了

创建项目的示例查询:

INSERT INTO products (title, image, price, description, category, rating, numberOfRatings) VALUES ("Retro Cat-Eye Sunglasses", "https://uploads-ssl.webflow.com/5b105a0c66f2f636c7884a17/64063dbcad97bd421b437096_chatgpt.jpg", 29.95, "Retro-inspired cat-eye sunglasses for a vintage look.", "Accessories", 4.4, 148);

数据库表创建查询(由Room生成):

CREATE TABLE IF NOT EXISTS `products` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `price` REAL NOT NULL, `description` TEXT NOT NULL, `image` TEXT NOT NULL, `category` TEXT NOT NULL, `rating` REAL NOT NULL, `numberOfRatings` INTEGER NOT NULL, PRIMARY KEY(`id`))

我使用的实体:

@Entity(tableName = "products")
data class ProductEntity(
    @PrimaryKey val id: Int,
    val title: String,
    val price: Double,
    val description: String,
    val image: String,
    val category: String,
    val rating: Double,
    val numberOfRatings: Int
)

我遵循了文档,所以我确定Room能够找到正确的资产(请参见图片)

任何想法都将不胜感激,因为我的理智已经消失了。

英文:

For the past 4 hours I've been fighting with room to load in my pre-packaged database, I've read some posts that told me to try finding the _Impl.java file, and check the schema generated there, so I did, and moved my database into that schema, ran SQL queries to load in the data into that DB, imported it again and... Room refuses loading in ANY data from the pre-packaged database, even if it was created using it's own autogenerated queries
got hit again with the same toast message (also, why a toast and not just a log?), for reproductive examples I've tried loading in only one db entity, but that changed nothing and I've got no ideas left

Example query for creating an item:

INSERT INTO products (title, image, price, description, category, rating, numberOfRatings) VALUES ("Retro Cat-Eye Sunglasses", "https://uploads-ssl.webflow.com/5b105a0c66f2f636c7884a17/64063dbcad97bd421b437096_chatgpt.jpg", 29.95, "Retro-inspired cat-eye sunglasses for a vintage look.", "Accessories", 4.4, 148);

the database table creation query (generated by room):

CREATE TABLE IF NOT EXISTS `products` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `price` REAL NOT NULL, `description` TEXT NOT NULL, `image` TEXT NOT NULL, `category` TEXT NOT NULL, `rating` REAL NOT NULL, `numberOfRatings` INTEGER NOT NULL, PRIMARY KEY(`id`))

the entity I've used:

@Entity(tableName = "products")
data class ProductEntity(
    @PrimaryKey val id: Int,
    val title: String,
    val price: Double,
    val description: String,
    val image: String,
    val category: String,
    val rating: Double,
    val numberOfRatings: Int
)

I followed the documentation, so I'm sure the room is able to find the correct asset (see image)

Any ideas will be appreciated, 'cause my sanity is gone

答案1

得分: 0

  1. 找到YourDatabaseName_Impl文件(通常在你看到相同错误时生成,尝试按两次Shift键并搜索实体类中的字段名称)
  2. 找到文件中的createAllTables函数,并复制包含你的表名的SQL查询(通常是第一个)
    3)(编辑:在这一步之前,可能值得清除模拟器数据)
    现在打开创建DB的地方(在我的情况下是一个Hilt模块)
    添加类似以下内容:
val rdc = object : RoomDatabase.Callback() {
    override fun onCreate(db: SupportSQLiteDatabase) {
        val SQL_CREATE_TABLE = "在此粘贴刚刚复制的查询"
        db.execSQL(SQL_CREATE_TABLE)
        val contentValues = ContentValues()
        // 这里我们手动创建了一个实体,你的表结构肯定不同,所以请更改这部分!
        contentValues.put("id", 0)
        contentValues.put("price", 12.99)
        contentValues.put("title", "yes")
        contentValues.put("description", "no")
        contentValues.put("image", "maybe.jpg")
        contentValues.put("category", "nonbin")
        contentValues.put("rating", 12.5)
        contentValues.put("numberOfRatings", 101)
        db.insert("YOUR TABLE NAME", OnConflictStrategy.REPLACE, contentValues)
    }
}

在顶部添加

然后只需将.addCallback(rdc)添加到数据库构建器,如下所示:

Room.databaseBuilder(appContext, YourDatabaseNameHere::class.java, "YourDatabaseNameHereButSlightlyDifferentForRoomReasons.db")
                .addCallback(rdc)
                .build()

这将(希望能够)创建数据库和表,并向表中添加一个项目

(在此测试应用程序)

如果一切正常:
在Android Studio中找到设备浏览器工具
选择正确的模拟器(在顶部)
然后导航到:data -> data -> (在这里搜索你的包名称,或者一个具有匹配名称的应用程序名称) -> databases
Room refuses loading in ANY data from the pre-packaged database, even if it was created using it's own autogenerated queries

然后右键单击.db文件,点击“另存为”,将其保存到某个地方

然后你将拥有一个带有正确模式和示例项目的工作数据库,现在你应该能够将其他项目插入到表中(通常通过查询完成),之后你可以取出数据库文件,将其移动到assets文件夹(在我的情况下是assets文件夹内的一个名为database的文件夹)
并执行:

Room.databaseBuilder(appContext, YourDatabaseName::class.java, "YourDatabaseNameHereButSlightlyDifferentForRoomReasons.db")
//                .addCallback(rdc)
                .createFromAsset("database/YourDatabaseName.db")
                .build()

但在此之前:清除设备上的数据(只是为了确保)

然后... 应该能够正常工作。希望如此。

英文:

Ok I made it work... here's how:

  1. find the YourDatabaseName_Impl file (it usually is generated IF you see the same error, try pressing shift twice and searching for a field name from your Entity class)
  2. find the createAllTables function in the file and copy the SQL query that contains your table name (usually the first one)
  3. (edit: It may be worth to wipe the emulator data before this step)
    now open the place where your DB is created (in my case: a hilt module)
    add something like:
val rdc = object : RoomDatabase.Callback() {
    override fun onCreate(db: SupportSQLiteDatabase) {
        val SQL_CREATE_TABLE = "PASTE HERE THE QUERY YOU JUST COPIED"
        db.execSQL(SQL_CREATE_TABLE)
        val contentValues = ContentValues()
        // here we are manually created an entity, your table schema is definitevely different, so change this!
        contentValues.put("id", 0)
        contentValues.put("price", 12.99)
        contentValues.put("title", "yes")
        contentValues.put("description", "no")
        contentValues.put("image", "maybe.jpg")
        contentValues.put("category", "nonbin")
        contentValues.put("rating", 12.5)
        contentValues.put("numberOfRatings", 101)
        db.insert("YOUR TABLE NAME", OnConflictStrategy.REPLACE, contentValues)
    }
}

at the top

Then just add .addCallback(rdc) to the database builder, like so:

Room.databaseBuilder(appContext, YourDatabaseNameHere::class.java, "YourDatabaseNameHereButSlightlyDifferentForRoomReasons.db")
                .addCallback(rdc)
                .build()

This will (hopefully) create the db and the table + add ONE item to the table

(Test the app here)

if it all worked:
find the device explorer tool in android studio
select the correct emulator (on top)
and then navigate to: data -> data -> (search here for your package name, or an app name for a dir with the matching name) -> databases
Room refuses loading in ANY data from the pre-packaged database, even if it was created using it's own autogenerated queries

then right click on the .db file and press "save as" and save it somewhere

and you will have a working db, with a table that has the correct schema and an example item, now you should be able to insert other items into the table (usually done by queries) and after that you can take the db file, move it into the assets (in my case it's a folder inside assets named database)
and do:

Room.databaseBuilder(appContext, YourDatabaseName::class.java, "YourDatabaseNameHereButSlightlyDifferentForRoomReasons.db")
//                .addCallback(rdc)
                .createFromAsset("database/YourDatabaseName.db")
                .build()

but before: wipe the data off the device (just to be sure)

and it... should work. hopefully.

huangapple
  • 本文由 发表于 2023年7月28日 04:37:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76783264.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定