Symfony 4: как безопасно «соединять» миграции вместе? / удалить миграции между первой и последней?

Недавно я настраивал свою БД и заметил, что сделал 5 миграций поверх существующих 2. Всего 7, m1, m2, ..., m7. Из этих 5 мне нужна только последняя версия. Поэтому я подумал, что могу удалить m3, m4, m5, m6, m7 и снова выполнить миграцию, в результате чего m3 уже содержит окончательную версию, которой я доволен. Теперь я никогда не делал этого раньше, и мне было интересно, какой самый безопасный способ сделать это?

Я использую PHPStorm. Могу ли я удалить их вручную (щелкните правой кнопкой мыши в PHPStorm, затем «Удалить»), а затем перейдите в командную строку и выполните php bin/console doctrine:migrations:migrate? Или мне нужно сделать php bin/console doctrine:schema:update? Или это действительно плохая идея?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
7
0
3 649
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

В целом да, вы можете. Но вы должны знать о том, что Doctrine/Migration сохраняет выполненные миграции в БД. Поэтому вам следует удалить ненужные файлы миграции (возможно объединить все запросы в один), после этого обновить базу данных.

Имя таблицы по умолчанию "доктрина_миграция_версия", просто удалите ненужные строки версии

-1 - Если вы удалите миграции где-то посередине, клонируете проект, а затем запускаете миграции, у вас будут плохие времена. Не делайте этого. Чтение принятый ответ вместо этого

rkeet 19.07.2019 15:11

Все в порядке. Но вопрос, как я понял, был «могу ли я удалить некоторые миграции в середине, если в последней миграции у меня есть все необходимые запросы». Так что ответ да.

Aleksei 21.07.2019 10:55

Все еще нет. Ради аргумента, пожалуйста, настройте случайный проект, создайте 3 миграции, каждая из которых создает таблицу (префикс fruit_*, таблицы «яблоки», «груши», «бананы» по порядку). Выполнение миграций. Создайте некоторую логику отображения индекса, чтобы показать их. Убрать миграцию "груши". Подтвердить репо. - Теперь клонируйте проект под новым именем (или другим компьютером, как угодно). Запустите миграции. Нет таблицы "fruit_pears" (и ошибок, если логика вашего приложения зависела/ожидалась от нее)... Итак, если вы не хотите смотреть в лицо музыке, ответ будет просто "нет".

rkeet 21.07.2019 15:00

Хорошо, ты выиграл. Но ключевое слово было "У меня есть все необходимые запросы".

Aleksei 22.07.2019 03:11
Ответ принят как подходящий

Нет, в общем, вы не должны делать ни того, ни другого. Позвольте мне начать с прояснения того, что кажется неправильным: миграция не содержит полной схемы базы данных, только запросы, необходимые для переноса базы данных из одной версии в другую. Эта система позволяет управлять изменениями базы данных и контролировать их версии. Таким образом, вы должны начать видеть некоторые проблемы с этим:

  • Миграция может зависеть от предыдущей. Например. v1 добавляет сущность, а v2 добавляет новое поле. Если вы удалите v1, v2 будет сломан, и его также необходимо удалить.
  • Поскольку миграция базы данных как правило идет рука об руку с изменением объектной модели, вам также придется отменить модель, иначе вы обнаружите проблемы с сопоставлением с несуществующими полями.

Это может быть приемлемо на этапе проектирования, когда у вас еще нет никаких функций. Вы можете отменить отдельную миграцию, используя bin/console doctrine:migrations:execute --down <version>. Обычно это делается во время тестирования изменений, если необходимо внести коррективы. Но обычно, когда это изменение еще не зафиксировано.

Doctrine отслеживает миграции с помощью таблицы базы данных под названием migration_versions. Называя их датой, он может упорядочивать их и применять последовательно. Всякий раз, когда миграция выполняется, она добавляет имя миграции в эту таблицу. При откате удаляет из таблицы вместе с полями в самой миграции. Имейте в виду, что даже если вы можете откатить миграцию, это не значит, что все будет так, как было. Если при миграции удаляется столбец, он будет воссоздан при откате, но данные будут потеряны.

Насчет "можно ли это сделать"? да. Если вы действительно очень хотите, внимательно прочитайте документация и осознайте все это.

Итак, поскольку ваш вопрос касается слияния миграций, давайте рассмотрим ваши фактические варианты:

  • Могу ли я удалить их вручную (щелкните правой кнопкой мыши в PHPStorm, затем «Удалить»), а затем перейдите в командную строку и выполните php bin/console doctrine:migrations:migrate?

Нет, это не сработает. migrate будут миграции применить доступный. Их не будет, и, как объяснено, ревизии все еще будут в таблице, и ее изменения будут применены.

  • Или мне нужно сделать php bin/console doctrine:schema:update?

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

В любом случае вам нужно будет сначала восстановить их, а затем создать эквивалентный. Команда для этого doctrine:migrations:diff. Это сравнит модель со схемой и сгенерирует миграцию для синхронизации базы данных. И чтобы это работало, вам нужно сначала execute --down выполнить миграции, иначе они не будут иметь никаких изменений, но могут привести к потере некоторых данных в процессе.

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

Вы также можете комбинировать миграции вручную. Это просто классы с методами up и down. Объедините все тела функций, примените процесс очистки и закройте его.

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

Если вы хотите сделать это:

  • Делайте резервные копии
  • Внесите свои изменения как можно раньше, чтобы избежать перерывов. Это нормально, если в базе данных какое-то время есть неиспользуемые поля, пока модель не наверстает упущенное. Если вы сделаете это поздно и это понадобится какому-то объекту, кто-то может быть вынужден создать миграцию и сломать вашу миграцию в процессе.
  • Сделать это правильно (желательно с первой попытки). Не настаивайте, пока не протестируете всесторонне.
  • Делайте резервные копии

Ссылка на консольные команды

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

Loenix 19.03.2021 12:23

Не существует «безопасного» способа сделать это, но если вы не развернули миграции, вы можете безопасно выбросить серию автоматически сгенерированных миграций и создать их заново. Просто будьте осторожны, чтобы не выбросить SQL ручной миграции одновременно.

Обычно на этапе проектирования мы:

  1. Используйте doctrine:schema:update --force, пока все не станет достаточно стабильным
  2. После того, как они станут стабильными, мы сбрасываем базу данных разработки из снапшота.
  3. Запустите doctrine:migrations:diff, а затем добавьте вручную запросы на миграцию, где это необходимо.

Будут ли корректно работать запросы, если, скажем, в миграции м3 я скажу создать пользовательскую таблицу, а потом скинуть в миграцию м5 или будет крах?

user8678484 19.07.2019 09:29

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

Ryan 23.07.2019 05:06

Возможно, вам нужно игнорировать все ваши миграции и сосредоточиться на последнем состоянии схемы базы данных. Если это то, что вы хотите получить в финале, вы можете просто нажать: php bin/console doctrine:schema:update --dump-sql, чтобы получить соответствующий оператор SQL, или нажмите php bin/console doctrine:schema:update --force, чтобы применить его к базе данных.

Другие вопросы по теме