11
votes

Problème de migration de données de base: "La migration du magasin persistant a échoué, modèle d'objet géré de la source manquante."

le fond

  • Données de base de cacao non documentaire Projet avec deux objets gérés Des modèles.
  • Le modèle 1 reste le même. Modèle 2 a changé, donc je veux migrer le magasin.
  • J'ai créé une nouvelle version Par design> Modèle de données> Ajouter un modèle Version en Xcode.
  • La différence entre les versions est une relation unique qui a été changée de l'une à plusieurs.
  • j'ai fait mon modifications apportées au modèle, puis sauvegardées.
  • J'ai fait un nouveau modèle de cartographie qui a l'ancien modèle comme une source et une nouvelle modèle comme une destination.
  • j'ai assuré Tous les modèles de mappage et modèles de données et sont compilés et tous sont copié dans le dossier de ressources de mon app.
  • J'ai allumé les migrations par passer dans un dictionnaire avec le NSMIGRACERPERSISTESTORSEUTEMENTOPTIONMENTOPTION clé comme [nsnumber Numérowithbool: Oui] lors de l'ajout du Magasin persistant.
  • plutôt que de fusionner Tous les modèles dans le paquet, j'ai spécifié les deux modèles que je veux utiliser (modèle 1 et nouvelle version du modèle 2) et fusionné à l'aide de ModelBymergingModels:

    le problème

    Peu importe ce que je fais pour migrer, je reçois le message d'erreur:

    "La migration du magasin persistant a échoué, Modèle d'objet géré de la source manquante. "

    ce que j'ai essayé

    • Je nettoie après chaque construction.
    • J'ai essayé diverses combinaisons de avoir seulement le modèle que je migre en ressources, être compilé, ou les deux.
    • depuis le message d'erreur implique qu'il ne trouve pas la source modèle pour ma migration, j'ai essayé avoir chaque version du modèle dans le dossier de ressources et être compilé.
    • je suis assuré que je ne suis pas faire une erreur vraiment fondamentale par Retourner à l'original version de mon modèle de données. L'application court bien.
    • J'ai supprimé la cartographie Modèle et nouvelle version du modèle, nettoyé, puis recréé à la fois.
    • J'ai essayé de faire un changement différent Dans le nouveau modèle - Suppression d'une entité à la place.

      Je suis à ma fin de mon esprit.

      Je ne peux pas m'empêcher de penser que j'ai fait une énorme erreur quelque part que je ne vois pas. Des idées?


0 commentaires

6 Réponses :


15
votes

Deux possibilités:

  1. Votre modèle source de votre application ne correspond pas au magasin réel sur le disque.
  2. Votre modèle de mappage ne correspond pas à votre modèle source.

    Allumez Débogage de données de base et vous devriez pouvoir voir les hachages que les données principales recherchent quand elle fait la migration. Comparez ces hachages à ce qui se trouve dans votre magasin sur disque et voyez s'ils correspondent. De même, le débogage devrait vous laisser voir les hachages dans le modèle de cartographie pour vous aider à tout faire correspondre à tout.

    Si ce n'est que votre modèle de mappage malaligné, vous pouvez le dire de la mise à jour de la source du menu de conception de Xcode. Si vous manquez le modèle source réel pour votre fichier de magasin sur le disque, vous pouvez consulter votre système de contrôle de version ou essayer d'utiliser une migration automatique pour obtenir ce fichier à migrer vers le modèle que vous croyez est la source.

    Mise à jour 1

    L'emplacement de modification des modèles source et de destination est déplacé vers le bas de la fenêtre de l'éditeur:


7 commentaires

Grande réponse, Marcus. Merci. Je vais vérifier les hachages. Je suis à peu près sûr que ce n'est pas l'option 1, mais je vais vérifier néanmoins. Xcode doit avoir une bonne raison pour montrer ce message d'erreur.


@Marcus Comment faire le modèle source de mise à jour dans Xcode 5?


@Marcus Je n'ai pas reçu la phrase que vous avez écrite: "Vous pouvez le dire de mettre à jour à partir de la source du menu de conception de xcode" - où? comment?


Réponse mise à jour. Xcode a changé au cours des 6 dernières années.


@Marcus: Merci d'avoir maintenu la réponse. Malheureusement, la capture d'écran n'est plus valide. De plus, dois-je conserver les versions de fichier source de fichiers, pour le modèle de données et pour les classes "Implémentation"?


@WizardofkNeUp Image Re-téléchargée. Vous devez conserver les deux fichiers de modèle, mais vous n'avez pas besoin de conserver les classes de mise en œuvre.


Cette réponse m'a finalement aidé à réduire ma longue recherche avec la clé d'option de débogage incroyablement utile pour la migration, disponible dans ce lien fourni. com.apple.coredata.migrationDebug 1 m'a aidé à voir que la migration a été appliquée deux fois et m'a permis d'ajuster le code de manière meilleure.



6
votes

plutôt que de fusionner tous les modèles dans le Bundle, j'ai spécifié les deux modèles Je veux utiliser (modèle 1 et nouveau version du modèle 2) et les a fusionnés Utilisation de modelBymergingModels: P>

Cela ne semble pas juste. Pourquoi fusionner les modèles? Vous voulez utiliser modèle 2 em>, migrer votre magasin de modèle 1 em>. P>

de la référence de classe NSManèdeObjectModel forte> p >

ModelBymergingModels: code> p>

