В этой лекции мы познакомимся с процессом создания первой миграции в проекте на FastAPI, используя Alembic. Мы разберём базовые команды для работы с миграциями, начиная с создания пустого шаблона миграции и заканчивая автоматической генерацией миграции на основе изменений в моделях данных. Заодно добавим немного практики, чтобы процесс миграции стал для нас понятным и, главное, ненапряжным. Готовы? Поехали!
Прежде всего, давайте вспомним, зачем нам эти миграции нужны. Когда вы работаете над проектом, структура базы данных постоянно меняется. Добавились новые поля, удалились старые таблички, поменяли типы данных — всё это требует внесения изменений непосредственно в базу. Делать такие изменения вручную — как писать код без Ctrl+Z: неразумно и рискованно. Миграции позволяют вам описать эти изменения в виде последовательности шагов, которые можно применять, откатывать и переносить между окружениями (например, с разработки на продакшн).
Alembic приходит на помощь
Alembic берёт на себя управление этими изменениями. Он помогает:
- Создавать новые миграции.
- Применять изменения к базе данных.
- Откатывать изменения, если вдруг что-то пошло не так (обычно это фраза из документации, но давайте притворимся, что такое никогда не случается 🤞).
План создания первой миграции
- Создать и инициализировать рабочую директорию Alembic.
- Настроить Alembic для взаимодействия с базой данных и моделями SQLAlchemy.
- Создать первую миграцию вручную.
- Автоматически сгенерировать миграцию на основе изменений моделей.
Шаг 1: инициализация Alembic
Начнём с подготовки проекта. Мы предполагаем, что у вас уже есть рабочий проект FastAPI с подключением к базе данных через SQLAlchemy.
Если Alembic ещё не установлен, самое время это сделать. Одна команда — и вы готовы к миграциям:
pip install alembic
Проверьте, установлен ли Alembic, выполнив:
alembic --version
Теперь попробуем инициализировать Alembic в нашем проекте. Команда ниже создаст директорию alembic, где будут храниться все миграции и настройки:
alembic init alembic
После выполнения этой команды вы увидите новую структуру файлов:
project/
├── alembic/
│ ├── env.py
│ ├── versions/
├── alembic.ini
- alembic.ini — файл настроек Alembic.
- env.py — скрипт для описания подключения к базе данных.
- versions/ — здесь будут храниться наши миграции.
Шаг 2: Настройка Alembic
Теперь давайте скажем Alembic, как ему подключаться к базе данных. Для этого откроем файл alembic.ini и укажем путь подключения. Найдите строку с sqlalchemy.url:
sqlalchemy.url = sqlite:///./test.db
Если вы, как истинный любитель минимализма, используете SQLite, строка выше подойдёт. Если ваш проект работает с PostgreSQL, измените её на что-то вроде:
sqlalchemy.url = postgresql+psycopg2://user:password@localhost/dbname
Теперь перейдём к настройкам env.py. Этот файл отвечает за то, как Alembic интегрируется с нашими моделями SQLAlchemy. Нам нужно указать модуль, в котором находятся модели, и настроить подключение.
Найдите функцию run_migrations_online() и исправьте часть с connectable на следующий код:
from app.database import engine # Импортируем наш SQLAlchemy engine
connectable = engine # Передаём engine Alembic для подключения к базе
Также обязательно убедитесь, что модели подключены:
from app.models import Base
target_metadata = Base.metadata # Передаём метаданные моделей Alembic
Шаг 3: создание пустой миграции
Попробуем создать нашу первую простейшую миграцию. Для начала воспользуемся следующей командой:
alembic revision -m "Создание начальной структуры"
Эта команда создаст файл в директории versions/:
alembic/versions/
└── <идентификатор_ревизии>_создание_начальной_структуры.py
Миграция пока будет пустой, но в реальном проекте вы можете вручную добавить код для создания таблиц.
Пример содержимого файла миграции:
def upgrade():
# Здесь можно писать инструкции для обновления схемы
pass
def downgrade():
# Здесь пишем инструкции для отката изменений
pass
Шаг 4: генерация миграции на основе изменений
Один из самых удобных аспектов Alembic — способность самостоятельно генерировать код миграций на основании изменений в ваших моделях данных. Настало время автоматизировать процесс!
Предположим, у нас есть модель User:
from sqlalchemy import Column, Integer, String
from app.database import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, index=True)
email = Column(String, index=True, unique=True)
Теперь мы хотим создать миграцию, описывающую структуру таблицы users. Запустим:
alembic revision --autogenerate -m "Создание таблицы users"
Alembic заглянет в ваши модели и сгенерирует миграцию, которая выглядит примерно так:
def upgrade():
op.create_table(
'users',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(), nullable=True),
sa.Column('email', sa.String(), nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('email')
)
def downgrade():
op.drop_table('users')
Шаг 5: применение миграции
После создания миграции пора применить изменения к базе данных. Это можно сделать командой:
alembic upgrade head
head означает, что Alembic применит все ревизии вплоть до последней. После выполнения команды в базе данных появится новая таблица users.
На что обратить внимание?
Иногда Alembic не может правильно определить изменения в модели — например, если вы добавили сложный тип данных или изменили поведение столбца. В таких случаях стоит вручную проверить сгенерированный файл миграции.
Теперь у вас есть базовые знания о том, как создать первую миграцию в FastAPI с помощью Alembic. Впереди ещё много интересного, включая изменение существующих структур базы данных и откаты изменений. Так что запасайтесь кофе и продолжаем расти как разработчики!
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