Skip to content

Latest commit

 

History

History
97 lines (56 loc) · 10.4 KB

README-ru.md

File metadata and controls

97 lines (56 loc) · 10.4 KB

Gorm Migrator

Russian | English

Мигратор используется для создания и применения/отмены миграций. В своей работе использует Gorm.

Добавление в проект

  1. Мигратор копируется в качестве утилиты в проект. Как правило в поддиректорию cmd/migrate.
  2. В файле migrate.go необходимо настроить пути импорта (заменить в двух местах project на название директории проекта).
  3. Ожидается, что импортируемый пакет 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 .

В созданном только что файле миграции необходимо сделать следующее:

  1. Определить для миграции тип разрушения (по умолчанию миграция является неразрушающей - DestructiveNo). Если миграция разрушает данные только при применении, то ей нужно присвоить тип DestructiveUp, если при откате - DestructiveDown (в большинстве случаев), если и в ту, и в другую сторону - DestructiveFully.
  2. Заменить заглушку в методе Up на настоящую реализацию. Этот метод вызывается, когда миграция применяется. Всё взаимодействие с БД следует производить с помощью gorm, используя экземпляр транзакции, передаваемый в метод Up в переменной tx .
  3. Заменить заглушку в методе 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.

License

Этот проект доступен по лицензии MIT. Смотри файл LICENSE для получения дополнительной информации.