Базовая ошибка данных относится к несуществующему базовому атрибуту данных рефлексивного отношения «многие ко многим» - PullRequest
7 голосов
/ 22 сентября 2011

Я испытываю сбивающую с толку ошибку Базовых данных, в которой я получаю следующее сообщение об ошибке при попытке сохранить некоторые данные:

CoreData: error: (1) I/O error for database at /var/mobile/Applications/5D3C0F3C-E097-43BF-887B-2870B1148226/Documents/Database.sqlite.  SQLite error code:1, 'table Z_1RELATEDCARDS has no column named FOK_REFLEXIVE'

Core Data: annotation: -executeRequest: encountered exception = I/O error for database at /var/mobile/Applications/5D3C0F3C-E097-43BF-887B-2870B1148226/Documents/Database.sqlite.  SQLite error code:1, 'table Z_1RELATEDCARDS has no column named FOK_REFLEXIVE' with userInfo = {

    NSFilePath = "/var/mobile/Applications/5D3C0F3C-E097-43BF-887B-2870B1148226/Documents/Database.sqlite";

    NSSQLiteErrorDomain = 1;

}

Для некоторого контекста: в моей модели данных нет столбца «возвратный». У меня есть объект Cards, у которого есть атрибут relatedCards, представляющий собой отношение многие ко многим между элементами Card. Я совершенно сбит с толку относительно того, на что ссылается эта ошибка, и любая помощь будет принята с благодарностью.


UPDATE

Согласно замечательному предложению в комментариях, я запустил приложение в iOS Simulator с аргументом -com.apple.CoreData.SQLDebug 3 и получил следующий ответ:

CoreData: annotation: Connecting to sqlite database file at "/Users/jason/Library/Application Support/iPhone Simulator/5.0/Applications/4EE6D378-A946-4EBF-9849-F7D2E58F2776/Documents/Database.sqlite"
CoreData: sql: pragma cache_size=200
CoreData: sql: BEGIN EXCLUSIVE
CoreData: sql: UPDATE ZCARD SET ZDATEMODIFIED = ?, Z_OPT = ?  WHERE Z_PK = ? AND Z_OPT = ?
CoreData: details: SQLite bind[0] = "338478797.092588"
CoreData: details: SQLite bind[1] = (int64)7
CoreData: details: SQLite bind[2] = (int64)119
CoreData: details: SQLite bind[3] = (int64)6
CoreData: sql: UPDATE ZCARD SET ZDATEMODIFIED = ?, Z_OPT = ?  WHERE Z_PK = ? AND Z_OPT = ?
CoreData: details: SQLite bind[0] = "338478797.092577"
CoreData: details: SQLite bind[1] = (int64)7
CoreData: details: SQLite bind[2] = (int64)100
CoreData: details: SQLite bind[3] = (int64)6
CoreData: sql: INSERT OR REPLACE INTO Z_1RELATEDCARDS(Z_1RELATEDCARDS, REFLEXIVE, FOK_REFLEXIVE) VALUES (119, 100, 0)
CoreData: annotation: Disconnecting from sqlite database due to an error.
CoreData: error: (1) I/O error for database at /Users/jason/Library/Application Support/iPhone Simulator/5.0/Applications/4EE6D378-A946-4EBF-9849-F7D2E58F2776/Documents/Database.sqlite.  SQLite error code:1, 'table Z_1RELATEDCARDS has no column named FOK_REFLEXIVE'
[Switching to process 45402 thread 0x15503]

Для небольшого контекста я изменил таблицу карт, чтобы отслеживать, когда она изменяется. Это то, что происходит в верхней части вывода отладки. Однако ключевая строка в отладочном выводе явно четвертая снизу:

CoreData: sql: INSERT OR REPLACE INTO Z_1RELATEDCARDS(Z_1RELATEDCARDS, REFLEXIVE, FOK_REFLEXIVE) VALUES (119, 100, 0)

