Как сделать обратно совместимую миграцию базы данных при добавлении и удалении колонок?
Что проверяют
Понимаете ли вы, что при rolling-деплое старая и новая версии приложения какое-то время работают с одной схемой, и миграция должна подходить обеим. Следом обычно просят разобрать переименование колонки и объяснить, как вы откатите релиз.
Как отвечать
Основной приём это expand/contract: сначала расширяем схему так, чтобы старый код её не заметил, потом переводим код, и только в последнюю очередь убираем лишнее.
- добавление колонки: колонка nullable или со значением по умолчанию. Старый код её не знает и при
INSERTне заполняет, поэтомуNOT NULLбез дефолта сломает его сразу. EF Core читает только колонки из своей модели, так что старая версия приложения лишнюю колонку проигнорирует; - удаление колонки: в несколько релизов. Если колонка обязательная, её делают nullable или дают дефолт. Затем выпускают код, который её больше не читает и не пишет, и ждут, пока он развернётся везде. Только следующей миграцией, когда старых инстансов не осталось, выполняется
DropColumn; - переименование: как добавление плюс удаление. Новая колонка, запись в обе, перенос данных пачками, переключение чтения, затем удаление старой.
RenameColumnв одном релизе ломает работающую версию; - применение: в многоинстансном окружении миграции гоняют отдельным шагом конвейера, через
dotnet ef migrations script --idempotentили migration bundle, а не вызовомDatabase.Migrate()на старте каждого инстанса.
Про откат скажите честно: метод Down у DropColumn вернёт колонку, но не данные. Поэтому на проде откатывают код, а не схему, и совместимость схемы с предыдущей версией как раз это и обеспечивает.
Где спотыкаются
Удаляют свойство из модели и сразу применяют сгенерированную миграцию. EF Core кладёт DropColumn в тот же релиз, и старые инстансы начинают падать на запросах. Предупреждение о потере данных при генерации многие пропускают.
Добавляют NOT NULL колонку на большую таблицу и заполняют её одним UPDATE на всю таблицу. Строки долго блокируются, а миграция не укладывается в окно деплоя.
Считают, что Down это план отката. Её почти никогда не запускают на проде, а проверять стоит сценарий «новая схема, старый код».