将主键添加到RLMObject需要迁移,任何想法如何?

时间:2015-03-25 17:04:44

标签: ios objective-c cocoa-touch realm

我正在使用Realm.io作为持久存储的iOS应用程序。 我刚刚通过添加主键更新了我的一个自定义RLMObject子类。

当我运行应用程序时,我收到错误,告诉我需要添加迁移步骤:

'Migration is required for object type 'MY_REALM_OBJECT' due to the following errors:
- Property 'property_name' has been made a primary key.'

我有其他迁移代码但无法在Realm文档中找到有关如何将主键添加到RLMObject的任何内容。

任何人都知道怎么做?

3 个答案:

答案 0 :(得分:4)

  

我有其他迁移代码,但在Realm文档中找不到有关如何将主键添加到RLMObject的任何内容。

你已经把它变成了主键! Realm文档在"Customizing Models"部分介绍了这一点。

由于向模型添加/修改主键需要更新数据库文件(数据库中该表/列的每个值都将被编入索引),因此需要更新模式版本。

主键必须是唯一的。如果所有值都是唯一的,Realm将自动为您应用迁移,因此您无需对迁移块中的property_name属性进行任何更改。

如果property_name值并非都是唯一的,那么您需要在迁移块中使它们唯一。在Realm迁移块中更改数据的方法是使用键控下标迭代现有对象并在newObject上设置值:

[RLMRealm setSchemaVersion:1
            forRealmAtPath:realmPath
        withMigrationBlock:^(RLMMigration *migration, NSUInteger oldSchemaVersion) {
  if (oldSchemaVersion < 1) {
    __block NSInteger incrementingPrimaryKeyValue = 0;
    // The enumerateObjects:block: method iterates
    // over every 'MY_REALM_OBJECT' object stored in the Realm file
    [migration enumerateObjects:@"MY_REALM_OBJECT"
                          block:^(RLMObject *oldObject, RLMObject *newObject) {

      // set the primary key to a unique value
      newObject[@"property_name"] = @(incrementingPrimaryKeyValue++);
    }];
  }
}];

要详细了解迁移,请阅读Realm文档的"Migrations"部分。

答案 1 :(得分:2)

在Swift中,我使用以下代码成功地向我的Realm添加了一个主键:

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
        var sharedUserID = ""

        migration.enumerate(AdAccount.className()) { oldObject, newObject in
            if oldSchemaVersion < 1 {
                // Realm will automatically detect new properties and removed properties
                // And will update the schema on disk automatically
                sharedUserID = oldObject!["userID"] as! String
                newObject!["compoundKey"] = oldObject!["compoundkey"]
            }
        }

        migration.enumerate(AdCampaign.className()) { oldObject, newObject in
            if oldSchemaVersion < 1 {
                // Realm will automatically detect new properties and removed properties
                // And will update the schema on disk automatically
                let id = oldObject!["id"] as! String
                let dateRange = oldObject!["daterange"]
                let userID = sharedUserID

                newObject!["dateRange"] = dateRange
                newObject!["userID"] = userID
                newObject!["compoundKey"] = "\(id)-\(dateRange)-\(userID)"
            }
        }
        print("Migration complete.")
    })

    // Tell Realm to use this new configuration object for the default Realm
    Realm.Configuration.defaultConfiguration = config
    let realm = try! Realm()
}

您需要确保使用主键的名称并使用oldObject属性设置它的值。每个主键都必须是唯一的。正如您在示例中所看到的,此主键由三个值组成,以使其唯一。

答案 2 :(得分:1)

您需要使用键“primaryKeyProperty”并将值设置为newObject的迁移块中的RLMObject属性名称。 primaryKeyProperty是需要迁移的RLMObjectSchema属性的名称。

[RLMRealm setSchemaVersion:kLatestSchemaVersion
            forRealmAtPath:theRealmPath
        withMigrationBlock:^(RLMMigration *migration,
                             NSUInteger oldSchemaVersion)
 {
     if ( oldSchemaVersion < kLatestSchemaVersion )
     {
         [migration enumerateObjects:MyRealmClass.className
                               block:^(RLMObject *oldObject, 
                                       RLMObject *newObject)
          {
              newObject[@"primaryKeyProperty"] = @"propertyName";
          }];
     }
 }];