Концепции миграций#
RESTAlchemy использует явные файлы миграций для эволюции схемы базы данных.
Миграции располагаются в каталоге (например, examples/migrations/) и применяются с помощью CLI-инструментов: ra-new-migration, ra-apply-migration, ra-rollback-migration, ra-rename-migrations.
Файлы миграций#
Каждая миграция — это Python-файл с объектом migration_step:
from restalchemy.storage.sql import migrations
class MigrationStep(migrations.AbstractMigrationStep):
def __init__(self):
self._depends = ["<prev-migration-file>.py"]
@property
def migration_id(self):
return "<uuid>"
@property
def is_manual(self):
return False
def upgrade(self, session):
# Apply changes
pass
def downgrade(self, session):
# Revert changes
pass
migration_step = MigrationStep()
Шаблон для новых миграций находится в файле:
restalchemy/storage/sql/migration_templ.tmpl
и используется командой ra-new-migration.
Идентификаторы и зависимости миграций#
У каждой миграции есть:
- UUID (
migration_id). - Список зависимостей (
self._depends) — список имён файлов миграций. - Флаг ручной миграции (
is_manual).
Зависимости образуют ориентированный ацикличный граф. При применении миграции сначала применяются все её зависимости.
Специальные константы:
HEAD— обозначает "последнюю автоматическую миграцию".MANUAL— маркер, используемый в номерах файлов для ручных миграций.
MigrationEngine использует эти правила, чтобы:
- Разрешать частичное имя до полного имени файла.
- Вычислять head-миграцию.
- Проверять, что автоматические миграции не зависят от ручных (в
ra-new-migrationбез--manual).
Имена файлов и нумерация миграций#
Новые миграции используют новую схему имён:
migration_number— число с ведущими нулями, например0001,0002, ...message-with-dashes— строка из--message, где пробелы заменены на-.hash— первые 6 символов UUID миграции.
Для ручных миграций номер равен MANUAL:
Старая схема имён по-прежнему поддерживается; команда ra-rename-migrations может переименовать старые файлы в новый формат и обновить зависимости.
Если сообщение начинается с 4-значного числа (длины по умолчанию для номера миграции), это число используется как migration_number напрямую.
Отслеживание состояния миграций#
Применённые миграции хранятся в отдельной таблице:
- Имя таблицы:
ra_migrations. - Модель:
MigrationModel(restalchemy.storage.sql.migrations.MigrationModel). - Поля:
uuid(PK) — UUID миграции.applied(bool) — признак применения миграции.
MigrationEngine гарантирует существование этой таблицы и использует её, чтобы:
- Определять, какие миграции ещё не применены.
- Проверять, можно ли выполнить откат миграции.
Автоматические и ручные миграции#
- Автоматические миграции (
is_manual == False): - Могут зависеть только от других автоматических миграций.
- Учитываются при вычислении head-миграции.
- Ручные миграции (
is_manual == True): - Часто содержат нестандартные/необратимые изменения.
- Не используются при поиске head-миграции.
Команда ra-new-migration проверяет, что автоматическая миграция не ссылается на ручные миграции в зависимостях. При нарушении этого правила выполнение завершается с ошибкой.
Общий рабочий процесс#
- Вы описываете DM-модели и со временем изменяете их.
- При изменении схемы БД создаёте новый файл миграции через
ra-new-migration. - Реализуете
upgrade()/downgrade()в файле миграции. - Применяете миграции к конкретной базе через
ra-apply-migration. - При необходимости откатываете миграции с помощью
ra-rollback-migration. - При переходе на новую схему имён используете
ra-rename-migrationsдля переименования существующих файлов и обновления зависимостей.