← Назад к вопросам

Какие знаешь способы работы с БД в SQLAlchemy?

1.0 Junior🔥 241 комментариев
#Базы данных (NoSQL)#Базы данных (SQL)

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

SQLAlchemy: основные способы работы с БД

SQLAlchemy предоставляет несколько подходов для работы с базами данных, каждый с собственными преимуществами и применением.

1. ORM (Object-Relational Mapping)

Самый высокоуровневый и популярный способ. Таблицы базы данных отображаются на Python классы, строки — на объекты.

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import declarative_base, Session

Base = declarative_base()

class User(Base):
    __tablename__ = "users"
    
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    email = Column(String(100), unique=True)

engine = create_engine("postgresql://user:password@localhost/db")
Base.metadata.create_all(engine)

with Session(engine) as session:
    user = User(name="Alice", email="alice@example.com")
    session.add(user)
    session.commit()
    
    # Запрос
    found = session.query(User).filter(User.name == "Alice").first()

Плюсы:

  • Интуитивно, приближено к объектному стилю
  • Автоматическое управление связями между таблицами
  • Встроенная кэширование сессии

Минусы:

  • Может быть медленнее на сложных запросах
  • Требует больше памяти для объектов

2. Core (SQL Expression Language)

Медиум-уровень между ORM и Raw SQL. Строит SQL запросы программно.

from sqlalchemy import MetaData, Table, Column, Integer, String, select

metadata = MetaData()

users_table = Table(
    "users",
    metadata,
    Column("id", Integer, primary_key=True),
    Column("name", String(50)),
    Column("email", String(100)),
)

with engine.connect() as conn:
    # Вставка
    stmt = users_table.insert().values(name="Bob", email="bob@example.com")
    conn.execute(stmt)
    conn.commit()
    
    # Выборка
    query = select(users_table).where(users_table.c.name == "Bob")
    result = conn.execute(query)

Плюсы:

  • Больше контроля над SQL
  • Быстрее ORM на сложных запросах
  • Не требует объектного отображения

Минусы:

  • Более многословный синтаксис

3. Raw SQL (текстовые запросы)

Полный контроль, но и полная ответственность. Используется для специфических случаев.

from sqlalchemy import text

with engine.connect() as conn:
    # Прямой SQL запрос с параметрами
    query = text("""
        SELECT * FROM users 
        WHERE name = :name 
        AND email = :email
    """)
    
    result = conn.execute(query, {"name": "Alice", "email": "alice@example.com"})
    for row in result:
        print(row)

Плюсы:

  • Максимальная производительность
  • Полный контроль над запросом
  • Поддержка специфичного для БД функционала

Минусы:

  • Уязвимо для SQL-инъекций при неправильном использовании
  • Нет защиты от ошибок БД на уровне ORM

4. Гибридный подход (ORM + Core)

Комбинирование ORM для стандартных операций и Core для сложных запросов.

# ORM для простого CRUD
user = session.query(User).get(1)
user.name = "Updated"
session.commit()

# Core для сложного запроса с aggregation
from sqlalchemy import func
stmt = select(
    User.name,
    func.count(User.id).label("count")
).group_by(User.name)

result = session.execute(stmt)

Рекомендации по выбору

  • ORM — идеален для стандартных CRUD операций и приложений с четкой доменной моделью
  • Core — когда нужна производительность и контроль, но без сырого SQL
  • Raw SQL — специфические случаи, сложные аналитические запросы, хранимые процедуры
  • Гибридный — наиболее практичный подход в production

В modern архитектуре (DDD, Clean Architecture) обычно используют ORM для моделирования доменной модели и Core/Raw SQL только для специфических запросов, чтобы сохранить чистоту архитектуры.