crée un seul modèle d'un tableau d'existant Modèles. P> blockQuote>

Vous n'avez pas besoin de faire quelque chose de spécial / spécifique avec votre modèle source ( modèle 1 em>) .. Tant que c'est dans votre paquet, le processus de migration légère automatique sera Découvrez et utilisez-le. P>

Je suggérerais d'abandonner le modèle de mappage que vous avez créé dans Xcode, comme j'ai Vu terrible performance par rapport aux migrations automatiques-légères. Votre kilométrage peut varier, mes changements entre les modèles sont différents pour le vôtre, mais je ne serais pas surpris. Essayez du chronométrage avec et sans votre propre modèle de mappage dans le paquet. P> xxx pré>

Vous pouvez vérifier dans votre code que votre modèle source est disponible en essayant de le charger et de vérifier que Ce n'est pas nul: p>

NSError *error;
NSDictionary *storeMeta = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:nil URL:self.storeURL error:&error];
if (storeMeta == nil) {
    // Unable to read store meta
    return NO;
}
BOOL isCompatible = [modelOne isConfiguration:nil compatibleWithStoreMetadata:storeMeta];


1 commentaires

Ohhorob: "Cela ne semble pas vrai. Pourquoi fusionner les modèles? Vous voulez utiliser le modèle 2, migrer votre magasin de modèle 1." Je crois que ses deux modèles sont pour deux ensembles différents d'entités / attributs / relations. Les deux modèles n'ont pas les mêmes entités - elles ne sont pas liées. Comme le modèle 1 pour les employés / ministères et modèle 2 pour les produits / clients.



3
votes

Tout en essayant de mettre à niveau le modèle de données de base de l'application existant (et de migrer les données hérités), je viens de courir sur un scénario dans lequel un cadre tiers écrivait des données dans la base de données d'une application. J'avais cette erreur "Impossible de trouver le modèle pour le magasin source." Étant donné que le modèle tiers n'a pas été chargé lorsque j'essayais la migration, la migration échouait.

J'ai écrit cette méthode (ci-dessous) pendant le dépannage de ce problème. Cela peut être utile à ceux qui sont confrontés à ces types de problèmes. P>

NSError *error = nil;
NSURL *storeUrl = [NSURL fileURLWithPath:storePath];
NSDictionary *storeMeta = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:nil URL:storeUrl error:&error];
NSLog(@"%@", [storeMeta objectForKey: @"NSStoreModelVersionHashes"]);


2 commentaires

Bonjour xyzzycoder! J'ai aussi eu un problème similaire. Pouvez-vous me dire comment vous avez migré des données de base dans un cas donné (cadre tiers écrivait des données dans la base de données d'une application). Merci


@MOHITNIGAM C'était il y a quelque temps, mais j'ai fini par ouvrir directement le magasin de données SQLite (avant d'aborder la pile de données de base), laissez tomber les tables de la tierce partie, à la mise à jour des entrées de métadonnées pour supprimer les références aux tables tiers, Fermer le fichier SQLITE, puis les données de base vers le haut (et il a ensuite été capable de faire la migration automatique). En fait, j'ai abordé l'équipe de données de base à la WWDC à ce sujet et ils n'avaient pas une meilleure idée.



1
votes

J'ai eu un problème similaire. J'ai utilisé + modelbymérgeingmodels: , mais je n'ai pas utilisé de modèle de mappage. Cependant, la fusion de modèles ne fonctionne pas avec la migration de données légères.

de la DOCS Apple:

Pour effectuer une migration légère automatique, les données de base doivent être capables de trouver Rechercher l'objet Source et de la destination Modèle S-SI-SIMO AU RUNTIME .

Si vous utilisez + modelbymérgeingmodels: que celui utilisé pour le modèle de destination. Cependant, les données de base ne pourront pas trouver le modèle source. Le modèle source a été créé à l'aide de + modelbymergeingmodels: dans la version antérieure de l'application et des données de base tente de fusionner des modèles pour connaître le modèle source.

Qu'est-ce que j'ai fini par faire, c'est que j'ai (manuellement) créé une nouvelle fustion .xcdatamodeld en modifiant les fichiers XML des modèles, l'a ajouté dans le projet, supprimé le séparé. xcdatamodeld S à partir de sources de compilée et au lieu d'utiliser + modelbymérgeingmodels: Utiliser nsmanagedObjectmodel 's -Initwithcontentsofurl: avec l'URL du nouveau Modèle fusionné. Je créerai probablement un script qui fusionnera automatiquement les modèles à l'avenir.


0 commentaires

4
votes

Lorsque j'ai eu cette erreur, j'avais mis à jour mes modèles de données principaux mais n'a pas effacé l'instance d'application de mon téléphone de test. Cela signifiait que les modèles économisés sur des données de base sur le téléphone ne correspondaient pas à ce que j'essayais d'utiliser dans le code.

J'ai supprimé l'application du téléphone et ré-construit / couru avec succès.


1 commentaires

Corrigé pour moi. Merci!



1
votes

Si vous avez ce problème pour une application Mac Catalyst, vous devez supprimer les données stockées qui peuvent être trouvées dans ~ / Bibliothèque / conteneurs / Nom de-App


1 commentaires

Cela a réparé pour moi. La seule capture était que le nom du conteneur était haché (par exemple 7f8e9252-cffa-446c-a0d7-d00b97db18de ), donc je l'ai trouvé en recherchant le plus récent conteneur, puis en le supprimant.