Alembic + SQLAlchemy + PostgreSQL (Docker) | Мини‑курс [2]
В этом уроке мы подключим Alembic, настроим автогенерацию миграций из SQLAlchemy моделей, создадим миграцию для таблицы users и применим её в БД.
1. Инициализируем Alembic
В корне проекта выполните:
alembic init alembic
Появятся файлы:
alembic/
env.py
script.py.mako
versions/
alembic.ini
Зачем они
alembic.ini— конфиг (в том числе URL подключения к БД).alembic/env.py— “точка входа” Alembic:- как подключиться к БД
- какую metadata использовать для сравнения (автогенерация)
- как выполнять миграции
alembic/versions/— папка с файлами миграций (каждый файл = один шаг схемы).
2. Настраиваем URL подключения в alembic.ini
Откройте alembic.ini и найдите:
sqlalchemy.url = driver://user:pass@localhost/dbname
Замените на:
sqlalchemy.url = postgresql+psycopg2://app_user:app_password@localhost:5432/app_db
3. Подключаем SQLAlchemy metadata к Alembic
Alembic автогенерирует миграции, сравнивая состояние БД и “описание таблиц” из ваших моделей. Это описание хранится в Base.metadata.
Откройте alembic/env.py и сделайте так, чтобы:
- Импортировались
Baseи модуль с моделями. target_metadataуказывал наBase.metadata.
В верхней части файла (рядом с импортами) добавьте:
from app.db import Base
import app.models # важно: импортируем модели, чтобы они зарегистрировались в Base.metadata
target_metadata = Base.metadata
Частая ошибка: поставить target_metadata = Base.metadata, но не импортировать модели. Тогда Base.metadata будет пустой, и --autogenerate “не увидит” ваши таблицы.
Почему нужно import app.models
Пока Python не импортировал модуль с моделями, классы User и другие не “созданы”, и SQLAlchemy не успевает зарегистрировать таблицы в Base.metadata. Импорт гарантирует, что классы будут загружены и metadata заполнится.
4. Создаем миграцию (autogenerate)
Выполните команду:
alembic revision --autogenerate -m "create users table"
Появится файл в alembic/versions/, например:
alembic/versions/7f3b9b1e0f2a_create_users_table.py
Что внутри файла миграции
Там будут:
revision— идентификатор этой миграции (уникальный).down_revision— идентификатор предыдущей миграции (у первой миграцииNone).upgrade()— шаг “вперед”.downgrade()— шаг “назад”.
Пример логики (у вас ID будут другими):
from alembic import op
import sqlalchemy as sa
def upgrade() -> None:
op.create_table(
"users",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("email", sa.String(length=255), nullable=False),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("email"),
)
def downgrade() -> None:
op.drop_table("users")
Разбор операций
op.create_table(...)— операция Alembic, которая создаёт таблицу.sa.Column— описание колонок (тип, nullable).sa.PrimaryKeyConstraint,sa.UniqueConstraint— ограничения.
5. Применяем миграцию в БД
Выполните:
alembic upgrade head
Что именно делает команда
- Подключается к БД по DSN из
alembic.ini. - Создает служебную таблицу
alembic_version, если её нет. - Выполняет
upgrade()из нужных миграций по порядку. - Записывает текущую “версию” в
alembic_version.
users и служебная alembic_version.6. Проверяем БД через psql в контейнере
Откроем psql прямо внутри контейнера Postgres:
docker exec -it alembic_course_db psql -U app_user -d app_db
Покажем список таблиц:
\dt
Посмотрим структуру users:
\d users
Выйти:
\qСсылки по теме
- Alembic + SQLAlchemy + PostgreSQL (Docker) | Мини‑курс [1]
- Alembic + SQLAlchemy + PostgreSQL (Docker) | Мини‑курс [3]
- Alembic + SQLAlchemy + PostgreSQL (Docker) | Ошибки | Мини‑курс [4]
![Alembic + SQLAlchemy + PostgreSQL (Docker) | Мини‑курс [2] Alembic + SQLAlchemy + PostgreSQL (Docker) | Мини‑курс [2]](https://technobee.ru/media/zoo/images/line100_python_b25cc4f165b72ffa38afe4daaa46eb87.png)
![Alembic + SQLAlchemy + PostgreSQL (Docker) | Мини‑курс [2] Alembic + SQLAlchemy + PostgreSQL (Docker) | Мини‑курс [2]](https://technobee.ru/media/zoo/images/line100_python_24f065d5f44b128d7987e916e0a668ad.png)