android
data_error
ai_generated
true
android.database.sqlite.SQLiteException: 无法从游标读取: 列'timestamp'类型为TEXT但期望INTEGER(代码0)
android.database.sqlite.SQLiteException: Cannot read from cursor: column 'timestamp' has type TEXT but expected INTEGER (code 0)
ID: android/room-migration-ambiguous-column-type
87%修复率
88%置信度
1证据数
2024-01-10首次发现
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| Room 2.6.1 | active | — | — | — |
| Android 12 (API 31) | active | — | — | — |
| Android 11 (API 30) | active | — | — | — |
| Room 2.5.2 | active | — | — | — |
根因分析
Room迁移脚本更改了架构但未转换现有数据类型,导致预期SQLite亲和类型(INTEGER)与列中实际存储类型(TEXT)不匹配。
English
Room migration script altered the schema without converting existing data types, causing a mismatch between the expected SQLite affinity (INTEGER) and the actual stored type (TEXT) in the column.
官方文档
https://developer.android.com/training/data-storage/room/migrating-databases解决方案
-
Write a manual migration that converts TEXT to INTEGER using CAST. Example in migration: ALTER TABLE my_table ADD COLUMN timestamp_temp INTEGER; UPDATE my_table SET timestamp_temp = CAST(timestamp AS INTEGER); ALTER TABLE my_table DROP COLUMN timestamp; ALTER TABLE my_table RENAME COLUMN timestamp_temp TO timestamp;
-
Use @TypeConverter to handle both types in the DAO. Example: @TypeConverter public static Long fromTimestamp(String value) { return value == null ? null : Long.parseLong(value); }
无效尝试
常见但无效的做法:
-
Delete app data and reinstall
80% 失败
This only works for development but destroys user data in production. The underlying migration issue is not fixed.
-
Add fallbackToDestructiveMigration() to Room database builder
90% 失败
This drops the entire database on migration failure, losing all user data. It's a nuclear option that doesn't fix the type mismatch.