Подтвердить что ты не робот

Как пакет может предоставить "данные по умолчанию", то есть предварительно заполненные таблицы в Symfony 2?

Я думаю, что я хорошо разбираюсь в Symfony и как работает пакет.

Однако я никогда не нашел, как решить простую проблему: сделать многоразовый пакет, который предоставляет данные, такие как таблицы/объекты доктрины, заполненные (т.е.) имена всех стран мира, всех провинций Италии, история ставок налогов в Англии и т.д.

Конечно, целью является предоставление форм, сервисов и контроллеров, основанных на этом источнике данных, без необходимости копировать и вставлять таблицы и объекты в проекты.

Как вы это сделаете?

Data fixtures IMHO не являются опцией, потому что очевидная причина: вы собираетесь очистить свою базу данных во время ее работы.

Пользовательская команда чтения из статического источника данных (json, YAML) и выполнения вставок/обновлений?

4b9b3361

Ответ 1

Первый шаг - объявление объекта Doctrine в вашем Bundle. Я думаю, вы должны создать DataFixtures, чтобы заполнить ваши данные в db.

Возможно, вам стоит рассмотреть возможность использования семян вместо светильников.

Светильники - это поддельные данные, используемые для тестирования вашего приложения.

Семена - это минимальные данные, необходимые для работы вашего приложения.

Технически, это точно то же самое, вы объявляете его в папке "DataFixtures/", и вы импортируете их с помощью команды "doctrine: fixtures: load".

Вы можете создать папку "Светильники/" и папку "Семена/" в папке "DataFixtures", затем загрузите семена с помощью команды

php app/console doctrine:fixtures:load --fixtures=/path/to/seeds/folder --append

В комментариях было высказано мнение, что может быть безопаснее, особенно в производственной среде, создать пользовательскую команду Symfony2 для принудительного использования режима "--append". Без этого режима ваша база данных будет очищена, и вы можете потерять свои производственные данные.

Ответ 2

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

Что вы можете сделать, это сделать экспорт SQL из данных, которые вы хотите, и убедиться, что он использует INSERT IGNORE INTO и получить правильные уникальные ограничения.

Затем вы сохраняете этот файл где-то в своем комплекте, в папке "данные" или "светильники". поэтому ваш путь к этому файлу будет следующим: "Поставщик/компания/epicbundle/данные/countries.sql"

Что вы тогда можете сделать, это добавить команды post-insert и post-update в ваш composer.json, который выглядит следующим образом:

"post-install-cmd": [
    "php app/console doctrine:query:sql \"$(cat vendor/company/epicbundle/data/countries.sql)\""
]

Если вы хотите, чтобы он запускался при установке, вы добавляете его только там, если вы иногда обновляете файл sql, вы также добавляете его в post-update-cmd.

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

Если вы хотите получить более экономичное/стабильное решение, вы можете написать свой собственный пост-install script в Symfony, который использует диспетчер сущностей, и там вы можете использовать, например, файл csv, и вставить/обновить его строка за строкой.

Ответ 3

В принципе, все, что вы могли бы реализовать, наверняка будет полагаться на механизмы сохранения, используемые в вашем ORM/ODM/независимо. Таким образом, вы в конечном итоге реализуете типичный механизм загрузки устройства, по крайней мере частично: вы должны выполнить код, который сохраняет некоторые предоставленные данные; если он сериализован, вы будете обрабатывать XML/JSON/YAML (но это всего лишь техничность) и сохраняйте результаты в базе данных.

Таким образом, неплохо придерживаться инструментов Doctrine Fixtures. Они программируются и расширяемы (вы даже можете получать данные из Интернета при загрузке).

Как указано в ответе @paul-andrieux, если вас беспокоит потеря данных (например, семена вашего пакета загружаются, когда конечная пользовательская БД уже вставлена), вы должны использовать doctrine:fixtures:load --append и позволить ограничениям выполнять свою работу ( например, в таблице имен стран у вас будет уникальное ограничение на название страны или даже "слизняк" ), чтобы вставлять повторяющиеся строки без малейших сбоев при вставке одного объекта, если ваш пакет обновил список стран и конец у пользователя была предыдущая версия.

Если вы действительно беспокоитесь о данных своих конечных пользователей, вы можете написать обертку для команды doctrine:fixtures:load, которая всегда включала бы флаг --append и регистрировала бы его как отдельную команду. (Вы также можете запускать необходимые миграции)

@lxg проблема с жестко запрограммированными идентификаторами также разрешима. Попробуйте использовать естественные ключи, где это применимо (например, таблица countries имела бы первичный ключ slug, который был бы great-britain для Grean Britain), Таким образом, поиск будет довольно простым: $em->find('\MyBundle\Country', 'great-britain');. Если вы не можете создать естественный ключ, то, возможно, сущность не нужна конечному пользователю.

UPD. Вот статья, которая может быть полезна: http://www.craftitonline.com/2014/09/doctrine-migrations-with-schema-api-without-symfony-symfony-cmf-seobundle-sylius-example/

Ответ 4

В общем случае пучок встраивал объекты, которые будут загружаться через ORM/ODM, используя свои встроенные команды (например, doctrine:schema:update, doctrine:migration:diff,...) и предоставляет пользовательскую команду, которая загружает необходимые приборы используя ODM/ORM

Эта команда может считывать приборы несколькими способами (разбор yaml, xml, raw sql, dql,...), это просто вопрос вкуса. Для этих задач существуют тональные пакеты, парсер,...

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