Перейти к содержимому
Alembic + SQLAlchemy + PostgreSQL (Docker) |  Мини‑курс [1]

Alembic + SQLAlchemy + PostgreSQL (Docker) | Мини‑курс [1]

Что должно быть установлено

  • Python 3.11+ (желательно)
  • Docker Desktop / Docker Engine
  • PyCharm Pro (для удобства, но команды одинаковы в любом IDE)
Важно: курс написан так, чтобы вы могли выполнять его командами из терминала. PyCharm Pro нужен только как удобная среда.

1. Создаем структуру проекта

Создайте папку проекта alembic_mini_course и такую структуру:

alembic_mini_course/
├─ app/
│  ├─ __init__.py
│  ├─ db.py
│  ├─ models.py
│  └─ settings.py
├─ docker-compose.yml
├─ requirements.txt
└─ README.md

Зачем каждый файл

  • app/settings.py — хранит настройки (DSN подключения к БД).
  • app/db.py — создает SQLAlchemy engine и фабрику сессий.
  • app/models.py — ваши модели (классы таблиц).
  • docker-compose.yml — поднимает PostgreSQL в Docker.
  • requirements.txt — зависимости Python.

 

2. Поднимаем PostgreSQL в Docker

Создайте файл docker-compose.yml в корне проекта:

services:
  db:
    image: postgres:16
    container_name: alembic_course_db
    environment:
      POSTGRES_DB: app_db
      POSTGRES_USER: app_user
      POSTGRES_PASSWORD: app_password
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

Пояснение параметров

  • image: postgres:16 — официальный образ PostgreSQL 16.
  • POSTGRES_DB/USER/PASSWORD — создаются при первом запуске контейнера.
  • ports — пробрасываем порт контейнера на локальный компьютер: localhost:5432.
  • volumes — сохраняем данные БД между перезапусками.

Запуск

docker compose up -d

Проверка

docker ps
Ожидаемый результат: в списке контейнеров есть alembic_course_db со статусом Up.

3. Устанавливаем зависимости Python

Создайте requirements.txt:

SQLAlchemy==2.0.30
psycopg2-binary==2.9.9
alembic==1.13.2
python-dotenv==1.0.1

Установите:

pip install -r requirements.txt

Зачем эти пакеты

  • SQLAlchemy — ORM и работа с БД.
  • psycopg2-binary — драйвер PostgreSQL для Python.
  • alembic — миграции схемы БД.
  • python-dotenv — удобно подгружать переменные окружения из .env (опционально).

4. Настройки: DSN подключения к БД

Создайте app/settings.py:

from dataclasses import dataclass
import os


@dataclass(frozen=True)
class Settings:
    """
    Настройки приложения.

    db_url — DSN (строка подключения) для SQLAlchemy и Alembic.
    Пример:
    postgresql+psycopg2://user:password@host:port/dbname
    """
    db_url: str


def get_settings() -> Settings:
    """
    Берем DSN из переменной окружения DATABASE_URL.
    Если переменной нет — используем значение по умолчанию под наш docker-compose.
    """
    default_url = "postgresql+psycopg2://app_user:app_password@localhost:5432/app_db"
    return Settings(db_url=os.getenv("DATABASE_URL", default_url))

Разбор

  • dataclass — удобный способ хранить настройки как объект.
  • frozen=True — делает объект неизменяемым (защита от случайной правки).
  • os.getenv("DATABASE_URL", default) — читаем переменную окружения, иначе берем дефолт.

5. Подключение SQLAlchemy: Base, engine, SessionLocal

Создайте app/db.py:

from sqlalchemy import create_engine
from sqlalchemy.orm import DeclarativeBase, sessionmaker

from app.settings import get_settings


class Base(DeclarativeBase):
    """
    Базовый класс декларативных моделей.

    Все модели наследуются от Base.
    SQLAlchemy собирает "описание таблиц" в Base.metadata.
    Alembic потом использует Base.metadata для автогенерации миграций.
    """
    pass


settings = get_settings()

# Engine управляет подключениями к БД и генерирует SQL под нужный диалект (PostgreSQL).
engine = create_engine(settings.db_url, echo=True)

# SessionLocal — фабрика сессий.
# Session — объект для запросов, транзакций и работы с сущностями ORM.
SessionLocal = sessionmaker(bind=engine)

Разбор методов

  • create_engine(url, echo=True):
    • url — DSN подключения
    • echo=True — печатает SQL в консоль (полезно на обучении)
  • sessionmaker(bind=engine):
    • возвращает фабрику, которая создает объекты Session
    • каждая Session обычно соответствует одной “единице работы” (unit of work)

6. Первая модель: User

Создайте app/models.py:

from sqlalchemy import String
from sqlalchemy.orm import Mapped, mapped_column

from app.db import Base


class User(Base):
    """
    Таблица пользователей.
    __tablename__ задает имя таблицы в БД.
    """
    __tablename__ = "users"

    # Primary Key. Тип берется из аннотации Mapped[int].
    id: Mapped[int] = mapped_column(primary_key=True)

    # email: VARCHAR(255), уникальный, NOT NULL
    email: Mapped[str] = mapped_column(String(255), unique=True, nullable=False)

Разбор

  • __tablename__ — имя таблицы.
  • Mapped[T] — типизированное поле SQLAlchemy 2.0.
  • mapped_column(...) описывает колонку:
    • primary_key=True — первичный ключ
    • String(255) — строковый тип с ограничением длины
    • unique=True — уникальность
    • nullable=False — запрет NULL
Итог урока 1: у вас есть Docker Postgres и Python‑проект с моделями, но таблицы в БД еще не созданы. Их создаст Alembic в уроке 2.

Ссылки по теме

Конспект:
Понедельник, 05 января 2026
Alembic + SQLAlchemy + PostgreSQL (Docker) |  Мини‑курс [1]