领域 android:无法将主键从 0.82.2 迁移到 0.86.0,因为字段支持 null
Realm android: Cant migrate primarykey from 0.82.2 to 0.86.0 because of field supporting null
我有一个 table,在 0.82.2 android 应用程序中有一个主键,具有以下字段:
// Each uid is generated using UUID strings:
@PrimaryKey
private String uid;
今天我已经更新到 Realm 0.86.0 以获得新的迁移 api(因为我添加了另一个 table 并想迁移现有的用户数据)。
但是,似乎 0.82.2 领域文件中的现有数据允许主键 uid 可以为空(当我 运行 应用程序没有对 uid 字段进行任何迁移时,领域告诉我这一点。
因此,我尝试创建一个名为 'id' 的新主键字段,然后使用以下代码迁移非空值:
dogSchema.removePrimaryKey();
dogSchema.addField("id", String.class, FieldAttribute.PRIMARY_KEY)
.transform(new RealmObjectSchema.Function() {
@Override
public void apply(DynamicRealmObject obj) {
String oldUid = obj.getString("uid");
// Bring over any non null uids, generate new id to replace nulls
if (oldUid == null || oldUid.equals("")) {
// Null, so generate one as primarykey doesnt allow nulls:
String newUid = RealmUtils.generateUID();
Log.d(TAG, "### New filler dog uid = " + newUid);
obj.setString("id", newUid);
} else {
Log.d(TAG, "### Old dog uid = " + oldUid);
obj.setString("id", oldUid);
}
}
});
dogSchema.removeField("uid");
但是,在迁移 运行s 之后,Realm 抛出异常说明:字段 'id' 不能是主键,因为现有的领域文件已经包含重复数据。尽管我可以看到每个 ID 值都不同。
如果我将 id 的 addfield 行更改为没有 PrimaryKey 属性(见下文),我会更进一步,但遇到另一个异常说 id 不能是主键,大概是因为我的模型有 @PrimaryKey 注释。
dogSchema.addField("id", String.class)
如何将主键迁移到 Realm 0.86.0?
感谢@Christian Melchior 在领域 java github 问题页面 (https://github.com/realm/realm-java/issues/1902) 上的帮助,我设法将旧模式主键迁移到领域 0.86.0:
结束代码是(注意缺少 'setNullable()' 调用)
"If your current uid field might contain null values you should be able to do it like this (without needing an additional field):"
dogSchema.transform(new RealmObjectSchema.Function() {
@Override
public void apply(DynamicRealmObject obj) {
String oldUid = obj.getString("uid");
// Bring over any non null uids, generate new id to replace nulls
if (oldUid == null || oldUid.equals("")) {
// Null, so generate one as primarykey doesnt allow nulls:
String newUid = RealmUtils.generateUID();
Log.d(TAG, "### New filler dog uid = " + newUid);
obj.setString("uid", newUid);
} else {
Log.d(TAG, "### Old dog uid = " + oldUid);
obj.setString("uid", oldUid);
}
}
});
我有一个 table,在 0.82.2 android 应用程序中有一个主键,具有以下字段:
// Each uid is generated using UUID strings:
@PrimaryKey
private String uid;
今天我已经更新到 Realm 0.86.0 以获得新的迁移 api(因为我添加了另一个 table 并想迁移现有的用户数据)。
但是,似乎 0.82.2 领域文件中的现有数据允许主键 uid 可以为空(当我 运行 应用程序没有对 uid 字段进行任何迁移时,领域告诉我这一点。
因此,我尝试创建一个名为 'id' 的新主键字段,然后使用以下代码迁移非空值:
dogSchema.removePrimaryKey();
dogSchema.addField("id", String.class, FieldAttribute.PRIMARY_KEY)
.transform(new RealmObjectSchema.Function() {
@Override
public void apply(DynamicRealmObject obj) {
String oldUid = obj.getString("uid");
// Bring over any non null uids, generate new id to replace nulls
if (oldUid == null || oldUid.equals("")) {
// Null, so generate one as primarykey doesnt allow nulls:
String newUid = RealmUtils.generateUID();
Log.d(TAG, "### New filler dog uid = " + newUid);
obj.setString("id", newUid);
} else {
Log.d(TAG, "### Old dog uid = " + oldUid);
obj.setString("id", oldUid);
}
}
});
dogSchema.removeField("uid");
但是,在迁移 运行s 之后,Realm 抛出异常说明:字段 'id' 不能是主键,因为现有的领域文件已经包含重复数据。尽管我可以看到每个 ID 值都不同。
如果我将 id 的 addfield 行更改为没有 PrimaryKey 属性(见下文),我会更进一步,但遇到另一个异常说 id 不能是主键,大概是因为我的模型有 @PrimaryKey 注释。
dogSchema.addField("id", String.class)
如何将主键迁移到 Realm 0.86.0?
感谢@Christian Melchior 在领域 java github 问题页面 (https://github.com/realm/realm-java/issues/1902) 上的帮助,我设法将旧模式主键迁移到领域 0.86.0:
结束代码是(注意缺少 'setNullable()' 调用)
"If your current uid field might contain null values you should be able to do it like this (without needing an additional field):"
dogSchema.transform(new RealmObjectSchema.Function() {
@Override
public void apply(DynamicRealmObject obj) {
String oldUid = obj.getString("uid");
// Bring over any non null uids, generate new id to replace nulls
if (oldUid == null || oldUid.equals("")) {
// Null, so generate one as primarykey doesnt allow nulls:
String newUid = RealmUtils.generateUID();
Log.d(TAG, "### New filler dog uid = " + newUid);
obj.setString("uid", newUid);
} else {
Log.d(TAG, "### Old dog uid = " + oldUid);
obj.setString("uid", oldUid);
}
}
});