Я зашел в свою базу данных SQLite и проверил, нет ли в этой таблице столбца FOK_REFLEXIVE. Схема для этой таблицы:

CREATE TABLE Z_1RELATEDCARDS ( Z_1RELATEDCARDS INTEGER, REFLEXIVE INTEGER, PRIMARY KEY (Z_1RELATEDCARDS, REFLEXIVE) );

Ясно, что Core Data пытается вставить данные в несуществующее поле. Что мне с этим делать?

Обновление:

Это также проблема, о которой сообщили пользователи. Я не могу обновить свое приложение и просто говорю пользователям: «О, хорошо, вам нужно очистить хранилище данных и начать все сначала». К сожалению, это не очень хорошо пройдет, даже если бы это было причиной этой ошибки.

Ответы [ 3 ]

3 голосов
/ 25 сентября 2011

[Обновление: Судя по комментариям авторов к этому ответу, причина не в этом.Проблема затрагивает конечное использование, и он не изменяет файл sqlite.Я оставлю этот ответ здесь только для дальнейшего использования.--TechZen ]

Здесь reflex, вероятно, является рефлексивным соединением в SQL (также называемым самообъединением). REFLEXIVE в выводе SQLDebug, вероятно, являетсяКоманда для создания таблицы соединения или аналогичной конструкции.В этом случае ваша сущность карты, вероятно, имеет отношение к себе. Базовые данные используют рефлексивную связь sql для сохранения этой связи сущности.

Вы говорите, что:

Я изменил карточный стол, чтобы отслеживать, когда он был изменен…

… из которого я беру это, чтоВы изменили файл хранилища sqlite напрямую.Это обычно вызывает проблемы, включая коррупцию.Core Data использует собственную схему sql, которая не документирована.Любые изменения в нем или даже среда выполнения sqllite могут вызвать проблемы.

Я думаю, что наиболее вероятная проблема заключается в том, что файл хранилища поврежден.Вы очень редко получаете ошибки SQL из кода Objective C Core Data, и когда вы делаете, это почти всегда связано с предикатом, который не может выполнить SQL.

Начните заново с чистой версии вашей базы данных без каких-либо ошибок и посмотрите, работает ли она.

1 голос
/ 16 ноября 2012

Я только что столкнулся с этой проблемой.Это проблема для вас и ваших клиентов.Тем более, если ваше приложение на рынке.

Кажется, есть проблема с тем, как базовые данные псевдонимов связывают несколько отношений «многие ко многим», содержащихся в одном объекте.Посмотрите НА ЭТОМ ПОЧТЕ и ЭТО ОДИН КАК ХОРОШО .

Решение, указанное в первой гиперссылке, не решиломоя проблема.Для смягчения я создал контейнерную сущность, чтобы мои многие ко многим выглядели как многие ко многим.Но если наше приложение уже есть в продаже, вам необходимо выполнить миграцию, чтобы сохранить пользовательские данные.

Кажется, вы получаете свое исключение в начале.Если это не так, рассмотрите возможность фильтрации в памяти, если у вас возникнет ошибка в предикате, и вы не получите исключение для своей корневой сущности.

Также кажется, что это иногда проблема.У меня есть несколько сущностей, содержащих несколько отношений «многие ко многим».Был только один объект, который имел эту проблему.У проблемного объекта было два отношения «многие ко многим» и отношение «один к одному»;все из которых были необязательными.Правило удаления «один к одному» было каскадным, и то и другое для многих: nullify.

Другой объект, который не вызывает этой проблемы, имеет отношения:

  • 1 отношение один-ко-многим, необязательно, каскад
  • 2 отношения один-один, необязательно, каскад
  • 3 отношения «многие ко многим», необязательно, обнулять

Какая разница ???Я не уверен.Я испытываю желание создать контейнеры сущностей для этих многих для многих, чтобы избежать вашей проблемы.

0 голосов
/ 01 октября 2011

Я думаю, что это проблема из-за старого файла .sqlite,

Вам нужно удалить старый, перезагрузив устройство или симулятор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...