Как мне создать базу данных sqlite для использования с Core Data? - PullRequest
5 голосов
/ 13 декабря 2011

Моя цель - создать базу данных sqlite и заполнить ее данными (возможно, 1000+ строк) и использовать эту базу данных для предварительной загрузки основных данных и заполнения табличного представления.

Пока у меня есть табличное представление, работающее с Базовыми данными, Модели управляемых объектов.Я могу добавлять элементы и удалять элементы - в основном у меня есть шаблон Master-Detail, работающий с моей собственной моделью.

Вопрос: Как мне создать базу данных sqlite в правильном формате для использования с Core Data?

Я успешно сделал это, используя предоставленные базы данных SQL и учебные пособия из книг.Что я заметил, так это то, что таблица 'fugitive' (например) в моем уроке написана как "ZFUGITIVE" в предоставленной базе данных sqlite.У всех его столбцов есть «Z», добавленный в начало («ZFUGITIVEID», «ZNAME» ...), и существует три дополнительных столбца («Z_PK», «Z_ENT», «Z_OPT»), которые не включены в управляемыйобъектная модель (.xcdatamodeld).Кроме 'Z' всех имен заглавных букв и дополнительных столбцов я также вижу (в этом .sqlite db, который идет с учебником), что есть две дополнительные таблицы "Z_PRIMARYKEY" и "Z_METADATA".

Я знаком сКоманды терминала sqlite и могут создавать базу данных, но не имеют правильного форматирования, лишних строк или дополнительных таблиц с метаданными.В качестве эксперимента я использовал приведенную выше таблицу базы данных Fugitive sqlite и добавил в нее еще одну таблицу.Сначала я назвал это таблицей 'вещь' со столбцами 'thingID' и 'title'.Я создал для него управляемый объект и подключил его к своему табличному представлению.Я не мог на всю жизнь получить данные для предварительной загрузки в базовые данные / представление моей таблицы.Я не получил сообщений об ошибках, он просто не загружал данные заранее (он позволял мне добавлять и удалять новые элементы, как шаблон Master-Detail).

Поэтому я переименовал таблицу 'thing' в 'ZTHING'со столбцами ('Z_PK', 'Z_ENT', 'Z_OPT', 'ZTHINGID' и 'ZTITLE'), и теперь я получаю следующее сообщение об ошибке. Я знаю, что это говорит мне о том, что я создал свою таблицу неправильно, однако я не могу найти документацию о том, как правильно ее создать.Пожалуйста, помогите.

Вот большая ошибка гудка, которая в основном утверждает, что номер версии, записанный в таблице Z_METADATA (столбец Z_UUID), неверен: [Или я так думаю]

