В этой статье разберёмся, как подключить FastAPI к PostgreSQL или MySQL с использованием SQLAlchemy, создадим модели, освоим CRUD-операции и даже попробуем асинхронные запросы. Всё по делу, с комментариями и практикой.

SQLAlchemy — это мощная ORM (Object-Relational Mapping), которая позволяет работать с базами данных на языке Python, а не на SQL. Она помогает абстрагировать SQL-запросы и управлять базой данных через удобные классы и методы.

Устанавливаем зависимости 📦

Для начала нам нужно установить несколько библиотек. В терминале выполним:

pip install sqlalchemy psycopg2-binary alembic
  • SQLAlchemy — сама ORM.
  • psycopg2-binary — драйвер для PostgreSQL (для MySQL используйте mysqlclient или aiomysql).
  • Alembic — инструмент для создания миграций.

Настраиваем подключение к базе данных 🔌

Создаём файл database.py для подключения:

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

# URL для подключения к PostgreSQL
DATABASE_URL = "postgresql://username:password@localhost/dbname"

# Создаём движок SQLAlchemy
engine = create_engine(DATABASE_URL)

# Создаём фабрику сессий для взаимодействия с БД
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

# Базовый класс для моделей
Base = declarative_base()

Что здесь происходит?

  • create_engine создаёт соединение с базой данных.
  • SessionLocal — это «фабрика» для создания сессий. Каждая сессия — это отдельный диалог с базой данных.
  • Base — базовый класс для всех моделей, которые мы будем создавать.

Создаём модель данных 🏗️

Давайте создадим простую модель для пользователей.

Создаём файл models.py:

from sqlalchemy import Column, Integer, String
from database import Base

# Модель пользователя
class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, index=True)
    email = Column(String, unique=True, index=True)
    age = Column(Integer)

Объяснение:

  • tablename — имя таблицы в базе данных.
  • Column — определяет столбцы таблицы.
  • primary_key=True — указывает, что это первичный ключ.
  • index=True — создаёт индекс для ускорения поиска.

Создаём таблицы с Alembic 🔄

Теперь нужно создать миграцию, чтобы таблица users появилась в базе данных.

Инициализируем Alembic:

alembic init alembic

Редактируем файл alembic.ini: находим строку с sqlalchemy.url и указываем наш DATABASE_URL.

Генерируем миграцию:

alembic revision --autogenerate -m "Create users table"

Применяем миграцию:

alembic upgrade head

Готово! Ваша база данных теперь знает о таблице users.

Операции CRUD: полный арсенал 🛠️

Теперь реализуем CRUD-операции (Create, Read, Update, Delete).

Создаём файл crud.py:

from sqlalchemy.orm import Session
from models import User

# Создание пользователя
def create_user(db: Session, name: str, email: str, age: int):
    new_user = User(name=name, email=email, age=age)
    db.add(new_user)
    db.commit()
    db.refresh(new_user)
    return new_user

# Получение пользователя по ID
def get_user(db: Session, user_id: int):
    return db.query(User).filter(User.id == user_id).first()

# Удаление пользователя
def delete_user(db: Session, user_id: int):
    user = db.query(User).filter(User.id == user_id).first()
    if user:
        db.delete(user)
        db.commit()

Интеграция CRUD в FastAPI 🚀

Осталось связать всё вместе в маршрутах. Открываем main.py:

from fastapi import FastAPI, HTTPException, Depends
from sqlalchemy.orm import Session
from database import SessionLocal
import crud

app = FastAPI()

# Зависимость для получения сессии БД
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.post("/users/")
def create_user(name: str, email: str, age: int, db: Session = Depends(get_db)):
    return crud.create_user(db, name, email, age)

@app.get("/users/{user_id}")
def read_user(user_id: int, db: Session = Depends(get_db)):
    user = crud.get_user(db, user_id)
    if not user:
        raise HTTPException(status_code=404, detail="Пользователь не найден")
    return user

Пояснение:

  • Depends(get_db) — внедряет зависимость для работы с базой данных.
  • create_user — создаёт нового пользователя.
  • read_user — возвращает пользователя по ID, а если не находит, выбрасывает исключение 404.

Заключение: ваши данные — под контролем!

Теперь у вас есть базовое API для управления записями в базе данных! Мы подключили FastAPI к PostgreSQL/MySQL, создали модели, настроили миграции с Alembic и реализовали CRUD. Дальше можно расширять функционал, добавлять валидацию и переходить к асинхронным запросам. Но это — тема для следующей статьи.