Как лучше всего организовать использование фикстур при наличии большого объема данных?

Здравствуйте! Я сейчас работаю над переписыванием старого desktop-legacy приложения на Symfony и столкнулся с некоторыми трудностями. В старом проекте находятся справочники, которые хранятся в нескольких таблицах базы данных в формате <code>nomer_spravochnika, code, value</code>. В этом приложении отсутствует контроль целостности данных, и логика обработки и хранения данных распределена как между кодом приложения, так и в самой базе данных (через триггеры и процедуры).

В новом проекте я решил вынести каждый справочник в отдельную таблицу. На данный момент их более 200, и количество записей в каждой таблице варьируется от нескольких десятков до нескольких тысяч. Я экспортировал данные из этих справочных таблиц в CSV файл, который загружаю во время миграций. Для тестирования отдельных модулей планирую использовать загрузку фикстур в базу данных с помощью DoctrineFixturesBundle и <a href="https://github.com/zenstruck/foundry" rel="nofollow">zenstruck/foundry</a>. Однако мне необходимо иметь корректные данные для справочников, поскольку бизнес-логика (включая правила валидации) опирается на конкретные значения из этих таблиц.

У меня возникли несколько вопросов, и я был бы признателен за советы, чтобы лучше организовать свои мысли:
  • 16 сентября 2024 г. 8:43
Ответы на вопрос 2
Здравствуйте! Понимаю ваши затруднения, когда речь идет о реализации справочников и их фикстур в новом проекте на Symfony. Вот несколько советов, которые могут помочь вам организовать использование фикстур при наличии большого объема данных:

### 1. Структурированная организация фикстур

- **Разделение на файлы**: Создайте отдельные файлы фикстур для каждого справочника, чтобы избежать беспорядка и упростить поддержку. Например, `Fixture/DirectorateFixtures.php`, `Fixture/ProductTypeFixtures.php` и так далее.
  
- **Использование CSV файлов**: Если объем данных велик, можно рассмотреть возможность использования CSV или другого формата для хранения данных и загрузки их в базе данных через фикстуры. Это позволит легче поддерживать данные вне кода и обновлять их при необходимости.

### 2. Обработка большого объема данных

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

- **Генерация фикстур из базы данных**: Если средства позволяют, возможно, стоит создать скрипт, который будет автоматически генерировать фикстуры на основе существующих данных из старой базы. Это упростит процесс создания корректных фикстур.

### 3. Использование Foundry

- **Настройка начальных значений**: Используйте Foundry для генерации тестовых данных, которые будут использоваться в тестах. Определите необходимые зависимости, чтобы тестируемые сущности имели доступ к корректным данным.

- **Правила валидции**: Убедитесь, что ваши фабрики в Foundry включают правила валидации, чтобы генерируемые данные соответствовали бизнес-логике и валидировались так же, как и в реальном приложении.

### 4. Согласованность данных

- **Проверка целостности данных**: Важно, чтобы фикстуры и тестовые данные были согласованы с бизнес-правилами вашего приложения. Создайте набор тестов, которые помогут проверить корректность загруженных данных и их соответствие ожиданиям.

### 5. Документация и поддержка

- **Хорошая документация**: Документируйте структуру своих данных и их взаимосвязи. Это поможет вашей команде быстрее понимать архитектуру проекта и требования к данным.

- **Обновление данных**: Создайте процесс для периодического обновления фикстур, особенно если данные в реальности изменяются или если вы внедряете новыеbusiness требование.

### 6. Интеграционные тесты

- **Создание интеграционных тестов**: Разработайте интеграционные тесты, которые будут использовать загруженные фикстуры и проверять, правильно ли бизнес-логика вашего приложения работает с этими данными.

Следуя этим шагам, вы сможете организовать использование фикстур более эффективно, а также обеспечить целостность и корректность ваших данных. Успехов в разработке!
Пару лет назад столкнулся с похожей задачей, сидинг данных через миграции регулярно стрелял в ноги, и нужно было его вынести в отдельный функционал. Так и не понял почему DoctrineFixturesBundle продвигается как тула именно для тестирования, видимо неудачный нейминг оригинальной либы сыграл своё. 
В доке к оригинальной либе среди юзкейсов упоминается в том числе и сидинг вне контекста тестов.
Doctrine Data Fixtures

Но, проверять на живом проекте я так и не решился и набросал на коленке свой силдер с нужным мне функционалом из 2-3 классов.

Как при загрузке фикстур для свойств класса (ManyToOne) указать уже имеющиеся в БД данные?

Если используются кодогенирируемые уникальные идентификаторы - можно их прописывать в константы, и использовать при сидинге родительской сущности, а потом её же использовать при сидинге потомков.
Если таких нет - хранить в константах те поля по которым оригинальную сущность получится найти и получить идентификатор.
Похожие вопросы