如何为使用 Room Auto-Migrations 创建的新列的现有行设置默认值?
How to set a default value to existing rows for a new column created using Room Auto-Migrations?
我的房间 SQL table 有几列。我想向其中添加一个包含布尔值的列。为了将我的数据库迁移到这个新模式,我正在尝试使用 Room Auto-Migrations。我的问题是如何更新 table 中的现有行,使这个新添加的列具有值 false
?我是否必须通过更改 table 并将默认值插入所有行来回退到编写手动迁移?
My question is how can I update my existing rows in the table to have a value false for this newly added column?
使用 @ColumnInfo
的 defalutValue 例如对于实体中的列。
@ColumnInfo(defaultValue = "0")
Will I have to fallback to writing manual migration by altering the table and inserting the default value to all rows?
这应该在自动迁移时添加具有默认值子句的列。
- 我相信(如果没记错的话)如果您不编写默认值,那么由于新列没有默认值,自动迁移将失败。
额外
如果您随后想使用默认值插入,您将无法在使用 @Dao 注释的相应 interface/asbstract class 中使用方便的 @Insert
注释,但是必须使用 @Query
来列出省略要使用默认值的列的列,并且具有指定命名列的值的 VALUES 子句。
例如对于具有 3 列的 table,columna、columnb 和 columnc;其中 columnc 指定了 DEFAULT 那么插入函数可能是这样的:-
@Query("INSERT INTO the_table (columna,columnb) VALUES(:valueForColumnA,:valueForColumnB);")
fun insertWithDefaultValueForColumnC(valueForColumnA: TheType,valueForColumnB: TheType): Long
- 注意以上为原理代码,尚未编译、测试或运行因此可能包含一些错误。
补充评论
I tried @ColumnInfo(defaultValue = "1") and @ColumnInfo(defaultValue = "true") to set the default value to true. But that didn't work.
defaultValue = "1"
or defaultvalue = "0"
do work (1 is true 0 is false).
但是、default = "false"
或 default = "true"
没有按预期工作。他们会得到与 default = "whatever...."
.
相似的结果
可能是错误,也可能是 Room 的问题。后者发生的情况是它们作为字符串(SQLite 中的 TEXT)传递,因此即使该列已被定义为布尔值,它们实际上也是如此插入的。由于任何列都可以存储任何类型的灵活性,SQLite 允许这样的值。
考虑以下实体:-
@Entity
data class Example1(
@PrimaryKey
val id: Long? = null,
val name: String,
/*
ADDITIONS FOR V2
*/
@ColumnInfo(defaultValue = "1")
val b1: Boolean,
@ColumnInfo(defaultValue = "0")
val b2: Boolean,
@ColumnInfo(defaultValue = "false")
val b3: Boolean,
@ColumnInfo(defaultValue = "true")
val b4: Boolean
)
当版本 1 为 运行 时存在 10 行时添加 b1-b4 并完成自动迁移,当版本 2 为 运行 时另外 10 行为 运行 ] 并根据 :-
添加另外 10 列
db = TheDatabase.getInstance(this)
dao = db.getAllDao()
for (i in 1..10) {
dao.insert(Example1(name = "V${DATABASE_VERSION}_$i", b1 = true, b2 = true, b3 = true, b4 = true))
}
for(e: Example1 in dao.getAllExample1s()) {
Log.d("DBINFO","Name is ${e.name} id id ${e.id} " +
/*" ADDED COL = There Aren't any" */
" B1=${e.b1} B2=${e.b2} B3=${e.b3} B4=${e.b4}"
)
}
第二个运行的结果是:-
2022-01-05 09:41:43.503 D/DBINFO: Name is V1_1 id id 1 B1=true B2=false B3=false B4=false
2022-01-05 09:41:43.504 D/DBINFO: Name is V1_2 id id 2 B1=true B2=false B3=false B4=false
2022-01-05 09:41:43.504 D/DBINFO: Name is V1_3 id id 3 B1=true B2=false B3=false B4=false
2022-01-05 09:41:43.504 D/DBINFO: Name is V1_4 id id 4 B1=true B2=false B3=false B4=false
2022-01-05 09:41:43.504 D/DBINFO: Name is V1_5 id id 5 B1=true B2=false B3=false B4=false
2022-01-05 09:41:43.504 D/DBINFO: Name is V1_6 id id 6 B1=true B2=false B3=false B4=false
2022-01-05 09:41:43.504 D/DBINFO: Name is V1_7 id id 7 B1=true B2=false B3=false B4=false
2022-01-05 09:41:43.504 D/DBINFO: Name is V1_8 id id 8 B1=true B2=false B3=false B4=false
2022-01-05 09:41:43.504 D/DBINFO: Name is V1_9 id id 9 B1=true B2=false B3=false B4=false
2022-01-05 09:41:43.504 D/DBINFO: Name is V1_10 id id 10 B1=true B2=false B3=false B4=false
2022-01-05 09:41:43.504 D/DBINFO: Name is V2_1 id id 11 B1=true B2=true B3=true B4=true
2022-01-05 09:41:43.504 D/DBINFO: Name is V2_2 id id 12 B1=true B2=true B3=true B4=true
2022-01-05 09:41:43.505 D/DBINFO: Name is V2_3 id id 13 B1=true B2=true B3=true B4=true
2022-01-05 09:41:43.505 D/DBINFO: Name is V2_4 id id 14 B1=true B2=true B3=true B4=true
2022-01-05 09:41:43.505 D/DBINFO: Name is V2_5 id id 15 B1=true B2=true B3=true B4=true
2022-01-05 09:41:43.505 D/DBINFO: Name is V2_6 id id 16 B1=true B2=true B3=true B4=true
2022-01-05 09:41:43.505 D/DBINFO: Name is V2_7 id id 17 B1=true B2=true B3=true B4=true
2022-01-05 09:41:43.505 D/DBINFO: Name is V2_8 id id 18 B1=true B2=true B3=true B4=true
2022-01-05 09:41:43.506 D/DBINFO: Name is V2_9 id id 19 B1=true B2=true B3=true B4=true
2022-01-05 09:41:43.506 D/DBINFO: Name is V2_10 id id 20 B1=true B2=true B3=true B4=true
前 10 行应用了默认值:-
根据编码的默认值,- b1 为真,即 1 = true
根据编码的默认值,- b2 为假,即 0 = false
- b3 和 b4 为 false,因为该值是 TEXT/STRING(如将显示的),无法转换为 Int,因此它不会发生异常,而是转换为 0,因此为 false。
如果App Inspection用于查看它显示的数据:-
如果再次使用 App Inspection/Database Inspector 并且 table 使用 SELECT *,typeof(b1),typeof(b2),typeof(b3),typeof(b4) FROM example1;
查询,则 :-
即AutoMigration 之前存在的 10 行的 b3 和 b4 列保存为 TEXT。
我的房间 SQL table 有几列。我想向其中添加一个包含布尔值的列。为了将我的数据库迁移到这个新模式,我正在尝试使用 Room Auto-Migrations。我的问题是如何更新 table 中的现有行,使这个新添加的列具有值 false
?我是否必须通过更改 table 并将默认值插入所有行来回退到编写手动迁移?
My question is how can I update my existing rows in the table to have a value false for this newly added column?
使用 @ColumnInfo
的 defalutValue 例如对于实体中的列。
@ColumnInfo(defaultValue = "0")
Will I have to fallback to writing manual migration by altering the table and inserting the default value to all rows?
这应该在自动迁移时添加具有默认值子句的列。
- 我相信(如果没记错的话)如果您不编写默认值,那么由于新列没有默认值,自动迁移将失败。
额外
如果您随后想使用默认值插入,您将无法在使用 @Dao 注释的相应 interface/asbstract class 中使用方便的 @Insert
注释,但是必须使用 @Query
来列出省略要使用默认值的列的列,并且具有指定命名列的值的 VALUES 子句。
例如对于具有 3 列的 table,columna、columnb 和 columnc;其中 columnc 指定了 DEFAULT 那么插入函数可能是这样的:-
@Query("INSERT INTO the_table (columna,columnb) VALUES(:valueForColumnA,:valueForColumnB);")
fun insertWithDefaultValueForColumnC(valueForColumnA: TheType,valueForColumnB: TheType): Long
- 注意以上为原理代码,尚未编译、测试或运行因此可能包含一些错误。
补充评论
I tried @ColumnInfo(defaultValue = "1") and @ColumnInfo(defaultValue = "true") to set the default value to true. But that didn't work.
defaultValue = "1"
or defaultvalue = "0"
do work (1 is true 0 is false).
但是、default = "false"
或 default = "true"
没有按预期工作。他们会得到与 default = "whatever...."
.
可能是错误,也可能是 Room 的问题。后者发生的情况是它们作为字符串(SQLite 中的 TEXT)传递,因此即使该列已被定义为布尔值,它们实际上也是如此插入的。由于任何列都可以存储任何类型的灵活性,SQLite 允许这样的值。
考虑以下实体:-
@Entity
data class Example1(
@PrimaryKey
val id: Long? = null,
val name: String,
/*
ADDITIONS FOR V2
*/
@ColumnInfo(defaultValue = "1")
val b1: Boolean,
@ColumnInfo(defaultValue = "0")
val b2: Boolean,
@ColumnInfo(defaultValue = "false")
val b3: Boolean,
@ColumnInfo(defaultValue = "true")
val b4: Boolean
)
当版本 1 为 运行 时存在 10 行时添加 b1-b4 并完成自动迁移,当版本 2 为 运行 时另外 10 行为 运行 ] 并根据 :-
添加另外 10 列db = TheDatabase.getInstance(this) dao = db.getAllDao() for (i in 1..10) { dao.insert(Example1(name = "V${DATABASE_VERSION}_$i", b1 = true, b2 = true, b3 = true, b4 = true)) } for(e: Example1 in dao.getAllExample1s()) { Log.d("DBINFO","Name is ${e.name} id id ${e.id} " + /*" ADDED COL = There Aren't any" */ " B1=${e.b1} B2=${e.b2} B3=${e.b3} B4=${e.b4}" ) }
第二个运行的结果是:-
2022-01-05 09:41:43.503 D/DBINFO: Name is V1_1 id id 1 B1=true B2=false B3=false B4=false
2022-01-05 09:41:43.504 D/DBINFO: Name is V1_2 id id 2 B1=true B2=false B3=false B4=false
2022-01-05 09:41:43.504 D/DBINFO: Name is V1_3 id id 3 B1=true B2=false B3=false B4=false
2022-01-05 09:41:43.504 D/DBINFO: Name is V1_4 id id 4 B1=true B2=false B3=false B4=false
2022-01-05 09:41:43.504 D/DBINFO: Name is V1_5 id id 5 B1=true B2=false B3=false B4=false
2022-01-05 09:41:43.504 D/DBINFO: Name is V1_6 id id 6 B1=true B2=false B3=false B4=false
2022-01-05 09:41:43.504 D/DBINFO: Name is V1_7 id id 7 B1=true B2=false B3=false B4=false
2022-01-05 09:41:43.504 D/DBINFO: Name is V1_8 id id 8 B1=true B2=false B3=false B4=false
2022-01-05 09:41:43.504 D/DBINFO: Name is V1_9 id id 9 B1=true B2=false B3=false B4=false
2022-01-05 09:41:43.504 D/DBINFO: Name is V1_10 id id 10 B1=true B2=false B3=false B4=false
2022-01-05 09:41:43.504 D/DBINFO: Name is V2_1 id id 11 B1=true B2=true B3=true B4=true
2022-01-05 09:41:43.504 D/DBINFO: Name is V2_2 id id 12 B1=true B2=true B3=true B4=true
2022-01-05 09:41:43.505 D/DBINFO: Name is V2_3 id id 13 B1=true B2=true B3=true B4=true
2022-01-05 09:41:43.505 D/DBINFO: Name is V2_4 id id 14 B1=true B2=true B3=true B4=true
2022-01-05 09:41:43.505 D/DBINFO: Name is V2_5 id id 15 B1=true B2=true B3=true B4=true
2022-01-05 09:41:43.505 D/DBINFO: Name is V2_6 id id 16 B1=true B2=true B3=true B4=true
2022-01-05 09:41:43.505 D/DBINFO: Name is V2_7 id id 17 B1=true B2=true B3=true B4=true
2022-01-05 09:41:43.505 D/DBINFO: Name is V2_8 id id 18 B1=true B2=true B3=true B4=true
2022-01-05 09:41:43.506 D/DBINFO: Name is V2_9 id id 19 B1=true B2=true B3=true B4=true
2022-01-05 09:41:43.506 D/DBINFO: Name is V2_10 id id 20 B1=true B2=true B3=true B4=true
前 10 行应用了默认值:-
-
根据编码的默认值,
- b1 为真,即 1 = true 根据编码的默认值,
- b2 为假,即 0 = false
- b3 和 b4 为 false,因为该值是 TEXT/STRING(如将显示的),无法转换为 Int,因此它不会发生异常,而是转换为 0,因此为 false。
如果App Inspection用于查看它显示的数据:-
如果再次使用 App Inspection/Database Inspector 并且 table 使用 SELECT *,typeof(b1),typeof(b2),typeof(b3),typeof(b4) FROM example1;
查询,则 :-
即AutoMigration 之前存在的 10 行的 b3 和 b4 列保存为 TEXT。