Проблема миграции основных данных: "ошибка миграции постоянного хранилища, отсутствует модель управляемого объекта источника."
Фон
- Основные Данные Не Документа Какао проект с двумя управляемыми объектами Модели.
- модель 1 остается неизменным. Модель 2 изменился, поэтому я хочу мигрировать магазин.
- Я создал новую версию по дизайну > модель данных > добавить модель Версии в Xcode.
- разница между версиями-это одно отношение, которое было изменено с одного на много.
- Я изменения в модели, после этого сохранить.
- Я сделал новую модель отображения, которая имеет старую модель как источник и новую модель как назначение.
- Я обеспечена все картографические модели и модели данных и компилируются, и все скопировать в папку Мои пакет приложений.
- я включил миграцию
передача в словаре с
NSMigratePersistentStoresAutomaticallyOption
ключ как[NSNumber numberWithBool:YES]
при добавлении Постоянный Магазин. - вместо слияния
все модели в комплекте, я указал два
модели, которые я хочу использовать (модель 1 и
новая версия модели 2) и слился
их использование
modelByMergingModels:
Проблема
независимо от того, что я делаю для миграции, я получаю сообщение об ошибке:
" ошибка миграции постоянного хранилища, отсутствует исходная управляемая объектная модель."
что я пробовал
- я убираю после каждой сборки.
- Я пробовал различные комбинации из имея только модель я миграция в ресурсы, компилируемые, или оба.
- С момента сообщения об ошибке подразумевается, что он не может найти источник модель для моей миграции, я пробовал каждая версия модели в как папка Resources, так и составленный.
- я убедился, что я не сделать действительно основную ошибку возврат к оригиналу версия моей модели данных. Приложение работает нормально.
- Я удалил отображение Модель и новая версия этот модель, очищенная, затем воссозданная.
- Я пробовал сделать другое изменение в новой модели - удаление объекта вместо.
Я в тупике.
Я не могу помочь, но думаю, что я совершила огромную ошибку где-то, что я не вижу. Есть идеи?
4 ответов
два варианта:
- ваша исходная модель в вашем приложении не соответствует фактическому хранилищу на диске.
- ваша модель отображения не соответствует вашей исходной модели.
поворот на отладка основных данных и вы должны иметь возможность видеть хэши, которые ищут основные данные, когда они выполняют миграцию. Сравните эти хэши с тем, что находится в вашем магазине на диске, и посмотрите, совпадают ли они. Аналогично, отладка должна позволить вам увидеть хэши в модели сопоставления, чтобы помочь вам сопоставить все.
Если это просто ваша модель отображения, которая не выровнена, вы можете сказать ей обновить из источника из меню дизайна в Xcode. Если отсутствует фактическая исходная модель для файла хранилища на диске, можно посмотреть в системе управления версиями или попробовать использовать автоматическую миграцию для переноса этого файла в модель, которая, по вашему мнению, является источником.
обновление 1
место для изменение исходной и целевой моделей переместилось в нижнюю часть окна редактора:
вместо объединения всех моделей в bundle, я указал две модели Я хочу использовать (модель 1 и новый версия модели 2) и объединили их использование modelByMergingModels:
это не кажется правильным. Зачем объединять модели? Вы хотите использовать модель 2 перенос вашего магазина от модель 1.
из ссылки на класс NSManagedObjectModel
modelByMergingModels:
создает единый модель из массива существующих модели.
вам не нужно делать ничего особенного / конкретного с вашей исходной моделью (модель 1).. пока он находится в вашем комплекте, автоматический легкий процесс миграции обнаружит и использует его.
Я бы предложил отказаться от модели отображения, которую вы создали в XCode, так как я видел ужасные показатели по сравнению с автоматическим-легкий миграции. Ваш пробег может отличаться, мои изменения между моделями отличаются от ваших, но я не удивлюсь. Попробуйте выбрать время с вашей собственной моделью отображения в комплекте и без нее.
/* Inferred mapping */
NSError *error;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,nil];
NSPersistentStore *migratedStore = [persistentStoreCoordinator addPersistentStoreWithType:nil
configuration:nil
URL:self.storeURL
options:options
error:&error];
migrationWasSuccessful = (migratedStore != nil);
вы можете проверить в своем коде, что ваша исходная модель доступна, пытаясь загрузить ее и убедиться, что она не равна нулю:
NSString *modelDirectoryPath = [[NSBundle mainBundle] pathForResource:@"YourModelName" ofType:@"momd"];
if (modelDirectoryPath == nil) return nil;
NSString *modelPath = [modelDirectoryPath stringByAppendingPathComponent:@"YourModelName"];
NSURL *modelFileURL = [NSURL fileURLWithPath:modelPath];
NSManagedObjectModel *modelOne = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelFileURL];
if (modelOne == nil) {
NSLog(@"Woops, XCode lost my source model");
}
else {
[modelOne release];
}
это предполагает, что в вашем проекте у вас есть ресурс"YourModelName.xcdatamodeld" и "YourModelName.xcdatamodel все" в ее рамках.
кроме того, вы можете проверить, совместима ли эта модель с вашим существующим постоянным хранилищем перед миграцией:
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];
этот код предполагает, что у вас есть метод -storeURL
чтобы указать, откуда загружается постоянное хранилище.
при попытке обновить основную модель данных существующего приложения (и перенести устаревшие данные) я только что столкнулся со сценарием, в котором сторонняя платформа записывала данные в базу данных приложения. Я получаю эту ошибку "не могу найти модель для исходного хранилища."Поскольку модель третьей стороны не была загружена, когда я пытался выполнить миграцию, миграция не удалась.
Я написал этот метод (ниже) во время устранения этой проблемы. Это может быть полезно для тех, кто столкнулся с этим тип вопроса.
- (BOOL) checkModelCompatibilityOfStoreWithURL: (NSURL *) myStoreURL
forModelNamed: (NSString *) myModelName
withBasePath: (NSString *) myBasePath;
{
NSError * error = nil;
NSDictionary *storeMeta = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:nil URL:myStoreURL error:&error];
if (!storeMeta) {
NSLog(@"Unable to load store metadata from URL: %@; Error = %@", myStoreURL, error);
return NO;
}
NSString * modelPath = [myBasePath stringByAppendingPathComponent: myModelName];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: modelPath]) {
// uh oh
NSLog(@"Can't find model.");
return NO;
}
NSURL * modelURL = [NSURL fileURLWithPath: modelPath];
NSManagedObjectModel * model = [[[NSManagedObjectModel alloc] initWithContentsOfURL: modelURL] autorelease];
BOOL result = [model isConfiguration: nil compatibleWithStoreMetadata: storeMeta];
NSLog(@"Tested model, %@, is%@ compatible with Database", modelPath, result ? @"" : @" ~not~");
return result;
}
этот фрагмент кода будет хранить метаданные.
NSError *error = nil;
NSURL *storeUrl = [NSURL fileURLWithPath:storePath];
NSDictionary *storeMeta = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:nil URL:storeUrl error:&error];
NSLog(@"%@", [storeMeta objectForKey: @"NSStoreModelVersionHashes"]);
В VersionInfo.plist (хранится в пакете скомпилированного приложения) содержит хэши, связанные с различными объектами в ваших моделях (кодировка base64). Аналогично, столбец BLOB в хранилище данных (Z_METADATA.Z_PLIST) содержит список свойств в двоичной кодировке с хэшами (также закодированными в base64) для каждой сущности, связанной с данными.
в - entitiesByName метод на NSManagedObjectModel полезен для сброса сущностей и хэшей, которые существуют в определенной модели.
у меня была похожая проблема. Я использовал +modelByMergeingModels:
, но я не использовал модель отображения. Однако объединение моделей не работает с упрощенной миграцией данных.
из документов Apple:
для выполнения автоматической легкой миграции, основные данные должны быть в состоянии найти источник и назначения управляемого объекта модельs сам во время.
если вы используете +modelByMergeingModels:
чем это используется для модель назначения. Однако основные данные не смогут найти исходную модель. Модель была создана с использованием +modelByMergeingModels:
в старой версии приложения и основных данных пытается объединить модели, чтобы узнать исходную модель.
то, что я закончил, это то, что я (вручную) создал новый объединенный .xcdatamodeld
путем редактирования XML-файлов моделей, добавил его в проект, удалил отдельный .xcdatamodeld
s из источников компиляции и вместо использования +modelByMergeingModels:
использовать NSManagedObjectModel
' s -initWithContentsOfURL:
с URL-адресом новой объединенной модели. Вероятно, я создам сценарий, который автоматически объединит модели в будущем.