我有一个对象NotSureItem
,其中我有三个属性title
,其名称已从text
重新命名,textDescription
我稍后添加了dateTime
属性。现在,当我要运行我的应用程序时,它会在我想要向这些属性添加内容时崩溃。它显示以下陈述。
'Migration is required for object type 'NotSureItem' due to the following errors:
- Property 'text' is missing from latest object model.
- Property 'title' has been added to latest object model.
- Property 'textDescription' has been added to latest object model.'
这是我的代码:
import Foundation
import Realm
class NotSureItem: RLMObject {
dynamic var title = "" // renamed from 'text'
dynamic var textDescription = "" // added afterwards
dynamic var dateTime = NSDate()
}
答案 0 :(得分:94)
只要您尚未发布应用,就可以删除自己的应用并再次运行。
每次更改Realm对象的属性时,现有数据库都会与新数据库不兼容。
只要您还处于开发阶段,您只需从模拟器/设备中删除该应用程序,然后重新启动即可。
稍后当您的应用已发布并且您更改了对象的属性时,您必须实现向新数据库版本的迁移。
要实际执行迁移,您需要实现Realm迁移块。通常,您会将块添加到application(application:didFinishLaunchingWithOptions:)
:
var configuration = Realm.Configuration(
schemaVersion: 1,
migrationBlock: { migration, oldSchemaVersion in
if oldSchemaVersion < 1 {
// if just the name of your model's property changed you can do this
migration.renameProperty(onType: NotSureItem.className(), from: "text", to: "title")
// if you want to fill a new property with some values you have to enumerate
// the existing objects and set the new value
migration.enumerateObjects(ofType: NotSureItem.className()) { oldObject, newObject in
let text = oldObject!["text"] as! String
newObject!["textDescription"] = "The title is \(text)"
}
// if you added a new property or removed a property you don't
// have to do anything because Realm automatically detects that
}
}
)
Realm.Configuration.defaultConfiguration = configuration
// opening the Realm file now makes sure that the migration is performed
let realm = try! Realm()
每当您的方案发生变化时,您必须增加迁移块中的schemaVersion
并更新块中所需的迁移。
答案 1 :(得分:18)
删除应用并重新安装不是一个好习惯。从我们第一次遇到迁移需求开始,我们应该在开发过程中加入一些迁移步骤。 SilentDirge给出的链接很好:realm migration document,它为处理不同情况提供了很好的例子。
对于最小迁移任务,上述链接中的以下代码段可以自动执行迁移,并与AppDelegate的disFinishLaunchWithOptions
方法一起使用:
let config = Realm.Configuration(
// Set the new schema version. This must be greater than the previously used
// version (if you've never set a schema version before, the version is 0).
schemaVersion: 1,
// Set the block which will be called automatically when opening a Realm with
// a schema version lower than the one set above
migrationBlock: { migration, oldSchemaVersion in
// We haven’t migrated anything yet, so oldSchemaVersion == 0
if (oldSchemaVersion < 1) {
// Nothing to do!
// Realm will automatically detect new properties and removed properties
// And will update the schema on disk automatically
}
})
// Tell Realm to use this new configuration object for the default Realm
Realm.Configuration.defaultConfiguration = config
// Now that we've told Realm how to handle the schema change, opening the file
// will automatically perform the migration
let _ = try! Realm()
答案 2 :(得分:9)
下面的代码对我有用
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
config.schemaVersion = 2;
config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) {
// The enumerateObjects:block: method iterates
// over every 'Person' object stored in the Realm file
[migration enumerateObjects:Person.className
block:^(RLMObject *oldObject, RLMObject *newObject) {
// Add the 'fullName' property only to Realms with a schema version of 0
if (oldSchemaVersion < 1) {
newObject[@"fullName"] = [NSString stringWithFormat:@"%@ %@",
oldObject[@"firstName"],
oldObject[@"lastName"]];
}
// Add the 'email' property to Realms with a schema version of 0 or 1
if (oldSchemaVersion < 2) {
newObject[@"email"] = @"";
}
}];
};
[RLMRealmConfiguration setDefaultConfiguration:config];
// now that we have updated the schema version and provided a migration block,
// opening an outdated Realm will automatically perform the migration and
// opening the Realm will succeed
[RLMRealm defaultRealm];
return YES;
}
答案 3 :(得分:3)
您修改的数据库不再与已保存的数据库兼容,这就是需要迁移的原因。您可以选择删除旧的数据库文件并重新开始(如果您处于初始开发阶段,则效果很好),或者如果您还在,请进行迁移。
您可以通过定义架构版本并提供数据库迁移&#39;脚本来实现此目的。在您的Realm配置中。这里记录了整个过程(以及代码示例):here
答案 4 :(得分:2)
您可以在启动时删除数据库,如下所示:
[[NSFileManager defaultManager] removeItemAtURL:[RLMRealmConfiguration defaultConfiguration].fileURL error:nil];
答案 5 :(得分:1)
var config = Realm.Configuration(
// Set the new schema version. This must be greater than the previously used
// version (if you've never set a schema version before, the version is 0).
schemaVersion: 2,
// Set the block which will be called automatically when opening a Realm with
// a schema version lower than the one set above
migrationBlock: { migration, oldSchemaVersion in
// We haven’t migrated anything yet, so oldSchemaVersion == 0
if (oldSchemaVersion < 1) {
// Nothing to do!
// Realm will automatically detect new properties and removed properties
// And will update the schema on disk automatically
}
})
do{
realm = try Realm(configuration: config)
print("Database Path : \(config.fileURL!)")
}catch{
print(error.localizedDescription)
}
答案 6 :(得分:0)
如果即使在递增schemaVersion后也遇到此错误。然后进行仔细检查。在更新App Delegate中的架构版本之前,是否您正在调用任何Realm对象。
对于我来说,我试图在执行该代码迁移语句之前访问App Delegate中的Realm对象。
始终将迁移代码写在App Delegate的第一行(DidfinishLaunchingWithOptions)中,以确保安全。