web-dev-qa-db-ja.com

RLMException、オブジェクトタイプには移行が必要です

オブジェクトNotSureItemには、titletextから名前を変更した3つのプロパティtextDescriptionがあり、後で追加したdateTime var] _プロパティ。アプリを実行しようとすると、これらのプロパティに何かを追加しようとするとクラッシュします。次のステートメントを示しています。

'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()
}
27

アプリをリリースしていない限り単にアプリを削除して再実行できます。

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を増やし、ブロック内の必要な移行を更新する必要があります。

98
joern

アプリを削除して再インストールすることはお勧めできません。移行のニーズに最初に遭遇したときから、開発中にいくつかの移行手順を組み込む必要があります。 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()
22
CodeBrew

以下のコードは私のために働いています

- (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;
}

詳細: https://realm.io/docs/objc/latest/#getting-started

10
Vignesh

変更されたデータベースは保存されたデータベースと互換性がなくなったため、移行が必要です。あなたのオプションは、古いデータベースファイルを削除して、新たに開始することです(最初の開発フェーズにいる場合はうまくいきます)。

これを行うには、スキーマバージョンを定義し、Realm設定内でデータベース移行「スクリプト」を提供します。プロセス全体は(コードサンプルとともに)ここに文書化されています。 here

3
SilentDirge

次のように、起動時にデータベースを消去できます。

[[NSFileManager defaultManager] removeItemAtURL:[RLMRealmConfiguration defaultConfiguration].fileURL error:nil];
2
protspace

スキーマバージョンをインクリメントするだけです

レルムは、新しいプロパティと削除されたプロパティを自動的に検出します

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)
        }
1
Kirit Vaghela