Unresolved error Error Domain=NSCocoaErrorDomain Code=134100 "The operation couldn’t be completed. (Cocoa error 134100.)" UserInfo=0x5b489c0 {metadata=<CFBasicHash 0x5b4e960 [0x2651380]>{type = immutable dict, count = 7,
entries =>
    2 : <CFString 0x5b4ea40 [0x2651380]>{contents = "NSStoreModelVersionIdentifiers"} = <CFArray 0x5b4eb10 [0x2651380]>{type = immutable, count = 0, values = ()}
    4 : <CFString 0x5b4ea90 [0x2651380]>{contents = "NSPersistenceFrameworkVersion"} = <CFNumber 0x5b4e530 [0x2651380]>{value = +248, type = kCFNumberSInt64Type}
    6 : <CFString 0x5b4eac0 [0x2651380]>{contents = "NSStoreModelVersionHashes"} = <CFBasicHash 0x5b4eba0 [0x2651380]>{type = immutable dict, count = 1,
entries =>
    1 : <CFString 0x5b4eb30 [0x2651380]>{contents = "Fugitive"} = <CFData 0x5b4eb50 [0x2651380]>{length = 32, capacity = 32, bytes = 0xe33370b6e7ca3101f91d25951e8bfe01 ... 9e50237bb313d390}
}

    7 : <CFString 0x1ee464 [0x2651380]>{contents = "NSStoreUUID"} = <CFString 0x5b4e850 [0x2651380]>{contents = "E711F65F-3C5A-4889-872B-6541E4B2863A"}
    8 : <CFString 0x1ee324 [0x2651380]>{contents = "NSStoreType"} = <CFString 0x1ee2e4 [0x2651380]>{contents = "SQLite"}
    9 : <CFString 0x5b4ea10 [0x2651380]>{contents = "NSStoreModelVersionHashesVersion"} = <CFNumber 0x5d0b520 [0x2651380]>{value = +3, type = kCFNumberSInt32Type}
    10 : <CFString 0x5b4eaf0 [0x2651380]>{contents = "_NSAutoVacuumLevel"} = <CFString 0x5b4ebf0 [0x2651380]>{contents = "2"}
}
, reason=The model used to open the store is incompatible with the one used to create the store}, {
    metadata =     {
        NSPersistenceFrameworkVersion = 248;
        NSStoreModelVersionHashes =         {
            Fugitive = <e33370b6 e7ca3101 f91d2595 1e8bfe01 3e7fb4de 6ef2a31d 9e50237b b313d390>;
        };
        NSStoreModelVersionHashesVersion = 3;
        NSStoreModelVersionIdentifiers =         (
        );
        NSStoreType = SQLite;
        NSStoreUUID = "E711F65F-3C5A-4889-872B-6541E4B2863A";
        "_NSAutoVacuumLevel" = 2;
    };
    reason = "The model used to open the store is incompatible with the one used to create the store";
}

Большое спасибо за всю помощь, которую вы можете оказать мне

Ответы [ 4 ]

14 голосов
/ 15 декабря 2011

ОК, поэтому я согласен с приведенными выше комментариями. Используйте Core Data для создания базы данных SQL. Если вы изменяете базу данных напрямую, все ставки отключаются с точки зрения того, что Apple может сделать с форматом; Тем не менее, Apple должна обеспечить обратную совместимость с Базовыми данными, поэтому их API ДОЛЖНЫ пересылать все, что находится в любом действительном недавнем формате.

Итак, чтобы ответить на ваш вопрос с реальной информацией (это верно по состоянию на декабрь 2011 г. и iOS 4), вот метод, который будет работать:

  1. Для начала создайте базу данных. Это ваш шаблон, который будет содержать правильные метаданные и свойства. Вы никогда не должны использовать DML для этого (не изменять таблицы и т. Д.).

  2. Столбец Z_ENT - это идентификатор объекта, используемый для отслеживания первичного ключа объекта в таблице ZPRIMARYKEY. Если вы изучите таблицу первичных ключей, она отслеживает максимальный идентификатор, уже используемый для каждого объекта (для генерации Z_ID). Он также отслеживает наследование, поскольку базовые данные используют одну таблицу для всех классов, которые имеют отношение наследования. Например. Менеджер является подклассом Сотрудника. Будет одна таблица (zemployee), а для таблицы первичного ключа будет установлено значение Z_SUPER, указывающее на реальную строку, которая отслеживает идентификаторы для таблицы. Если у вас есть подклассы, то Z_ENT укажет правильный тип для этой строки. Например. если Employee равен 1, а Manager равен 2 в ZPRIMARYKEY, то в ZEMPLOYEE будут строки с Z_ENT, равными 1 и 2.

  3. Столбец Z_OPT - это число раз, в которое строка была записана (включая вставку ... поэтому она начинается с 1). Он почти наверняка используется для согласованности (например, оптимистическая обработка параллельных транзакций). В любом случае, вы должны увеличивать его при записи в строку.

Конечно, вы также должны обновлять поле MAX в таблице первичного ключа. Убедитесь, что вы выполняете вставку и обновление таблицы PK вместе в транзакциях, чтобы не повредить вещи!

