Comments 25
Принцип работы прост: в базе хранится имя последней миграции и при запуске команды будут применены все миграции которые «больше» ее в порядке natsort(), то есть если у нас есть файлы 1.sql, 2.sql… 22.sql, a последняя в базе 13.sql то выполнятся все от 14 до 22, и затем в базе сохранится 22 как имя последней.
При разработке с использованием веток будут проблемы. К примеру: создали ветку в ней миграцию 1. Чуть позже создали ветку с миграцией 2, которую смёржили в стабильную ветку и выкатили. Т.о. в базе записано, что последняя миграция это 2. Когда будет смёржена первая ветка миграция 1 не будет накачена т.к. она меньше 2.
Закиньте коммент еще раз и я в этот раз нажму правильную кнопку
Нашел в мейле:
Так а если сделать просто проверку миграций что есть в базе и что есть на текущий момент в файлах?
Два разработчика ответвились от ветки где последняя миграция Version20150527081937. Первый генерирует миграцию, номер у нее будет Version20160627081937, второй Version20160528081937. Вначале вливаются изменения первого, и теперь номер миграции выше чем у второго. Получается она не применится? В обоих миграциях создания не связанных друг с другом таблиц
Мне кажется это не совсем верный подход, хорошо если делаешь два мержа один за другим, и можешь посмотреть и соотнести последовательность миграций, а когда делаешь мержи через несколько дней и/или несколько мержей в течении дня. У меня не так много опыта, но уже даволно часто приходилось встречаться, когда фича могла висеть долгое время, до вливания ее в мастер. а тут получается нужно будет переименовать файлы миграций, перед тем как что-то влить, и при том делать это постоянно, чтобы быть уверенным что миграция будет выполнена
А — накатываются все миграции, которых не было
Б — накатываются миграции, которые свежее последней
1. Человек не думает:
А — обычно ничего не произойдет, максимум, миграция не сработает, т.к. будут конфликт из-за другой миграции (поле уже есть, такая таблица уже создана и т.п.)
Б — код не работает, т.к. нет необходимых таблиц, полей и т.п.
2. Человек подумал:
А — запустил миграции, все ок
Б — переименовал миграции в особом порядке, запустил, все ок.
Итог — в случае Б вероятность все сломать, когда не думаешь выше, когда думаешь, надо выполнять лишние действия.
1. Тестирование ветки на тестовом.
2. При успешном тестировании мержер мержит ветку задачи в мастер локально.
3. Выполняются миграции локально у мержера, если идут какие-то ошибки в локальных миграциях, то решается вопрос с разрабами или силами мержера.
4. Если локально у мержера все ок в мастере, то результаты мержа выкладываются в репу, выливаются на прод, запускаются миграции (скрипт миграций всегда запускается автоматом при пуле мастера на проде, дальше скрипт сам решает есть что выполнять или нет).
2.2. Смотрит, были ли файлы миграций в сливаемой ветке
2.3. Если были, то смотрит, какие у них даты и сравнивает с последним числом в базе.
2.4. Если последняя миграция свежее тех, что в ветке, то переименовывает файлы миграций из ветки, делает еще коммит в мастер с переименованием миграций.
Только после этого выполняется шаг 3.
Потенциально на этих шагах может возникнуть проблема, когда недосмотрел даты, что-то упустил, тогда именно на проде миграции не сработают и ой, хотя на тестовом все было ок.
В моих комментах выше подразумевается Laravel, насколько я понимаю аналогично с Yii.
Как ниже ответил Zhuravljov, проблемы из-за разной последовательности случаются редко, да и их будет видно у мерджера локально при запуске миграций.
А почему бы и нет?
На основе списка всех миграций и истории с примененными выявляем новые миграции, и их применяем. Порядок применения, в этом случае, критически важен только для новых, потому что они обновляют структуру БД для одной фичи из одной и той же ветки.
Коллизии возможны, но встречаются крайне редко, если разработчики в разных ветках обновляли одни и те же таблицы.
Именно так миграции работают в Yii, и пока связанных с этим проблем при командной разработке не наблюдал.
Кроме того, при этом кейсе, допустимо подтягивать и применять миграции из сторонних модулей, которые могу дополнить общую структуру БД своими таблицами и связями.
Тогда получается проблема где две базы з тем же списком выполненных миграций могут находится в абсолютно разных состояниях:
1.sql: CREATE TABLE IF NOT EXISTS fairies(id int);
2.sql: DROP TABLE IF EXISTS fairies;
Очевидно что легко можно получить 2 разных состояния при том же списке миграций но в разном порядке. Пикся же всегда делала упор на строгость.
Да и опять же, с какой стати такая ситуация возникнет, что в одной ветке таблицу только создают — это ок, в другой только ее удаляют — эта ветка уже будет зависеть от предыдущей.
Для строгости стоит выбросить IF [NOT] EXISTS
. Тогда, вместо того, чтобы ничего не сделать и слиться по тихому, миграция отвалится с ошибкой. Это и будет сигналом о том, что что-то не так. Но, повторюсь, такое бывает крайне редко. В разных ветках под разные фичи, обновляются разные сущности.
1. Назначение на 1 поле разных дефолтных значений.
2. Расширение значений 1 и того же поля типа enum.
+ 3. Изменение типа поля — тут совпадение почти невероятно.
2-й случай скорее всего вызовет ошибку независимо от последовательности миграций, т.к. 1 разработчику надо дописать 1 значение, другому — другое. В данном случае последовательность миграций только повлияет на то, у какого пользователя код неверно отработает (у того, чья миграция была выполнена раньеш).
По поводу первого случая — тут да — надо следить, но это довольно редкий случай и следить довольно просто — просто смотреть есть ли установка дефолтного значения, если есть то глянуть, к чему может привести.
Если же скрипт будет пропускать миграции, то в случае с 2+ разработчиками придется всегда смотреть, все ли миграции в верной последовательности. В случае с 3+ разработчиками, насколько я представляю, приблизительно в каждом 3-м мерже придется переименовывать миграции для применения верной последовательности.
Такие коллизии возможны, но это случается редко. Как правило, в разных ветках идет работа над разными фичами, и разработчики меняют разные части базы данных. Главное чтобы после того, как миграцию накатили, в историю она сохранялась в порядке применения а не в порядке того, как она была создана, чтобы гарантировать последовательный откат. И, да, перед применением в боевом окружении нужно проверить что все накатывается без ошибок.
Простые миграции с PHPixie Migrate