В этой статье разберёмся, как подключить FastAPI к PostgreSQL или MySQL с использованием SQLAlchemy, создадим модели, освоим CRUD-операции и даже попробуем асинхронные запросы. Всё по делу, с комментариями и практикой.
Устанавливаем зависимости 📦
Для начала нам нужно установить несколько библиотек. В терминале выполним:
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. Дальше можно расширять функционал, добавлять валидацию и переходить к асинхронным запросам. Но это — тема для следующей статьи.