SQLModel – ORM на основе Pydan

онлайн тренер по питону
Онлайн-тренажер Python 3 для начинающих

Теория без воды. Задачи с автоматической проверкой. Подсказки на русском языке. Работает в любом современном браузере.

начать бесплатно

Введение

SQLAlchemy и Pydantic — два мощных инструмента Python-разработчика: один для работы с базой данных, другой — для валидации данных. Однако между ними всегда существовал разрыв. Решение этой проблемы — SQLModel – ORM на основе Pydantic, объединяющая лучшее от обоих миров.

SQLModel позволяет использовать типизированные Pydantic-модели как ORM-таблицы SQLAlchemy. Это упрощает разработку, ускоряет создание API и устраняет дублирование кода между моделями БД и сериализаторами.

Установка и подключение

Установка SQLModel:

bash
pip install sqlmodel

Подключение к базе данных через SQLAlchemy:

python
from sqlmodel import SQLModel, create_engine engine = create_engine("sqlite:///database.db")

Основы работы с SQLModel

Создание модели:

python
from sqlmodel import Field class User(SQLModel, table=True): id: int = Field(default=None, primary_key=True) name: str email: str

Особенности:

  • table=True указывает, что модель используется как таблица

  • Типы данных задаются через аннотации

  • Поддержка default, nullable, foreign_key

Создание таблиц и баз данных

python
SQLModel.metadata.create_all(engine)

Для PostgreSQL:

python
engine = create_engine("postgresql://user:pass@localhost/dbname")

CRUD-операции с SQLModel

Создание записи

python
from sqlmodel import Session user = User(name="Иван", email="ivan@example.com") with Session(engine) as session: session.add(user) session.commit()

Получение данных

python
result = session.exec(select(User).where(User.name == "Иван")).first()

Обновление

python
user.email = "new@example.com" session.add(user) session.commit()

Удаление

python
session.delete(user) session.commit()

Асинхронная работа с SQLModel

SQLModel можно использовать с async SQLAlchemy 2.0:

python
from sqlalchemy.ext.asyncio import create_async_engine engine = create_async_engine("sqlite+aiosqlite:///database.db")

Асинхронная сессия:

python
from sqlalchemy.ext.asyncio import AsyncSession async with AsyncSession(engine) as session: await session.commit()

Совместимость с FastAPI

SQLModel идеально сочетается с FastAPI:

python
from fastapi import FastAPI app = FastAPI() @app.post("/users") def create_user(user: User): with Session(engine) as session: session.add(user) session.commit() return user

Модели SQLModel сразу используются как Pydantic-схемы — их не нужно дублировать.

Фильтрация и запросы

python
from sqlmodel import select stmt = select(User).where(User.email.contains("@example.com")) with Session(engine) as session: users = session.exec(stmt).all()

Работа с отношениями (ForeignKey)

python
class Post(SQLModel, table=True): id: int = Field(default=None, primary_key=True) title: str user_id: int = Field(foreign_key="user.id")

Пока нет встроенной загрузки связей (eager/lazy), как в SQLAlchemy, но можно реализовать вручную.

Наследование и повторное использование моделей

python
class UserBase(SQLModel): name: str email: str class User(UserBase, table=True): id: int = Field(default=None, primary_key=True) class UserCreate(UserBase): pass

Это позволяет отделять схемы запроса, ответа и базу данных.

Миграции с Alembic и SQLModel

Для миграций используйте Alembic с SQLAlchemy:

bash
alembic init alembic

В env.py добавьте:

python
from myapp.models import SQLModel target_metadata = SQLModel.metadata

Затем:

bash
alembic revision --autogenerate -m "initial" alembic upgrade head

Интеграция с Pandas и аналитикой

Преобразование модели в словарь:

python
user.dict()

Можно легко создать DataFrame:

python
import pandas as pd users = session.exec(select(User)).all() df = pd.DataFrame([u.dict() for u in users])

Сравнение с другими ORM

ORM Библиотека Поддержка Pydantic Асинхронность Использование в FastAPI
SQLModel SQLAlchemy + Pydantic Да Да Идеально подходит
SQLAlchemy SQLAlchemy Нет (отдельно) Да (в 2.0) Через дополнительные модели
Tortoise ORM Асинхронная ORM Частично Да Есть интеграция
Django ORM Django Нет Ограничена Только в Django

