Comments 7
А мы обычно так делаем
Добавляем поля, nullable или со значением по умолчанию
Релизим код который одновременно пишет в новые и старые поля, но читает только старые
Копируем данные
Релизим код который читает новые поля
Проверяем, что старые поля имеют значение по умолчанию или nullable
Если проблем нет, то релизим код который ничего уже не знает про старые поля
Удаляем старые поля
Мне кажется в статье не совсем правильно: переключатель должен включать запись новых, но не выключать запись старых.
Всю статью можно свернуть до 3 пункктов
Пишите данные и в новом формате и в старом
Скопируйте все старое в новое
Переключите чтение на новый формат
Переезд де факто завершен. Осталось только убрать за собой: Подождать недели две, отключить запись в старом формате и убрать за собой.
Если нужен замороченный flow с одновременной поддержкой старой и новой моделей:
создаете новую таблицу
мигрируете данные со старой
синхронизацию изменений реализуете при помощи триггеров
следующий апдейт дропает старую таблу и триггеры
хорошая статья
На мой взгляд сам сценарий выбран неверно (с точки зрения использования feature toggle)
я бы В ДАННОМ СЛУЧАЕ рассматривал процедуру создания новых полей в таблице БД и заполнение из данными как единую и неделимую процедуру миграции БД. Код соотвествующий изменениям в БД разворачивается как часто процедуры развертывания которая включает в себя процедуру миграции БД как необходимое условие развертывания (и эта процедура также должна включать и процедуру восстановления).
Разумеется конкретный сценарий зависит как от программной, так и от системной архитектуры, но это в принципе не важно - у вас монолит? ну значит у вас процедура обновления монолита (которая может включать множество подобных обновлений которые в числе прочего требуют несколько миграций БД). У вас микросервисная архитектура? ну значи у вас процедура которая просто разворачивает новые микросервисы и перенаправляет на них трафик. У вак кластер? ну значит у вас процедура последовательного обновления каждого узда при которой часть узлов становятся не функциональными после обновления БД и процедура развертывания должна это учитывать...
Flyway и Liquibase не могут в полной мере поддерживать подобные процедуры? ну тем хуже для Flyway и Liquibase - нужно делать какие-то надстройки (я лично тупо скрипты на питоне пишу. Да со стороны выглядит криво и.. часто неоправданно сложно. Но работает и главное работает всегда, хотя честно говоря может породить "незаменимых людей" в компании)
Сложно? ну.. да... а за что мы деньги получаем? Сдается мне, что не за обилие многочисленных if-else и множества вариантов классов реализующих лишь обновление существующего функционала (как много процдет времени когда весь продукт будет состоять преимущественно из этих If-Else и NewCustomer? И не надо про "это должно удаляться" - мало ли кто и кому должен - в реальном мире у нас есть клиенты которым нужно объяснить, что нам тут периодически нужно удалять ветвления и старые классы)
Но Feature Toggle (и продукты вроде LaunchDarkly) на мой взгляд это немного про другое... конкретно это про features
Нулевое время простоя при изменениях базы данных с помощью флагов функций — шаг за шагом