使用现有布尔列类型的房间迁移
room migration using existing boolean column types
到目前为止我发现了什么
所有带注释的@entity classes 都在编译期间进行处理,并生成数据库class 的实现。然后在访问数据库之前,调用此生成的 class 的 validateMigration 方法。此 validateMigration 方法通过原始查询
验证现有的数据库模式
PRAGMA table_info mytable name
(见android.arch.persistence.room.util.TableInfo.java的L208)
现在的问题
我的 sqlite3 数据库中有一些列的列类型为 BOOLEAN。 (slqite 内部处理为 int)。现在当我创建房间实体时说
public someEntity {
@columnInfo(name="someName")
public Boolean myValue;
}
房间的创建 table 查询将是
Create Table someEntity ( myValue INTEGER)
当我们使用 PRAGMA table_info someEntity
查询 existing 数据库时,我们得到
1|myValue|BOOLEAN|0||0
如上所述,room 通过比较字段名称、列类型等来验证(sqlite 到 room)迁移。并且由于列类型不匹配(BOOLEAN 和 INTEGER),它会抛出一个错误,指出迁移失败。
任何人都可以提出解决方法吗?我们可以让房间在 sqlite 中创建 BOOLEAN 列类型吗? (据我所知,我们不能 change/alter 现有 table 的列类型。)
PS:我也看到了 VARCHAR 的类似问题 - Using an existing VARCHAR column with Room
使用 DEFAULT
值和 NOT NULL
.
定义新属性 newAttribute 的迁移
代码
database.execSQL("ALTER TABLE tableName ADD COLUMN newAttribute INTEGER DEFAULT 0 NOT NULL")
完整代码
@Database(entities = arrayOf(ModelName::class), version = 2)
@TypeConverters(Converters::class)
abstract class DatabaseName : RoomDatabase() {
abstract fun daoName(): DaoName
companion object {
private var INSTANCE: DatabaseName? = null
fun getAppDatabase(context: Context): DatabaseName {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.applicationContext,
DatabaseName::class.java, DATABASE_NAME)
.addMigrations(MIGRATION_1_2)
.build()
}
return INSTANCE as DatabaseName
}
val MIGRATION_1_2: Migration = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE tableName ADD COLUMN newAttribute INTEGER DEFAULT 0 NOT NULL")
}
}
}
}
SQLite 没有布尔数据类型。 Room 将其映射到 INTEGER
列,将 true
映射到 1
,将 false 映射到 0
。
我认为下面的代码可以工作
database.execSQL("ALTER TABLE xyz_table ADD COLUMN abc INTEGER DEFAULT 0");
未记录。
到目前为止我发现了什么
所有带注释的@entity classes 都在编译期间进行处理,并生成数据库class 的实现。然后在访问数据库之前,调用此生成的 class 的 validateMigration 方法。此 validateMigration 方法通过原始查询
验证现有的数据库模式PRAGMA table_info mytable name
(见android.arch.persistence.room.util.TableInfo.java的L208)
现在的问题
我的 sqlite3 数据库中有一些列的列类型为 BOOLEAN。 (slqite 内部处理为 int)。现在当我创建房间实体时说
public someEntity {
@columnInfo(name="someName")
public Boolean myValue;
}
房间的创建 table 查询将是
Create Table someEntity ( myValue INTEGER)
当我们使用 PRAGMA table_info someEntity
查询 existing 数据库时,我们得到
1|myValue|BOOLEAN|0||0
如上所述,room 通过比较字段名称、列类型等来验证(sqlite 到 room)迁移。并且由于列类型不匹配(BOOLEAN 和 INTEGER),它会抛出一个错误,指出迁移失败。
任何人都可以提出解决方法吗?我们可以让房间在 sqlite 中创建 BOOLEAN 列类型吗? (据我所知,我们不能 change/alter 现有 table 的列类型。)
PS:我也看到了 VARCHAR 的类似问题 - Using an existing VARCHAR column with Room
使用 DEFAULT
值和 NOT NULL
.
代码
database.execSQL("ALTER TABLE tableName ADD COLUMN newAttribute INTEGER DEFAULT 0 NOT NULL")
完整代码
@Database(entities = arrayOf(ModelName::class), version = 2)
@TypeConverters(Converters::class)
abstract class DatabaseName : RoomDatabase() {
abstract fun daoName(): DaoName
companion object {
private var INSTANCE: DatabaseName? = null
fun getAppDatabase(context: Context): DatabaseName {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.applicationContext,
DatabaseName::class.java, DATABASE_NAME)
.addMigrations(MIGRATION_1_2)
.build()
}
return INSTANCE as DatabaseName
}
val MIGRATION_1_2: Migration = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE tableName ADD COLUMN newAttribute INTEGER DEFAULT 0 NOT NULL")
}
}
}
}
SQLite 没有布尔数据类型。 Room 将其映射到 INTEGER
列,将 true
映射到 1
,将 false 映射到 0
。
我认为下面的代码可以工作
database.execSQL("ALTER TABLE xyz_table ADD COLUMN abc INTEGER DEFAULT 0");
未记录。