web-dev-qa-db-fra.com

RLMException, la migration est requise pour le type d'objet

J'ai un objet NotSureItem dans lequel j'ai trois propriétés title dont le nom est renommé en text et textDescription que j'avais ajouté plus tard et une propriété dateTime. Maintenant, lorsque je vais exécuter mon application, elle se bloque lorsque je veux ajouter quelque chose à ces propriétés. Il montre les déclarations suivantes.

'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.'

Voici mon code:

import Foundation
import Realm

class NotSureItem: RLMObject {
    dynamic var title = ""   // renamed from 'text'
    dynamic var textDescription = "" // added afterwards
    dynamic var dateTime = NSDate()
}
22
shahin ali agharia

Tant que vous n'avez pas publié votre application , vous pouvez simplement supprimer votre application et l'exécuter à nouveau.

Chaque fois que vous modifiez les propriétés de vos objets Realm, votre base de données existante devient incompatible avec le nouveau. 

Tant que vous en êtes encore au stade du développement, vous pouvez simplement supprimer l’application du simulateur/appareil et la redémarrer.

Une fois votre application publiée et si vous modifiez les propriétés de vos objets, vous devez implémenter une migration vers la nouvelle version de la base de données.

Pour effectuer réellement une migration, vous implémentez un bloc de migration de royaume. En règle générale, vous ajoutez le bloc à 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()

Chaque fois que votre schéma change, vous devez augmenter la schemaVersion dans le bloc de migration et mettre à jour la migration nécessaire dans le bloc.

90
joern

Supprimer l'application et la réinstaller n'est pas une bonne pratique. Nous devrions intégrer certaines étapes de la migration au cours du développement dès la première fois que nous rencontrons un besoin de migration. Le lien donné par SilentDirge est bon: document de migration de royaume , qui donne de bons exemples pour la gestion de situations différentes.

Pour une tâche de migration minimale, l'extrait de code suivant provenant du lien ci-dessus peut effectuer automatiquement la migration et doit être utilisé avec la méthode disFinishLaunchWithOptions de AppDelegate:

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()

16
CodeBrew

Le code ci-dessous fonctionne pour moi

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

Plus d'infos: https://realm.io/docs/objc/latest/#getting-started

8
Vignesh

Votre base de données modifiée n'est plus compatible avec la base de données enregistrée, c'est pourquoi une migration est requise. Vous avez le choix entre supprimer l’ancien fichier de base de données et recommencer à zéro (fonctionne très bien si vous êtes dans la phase de développement initiale), ou si vous êtes en direct, effectuez la migration.

Pour ce faire, vous définissez une version de schéma et fournissez un "script" de migration de base de données dans votre configuration de royaume. L'ensemble du processus est documenté ici (avec des exemples de code): ici

3
SilentDirge

Vous pouvez effacer la base de données au lancement de la manière suivante:

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

Il suffit d'incrémenter la version du schéma

Le royaume détectera automatiquement les nouvelles propriétés et les propriétés supprimées

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