И, наконец, конечно, вы не должны делать это в первую очередь:)

Мне нужно было это знать, потому что мне нужен не синхронизирующий OSX сервер для работы с файлами, сгенерированными данными ядра ... и поэтому я не могу напрямую использовать API данных ядра.

Обновление: сентябрь 2012

Краткое примечание о наследовании. Если у вас есть отношения FK от подклассов в вашей базовой модели данных, Core Data использует модель наследования одной таблицы (посмотрите в документации по Hibernate, чтобы лучше понять, что происходит). В одной таблице Z_ENT будет установлен правильный тип класса, а внешним ключам может потребоваться более одного столбца для обработки альтернатив, присутствующих в классах. Лучше всего убедиться, что вы получаете это право, - создать небольшой набор данных в Objective-C с экземплярами каждого класса, а затем вывести данные с помощью sqlite3 из командной строки. Будет очевидно, какой тип данных использует какие столбцы.

5 голосов
/ 29 ноября 2012

Вот как я это делаю

  1. Создайте свою базу данных в любой СУБД, которую вы хотите (я использую MySQL)
  2. Создайте свою сущность в Core Data, убедитесь, что вы запускаете своюприложение хотя бы один раз, поэтому таблицы создаются
  3. Экспорт данных с использованием CSV
  4. Импорт их в Excel (да, Excel - я никогда не думал, что Excel будет так полезен в такой задаче)
  5. Измените имена столбцов в Excel, чтобы они соответствовали версиям Core Data (вы можете проверить файл базы данных, чтобы узнать имена столбцов, используя СУБД SQLite. Я использую плагин Firefox с именем SQLite Manager. Файл базы данных находится в Library /Поддержка приложений / iPhone Simulator / версия / ID приложения / Documents / file_name.sqlite) Но примерно у вас есть Z_PK, Z_ENT и Z_OPT в каждой таблице в качестве первых столбцов.Затем у вас есть собственные столбцы, заглавные буквы и Z.Таким образом, col1 будет ZCOL1
  6. Добавить столбцы Z_ENT и Z_OPT.Установите Z_OPT в 1, установите Z_ENT в значение, указанное в таблице Z_PRIMARYKEY.(Z_PK автоматически добавляется во время импорта, поэтому вам не нужно делать это вручную)
  7. Экспорт CSV из Excel
  8. Импортируйте этот файл CSV в файл базы данных (как указано в шаге 5), используяваша СУБД SQLite.

Надеюсь, это поможет

5 голосов
/ 13 декабря 2011

Вы не можете найти документацию о том, как правильно ее создать, потому что с точки зрения Apple вы не должны создавать ее самостоятельно.Если вам нужна базовая модель данных, вы должны использовать базовые данные для создания таблиц, а не создавать ее самостоятельно.

Если вы хотите предварительно заполнить таблицу данными, вы можете сделать это, написав код длятак.Этот код может выполняться либо в коде запуска вашего приложения, либо вы можете написать отдельное автономное приложение для заполнения базы данных в файловой системе, а затем импортировать этот файл базы данных в ваш «реальный» проект.

Однакоподходя к этому, вы должны предположить, что использование основных данных с хранилищем постоянства SQlite означает, что вы должны позволить основным данным позаботиться о создании таблицы.Если вы хотите написать приложение на основе SQlite, вы можете это сделать, но Core Data не является для вас решением.

2 голосов
/ 13 декабря 2011

Я бы написал приложение для командной строки рабочего стола, которое использует базовые данные (и ту же модель, что и ваше телефонное приложение) и заполняет постоянное хранилище базовых данных, а затем добавил файлы в ваше приложение iOS ...

... или создайте другую цель в вашем приложении iOS, чтобы сделать это (вы можете запустить ее на устройстве, если обнаружите какие-либо проблемы с порядком байтов, но у вас не будет командной строки, просто вставьте из кода).

...