Android Kotlin项目SQLDelight新增表时非空数据库报无表错误
问题:SQLDelight新增表在已有数据的数据库中触发“No such table”错误
我用Kotlin+SQLDelight开发Android应用,新增.sq表定义后,仅在数据库已有数据时操作新表会报“No such table”错误,但空数据库下完全正常。
环境信息
- Kotlin版本:1.8.0
- SQLDelight版本:2.0.0
- Gradle配置:
databases { register("TestDatabase") { packageName.set("com.test.app.db") verifyMigrations.set(true) } }
- SQLDelight驱动配置代码:
fun provideSqlDriver(context: Context): AndroidSqliteDriver = AndroidSqliteDriver( schema = DanaosDatabase.Schema, context = context, name = "test-db", callback = object : AndroidSqliteDriver.Callback(TestDatabase.Schema) { override fun onConfigure(db: SupportSQLiteDatabase) { super.onConfigure(db) setPragma(db, "JOURNAL_MODE = WAL") setPragma(db, "SYNCHRONOUS = 1") setPragma(db, "JOURNAL_SIZE_LIMIT = 6144000") } private fun setPragma(db: SupportSQLiteDatabase, pragma: String) { val cursor = db.query("PRAGMA $pragma") cursor.moveToFirst() cursor.close() } } ) fun provideDatabase( driver: SqlDriver, ): TestDatabase = TestDatabase( driver = driver )
- 新表定义示例(.sq文件):
CREATE TABLE IF NOT EXISTS NewTable ( id INTEGER PRIMARY KEY, name TEXT NOT NULL );
已尝试但无效的方案
- 清理并重建Android Studio项目
- 确认.sq文件位置、格式正确
- 检查SQLDelight生成的Kotlin代码无异常
- 添加SQLDelight迁移脚本(2.sqm),问题依旧
解决方案
1. 修正迁移脚本的写法
SQLDelight迁移脚本不需要加IF NOT EXISTS,因为迁移是针对旧版本数据库执行的,旧库中必然没有新表。错误的IF NOT EXISTS会导致SQLDelight的schema验证不通过,进而跳过表创建逻辑:
假设原数据库版本为1,新增表后版本升为2,在src/main/sqldelight/com/test/app/db/目录下创建2.sqm文件,内容改为:
-- 从版本1升级到版本2 CREATE TABLE NewTable ( id INTEGER PRIMARY KEY, name TEXT NOT NULL );
2. 统一Schema引用
原配置中同时出现了DanaosDatabase.Schema和TestDatabase.Schema,这会导致迁移逻辑混乱,必须统一为同一个Schema:
fun provideSqlDriver(context: Context): AndroidSqliteDriver = AndroidSqliteDriver( schema = TestDatabase.Schema, // 修正为统一的Schema引用 context = context, name = "test-db", callback = object : AndroidSqliteDriver.Callback(TestDatabase.Schema) { // 原有onConfigure代码不变 } )
3. 验证迁移执行状态
在Callback中添加onUpgrade方法,确认迁移是否被触发:
override fun onUpgrade(db: SupportSQLiteDatabase, oldVersion: Int, newVersion: Int) { super.onUpgrade(db, oldVersion, newVersion) Log.d("DB_MIGRATION", "执行迁移:从版本$oldVersion 到 $newVersion") }
如果日志未打印,说明数据库版本号未正确递增,需检查SQLDelight生成的TestDatabase.Schema.version是否符合预期。
4. 强制同步Schema与迁移脚本
开启verifyMigrations.set(true)后,SQLDelight会严格校验迁移脚本是否能将旧Schema升级为新Schema。如果编译时出现验证错误,需:
- 确保.sq文件中的表定义和迁移脚本的创建语句完全一致(字段类型、约束、索引等)
- 检查是否遗漏了其他Schema变更(如字段新增、约束修改)
内容的提问来源于stack exchange,提问作者NewAvenger220
相关产品推荐
相关产品推荐

