You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Room数据库预填充问题:预设SQL查询未执行

解决Room数据库预填充问题

问题根源

  1. 文件类型错误:你把纯文本SQL脚本直接命名为attributes.db,但createFromAsset要求传入的是已初始化完成的SQLite数据库文件,并非SQL语句文本。
  2. 表名不匹配:创建表的目标是attributes,但插入语句指向attributes_in_detail,两者名称不一致。
  3. SQL语法错误:字符串值用了反引号`,SQL中字符串常量必须用单引号'包裹。

正确实现方案

方案一:使用预创建的SQLite数据库文件(推荐)

  1. 创建并初始化SQLite数据库
    • 用SQLiteStudio、DB Browser for SQLite等工具新建一个attributes.db文件。
    • 在工具中执行修正后的SQL:
      CREATE TABLE IF NOT EXISTS `attributes` (
          `id` INTEGER PRIMARY KEY AUTOINCREMENT,
          `key` TEXT NOT NULL,
          `value` TEXT NOT NULL,
          `meta_data` TEXT DEFAULT '',
          `isActive` INTEGER NOT NULL
      );
      
      INSERT INTO `attributes` (`key`, `value`, `isActive`) VALUES ('essentials', 'Rent/mortgage', 1);
      
    • 保存该.db文件,放入项目的src/main/assets目录下。
  2. 匹配Room实体类
    确保AppDataBase中的实体类与attributes表结构完全对应:
    @Entity(tableName = "attributes")
    data class Attribute(
        @PrimaryKey(autoGenerate = true) val id: Int = 0,
        val key: String,
        val value: String,
        val meta_data: String = "",
        val isActive: Int
    )
    
    @Database(entities = [Attribute::class], version = 1)
    abstract class AppDataBase : RoomDatabase() {
        // 定义DAO接口
    }
    
    你的原有初始化代码无需修改,首次启动时Room会自动将assets中的.db文件复制到应用私有目录,后续数据库可正常读写编辑。

方案二:使用Room Callback执行初始化SQL

若不想提前创建.db文件,可通过Room的Callback在数据库首次创建时执行初始化逻辑:

  1. 定义Database Callback
    val roomInitCallback = object : RoomDatabase.Callback() {
        override fun onCreate(db: SupportSQLiteDatabase) {
            super.onCreate(db)
            // 若已通过Room实体类创建表,可省略CREATE TABLE语句
            db.execSQL("""
                INSERT INTO `attributes` (`key`, `value`, `isActive`) 
                VALUES ('essentials', 'Rent/mortgage', 1);
            """.trimIndent())
            // 可添加更多预填充数据的INSERT语句
        }
    }
    
  2. 修改Room初始化代码
    移除createFromAsset,添加回调:
    Room.databaseBuilder(
        context.applicationContext,
        AppDataBase::class.java,
        "wallet.db"
    )
    .setQueryCallback(QueryInterceptor(), Executors.newSingleThreadScheduledExecutor())
    .addCallback(roomInitCallback)
    .build()
    

额外注意事项

  • 确保Room数据库版本号与操作匹配,后续修改表结构需添加Migration逻辑。
  • 方案一中,assets内的.db文件结构必须与Room实体类完全一致,否则会触发初始化失败。
  • 所有SQL语句中的字符串值必须用单引号包裹,避免语法错误。

内容的提问来源于stack exchange,提问作者Sv Harish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 13:15:08