Russian | English
Мигратор используется для создания и применения/отмены миграций. В своей работе использует Gorm.
- Мигратор копируется в качестве утилиты в проект. Как правило в поддиректорию
cmd/migrate
. - В файле
migrate.go
необходимо настроить пути импорта (заменить в двух местахproject
на название директории проекта). - Ожидается, что импортируемый пакет
models
экспортирует две функции:
// GetDB returns an instance of * gorm.DB
func GetDB() *gorm.DB
// GetDBType returns the type of the DBMS ("mysql" or "postgres") from config
func GetDBType() string
Мигратор в своей работе опирается на модель проекта, которая для подключения к БД использует конфиг. Поэтому запуск следует проводить из такого места, чтобы файл конфига был доступен.
Некоторые возможные варианты запуска мигратора (предполагается, что GOPATH
и прочее уже настроены):
- Файл
.env
расположен там же, где иmain.go
(package main). Тогда, находясь в этой директории, следует запустить командуgo run cmd/migrate/migrate.go -h
. - Файл
.env
уже расположен в директорииbin
. Можно собрать исполняемый файл с помощью командыgo install project/cmd/migrate
(project
необходимо заменить на соответствующее название директории проекта). После этого из директорииbin
можно запускать:./migrate -h
.
Далее в примерах для краткости вместо полной команды вроде go run cmd/migrate/migrate.go -h
будет использоваться сокращение migrate -h
.
Для создания миграций используется команда migrate --new
, в качестве параметра - название миграции. Если в названии миграции будут обнаружены пробелы, то они будут заменены на символ _
. Так, например, команда:
migrate --new "alter user table add age"
создаст в поддиректории мигратора файл с шаблоном миграции примерно такого вида: migrations/2020_11_05_150521_alter_user_table_add_age.go
.
В созданном только что файле миграции необходимо сделать следующее:
- Определить для миграции тип разрушения (по умолчанию миграция является неразрушающей -
DestructiveNo
). Если миграция разрушает данные только при применении, то ей нужно присвоить типDestructiveUp
, если при откате -DestructiveDown
(в большинстве случаев), если и в ту, и в другую сторону -DestructiveFully
. - Заменить заглушку в методе
Up
на настоящую реализацию. Этот метод вызывается, когда миграция применяется. Всё взаимодействие с БД следует производить с помощьюgorm
, используя экземпляр транзакции, передаваемый в методUp
в переменнойtx
. - Заменить заглушку в методе
Down
на настоящую реализацию. Этот метод вызывается, когда миграция откатывается. Всё взаимодействие с БД следует производить с помощьюgorm
, используя экземпляр транзакции, передаваемый в методDown
в переменнойtx
.
Для просмотра списка миграций используется команда migrate --list
.
Вывод этой команды как правило разделен на две части: список примененных миграций (Implemented migrations) и список новых миграций (New migrations).
В списке примененных миграций они могут быть:
- зеленого цвета - миграция была успешно применена, код миграции в наличии;
- красного цвета - миграция была успешно применена, но код миграции не найден, поэтому откатить такую миграцию нельзя.
Примененные миграции разделяются на блоки (с помощью пустых строк). Каждый блок миграций был выполнен одной командой.
В списке новых миграций они могут быть:
- синего цвета - миграция, дата создания которой располагается после даты создания последней выполненной миграции;
- желтого цвета - миграция с нарушенной хронологией выполнения (существуют применные миграции с более поздней датой создания), существует вероятность, что при применении такой миграции могут произойти ошибки (как правило нет).
Для применения миграций используется команда migrate --up
. Будут применены все новые миграции. Если требуется применить только одну миграцию, то следует добавить флаг --one
- будет применена только первая миграция из списка новых миграций.
Для отмены миграций используется команда migrate --down
. Будут отменены все миграции последнего блока примененных миграций. Если требуется отменить только одну (последнюю) миграцию, то следует добавить флаг --one
- будет отменена только последняя миграция из списка примененных миграций.
Если при применении/откате миграций встретится разрушающая в данном направлении миграция, то выполнение будет остановлено. Чтобы выполнить миграцию, разрушающую данные, нужно к команде добавить флаг --force
.
В случае деплоя на инсталяцию с несколькими серверами может возникнуть проблема с параллельным запуском миграторов, которые будут друг другу мешать (в т.ч. и потому, что будут иметь одинаковый список миграций к выполнению).
Если деплой происходит на AWS с использованием сервиса CodeDeploy, то можно использовать флаг --deploy
, который не позволит мигратору произвести более одной попытки применения новых миграций в рамках одного развертывания.
По умолчанию мигратор выполняет каждую миграцию в своей транзакции. Отрицательная сторона такого выполнения - если в выполняемом блоке миграции возникнет ошибка, то будет откачена только текущая миграция, ранее выполненные миграции в этом блоке останутся примененными. Для изменения этого поведения существует флаг -s
- в этом случае блок новых миграций будет выполняться в единой транзакции, если в процессе возникнет ошибка, то будут откачен весь блок миграций.
Пользоваться данной возможностью следует с осторожностью, т.к. выполнение разных операций, работающих с одними и теми же объектами в БД, в одной транзакции в gorm работает странно (завершается с ошибкой).
Этот проект принадлежит и поддерживается Rosberry. Мы создаем мобильные приложения для пользователей по всему миру 🌏.
Ознакомьтесь с нашими open source проектами, читайте наш блог или дайте нам пять на 🐦 @rosberryapps.
Этот проект доступен по лицензии MIT. Смотри файл LICENSE для получения дополнительной информации.