Тестирование моделей SQLModel

  • Используйте SQLite в памяти:

python
engine = create_engine("sqlite://", echo=True)
  • Генерация базы:

python
SQLModel.metadata.create_all(engine)
  • Проверка сериализации:

python
user = User(name="Тест", email="test@test.com") assert user.dict()["email"] == "test@test.com"

Часто задаваемые вопросы (FAQ)

1. Что такое SQLModel?
Это ORM-библиотека, объединяющая SQLAlchemy и Pydantic в одном синтаксисе.

2. Можно ли использовать SQLModel без FastAPI?
Да, она полностью самостоятельна.

3. Поддерживает ли SQLModel асинхронность?
Да, через SQLAlchemy 2.0 и async engine.

4. Как создать таблицу из модели?
Через SQLModel.metadata.create_all(engine).

5. Как реализовать ForeignKey?
Через Field(foreign_key="tablename.columnname").

6. Работает ли SQLModel с PostgreSQL?
Да, поддерживает все СУБД, поддерживаемые SQLAlchemy.

Полный справочник по работе с SQLModel — современной ORM-библиотекой для Python

Установка

bash
pip install sqlmodel

Для работы с базами данных:

bash
pip install "sqlmodel[postgresql]" # если нужен asyncpg

Основы: объявление модели

python
from sqlmodel import SQLModel, Field class User(SQLModel, table=True): id: int | None = Field(default=None, primary_key=True) name: str age: int
Компонент Назначение
SQLModel Родительский класс для всех моделей.
table=True Делает модель таблицей БД.
Field(...) Настройка поля (аналог Column).

Создание базы данных и таблиц

python
from sqlmodel import create_engine, SQLModel engine = create_engine("sqlite:///database.db") SQLModel.metadata.create_all(engine)

Синхронные операции с сессией

python
from sqlmodel import Session with Session(engine) as session: user = User(name="Alice", age=30) session.add(user) session.commit()

Чтение из базы

python
with Session(engine) as session: users = session.query(User).all() user = session.get(User, 1)

Фильтрация и сортировка

python
from sqlmodel import select with Session(engine) as session: statement = select(User).where(User.age > 25).order_by(User.name) results = session.exec(statement) for user in results: print(user.name)

Обновление данных

python
with Session(engine) as session: user = session.get(User, 1) user.age += 1 session.add(user) session.commit()

Удаление записи

python
with Session(engine) as session: user = session.get(User, 1) session.delete(user) session.commit()

Разделение модели: Create, Read, Update

python
class UserBase(SQLModel): name: str age: int class UserCreate(UserBase): pass class UserRead(UserBase): id: int

Асинхронная работа (SQLAlchemy 1.4+)

python
from sqlmodel import SQLModel, select from sqlmodel.ext.asyncio.session import AsyncSession from sqlalchemy.ext.asyncio import create_async_engine engine = create_async_engine("sqlite+aiosqlite:///db.db") async with AsyncSession(engine) as session: result = await session.exec(select(User)) users = result.all()

Поддержка связей (ForeignKey)

python
class Author(SQLModel, table=True): id: int | None = Field(default=None, primary_key=True) name: str class Book(SQLModel, table=True): id: int | None = Field(default=None, primary_key=True) title: str author_id: int = Field(foreign_key="author.id")

Использование с FastAPI

python
from fastapi import FastAPI, Depends from sqlmodel import Session app = FastAPI() def get_session(): with Session(engine) as session: yield session @app.post("/users/") def create_user(user: User, session: Session = Depends(get_session)): session.add(user) session.commit() session.refresh(user) return user

Преимущества SQLModel

Особенность Описание
Типизированные модели Поддержка mypy, автокомплит, автодокументация.
Pydantic + SQLAlchemy Валидация и ORM в одной модели.
Простота миграции Работает с Alembic (как и SQLAlchemy).
Поддержка async Совместим с FastAPI и асинхронными драйверами.
Совместимость с select() Современные выражения SQLAlchemy 2.0.

Когда использовать SQLModel

  • Когда ты используешь FastAPI или асинхронные API.