在Room 2.1.0中,通常使用以下代码
版本2
@Entity(tableName = "password")
public class Password {
@ColumnInfo(name = "dummy0")
@NonNull
public String dummy0;
}
public class Migration_1_2 extends Migration {
public Migration_1_2() {
super(1, 2);
}
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE password ADD COLUMN dummy0 TEXT NOT NULL DEFAULT ''");
}
}
迁移指南来自
- https://developer.android.com/training/data-storage/room/migrating-db-versions.md#handle-default-values-migrations
- https://developer.android.com/jetpack/androidx/releases/room
是相当混乱的。
注:如果您的数据库方案已有默认值(例如通过ALTER TABLE x ADD COLUMN y INTEGER NOTNULL DEFAULT z添加的默认值),并且您决定通过@ColumnInfo为相同的列定义默认值,则可能需要提供迁移来验证未计入的默认值。有关详情,请参阅:房间迁移
在升级到2.2.3之前,有两种可能性
1.如果迁移运行,则dummy0
列具有默认值。
1.或者,如果这是新的DB,我们有一个没有默认值的dummy0
列。
当我们从Room 2.1.0升级到Room 2.2.3时,这两种情况下一切都运行良好,无需为删除并重新创建表添加额外的迁移代码。
我们会做进一步测试。
版本3
@Entity(tableName = "password")
public class Password {
@ColumnInfo(name = "dummy0")
@NonNull
public String dummy0;
@ColumnInfo(name = "dummy1")
@NonNull
public String dummy1;
}
public class Migration_2_3 extends Migration {
public Migration_2_3() {
super(2, 3);
}
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE password ADD COLUMN dummy1 TEXT NOT NULL DEFAULT ''");
}
}
仍然工作正常。
版本4
@Entity(tableName = "password")
public class Password {
@ColumnInfo(name = "dummy0")
@NonNull
public String dummy0;
@ColumnInfo(name = "dummy1")
@NonNull
public String dummy1;
@ColumnInfo(name = "dummy2", defaultValue = "")
@NonNull
public String dummy2;
}
public class Migration_3_4 extends Migration {
public Migration_3_4() {
super(3, 4);
}
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE password ADD COLUMN dummy2 TEXT NOT NULL DEFAULT ''");
}
}
仍然工作正常。
所以,我很困惑?在什么用例下,我们需要删除并重新创建表?
2条答案
按热度按时间uqzxnwby1#
我认为问题不在于添加新列时,而在于对现有列应用/更改/删除默认值时。然后,您可能必须重新创建受影响的表。
例如,如果您更改了:-
添加默认值
那么就会出现模式不匹配,因为预期的模式将具有
DEFAULT ''
,而找到的模式(原始数据库)没有默认编码。如果在2.2.0之前,您有一个包含默认值的先前非空间生成的模式,并且实体没有相应地更改,那么您将得到冲突,因为预期的模式没有默认值,而找到的模式包含
DEFAULT = ''
。示例
假设当前实体为:
那么生成的用于创建表的代码是:-
如果现在是版本2,则更改为:-
则生成的代码为:-
运行哑/空迁移(1-2),然后:-
defaultValue='null'
defaultValue=''''
依据:-
示例修复
使用迁移:-
修复了该问题。
编号
以下代码用于生成上述内容:
密码.java
密码数据库.java
主要活动.java
smdncfj32#
初始版本数据库瓦尔为var saleType:字符串=“买入”
在下一个版本中,我将其更改为var saleType:字符串=“卖出”
那么如何编写迁移代码呢?