Что такое SQLAlchemy в Python?

Ответ

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

Два основных компонента:

  1. Core: Низкоуровневый SQL-инструментарий. Он предоставляет абстрактный слой для построения SQL-выражений, управления соединениями (пулинг) и выполнения запросов. Это «правильный» способ писать SQL в Python.
  2. ORM: Высокоуровневая надстройка над Core. Она связывает таблицы базы данных с классами Python, а строки — с экземплярами этих классов, позволяя манипулировать данными как обычными объектами.

Пример работы с ORM (Декларативный стиль):

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

# 1. Определяем базовый класс для моделей
Base = declarative_base()

# 2. Определяем класс-модель, который соответствует таблице в БД
class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(50), nullable=False)
    email = Column(String(100), unique=True)

# 3. Создаем движок для подключения к БД (SQLite в примере)
engine = create_engine('sqlite:///app.db', echo=True) # echo=True логирует SQL

# 4. Создаем таблицы в БД
Base.metadata.create_all(engine)

# 5. Работаем с данными через сессию
with Session(engine) as session:
    # Создание нового пользователя
    new_user = User(name='Alice', email='alice@example.com')
    session.add(new_user)
    session.commit()  # INSERT INTO users ...

    # Запрос данных
    user = session.query(User).filter_by(name='Alice').first()
    print(user.email)  # alice@example.com

Ключевые преимущества:

  • Абстракция от СУБД: Код практически не меняется при переходе с PostgreSQL на MySQL или SQLite.
  • Безопасность: Использование параметризованных запросов через ORM или Core предотвращает SQL-инъекции.
  • Гибкость: Для сложных аналитических запросов можно использовать Core или гибридный подход (ORM + raw SQL).
  • Экосистема: Поддержка Alembic для миграций схемы БД.

Ответ 18+ 🔞

А, SQLAlchemy! Ну это, блядь, такая штука, которая тебе всю работу с базой данных в Python делает так, что ты даже не вспотеешь. Представь, что у тебя есть куча таблиц в базе, а ты с ними как с обычными питоновскими объектами работаешь. Красота, ёпта!

Два главных кита, на которых всё держится:

  1. Core: Это, типа, низкоуровневый ствол. Если ты хочешь сам SQL писать, но чтобы было красиво и безопасно — это твой выбор. Это как собрать мебель из Икеи по инструкции, а не гвоздями сколачивать. Правильный способ, блядь.
  2. ORM: А это уже высший пилотаж. Надстройка над Core. Ты просто объявляешь классы, а SQLAlchemy сама догадывается, как их в таблицы превратить и обратно. Сидишь, пьешь кофе, а она там INSERT-ы и SELECT-ы за тебя строит. Удобство — овердохуища.

Смотри, как это выглядит на практике (самый популярный способ):

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

# 1. Создаём базовый класс, от которого все модели будут плодиться. Магия начинается тут.
Base = declarative_base()

# 2. Вот она, наша модель. Класс `User` — это будущая таблица `users`. Проще некуда.
class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)  # Это типа наш главный и уникальный номер, primary key, ёпта
    name = Column(String(50), nullable=False)  # Имя, и оно ОБЯЗАТЕЛЬНОЕ (null нельзя)
    email = Column(String(100), unique=True)  # Почта, и чтобы никаких повторов!

# 3. Подключаемся к базе. Для примера — SQLite, файлик `app.db`. `echo=True` — это чтобы в консоль все SQL-запросы выводились, для отладки.
engine = create_engine('sqlite:///app.db', echo=True)

# 4. Вжух! И таблицы в базе создались. Всё по описанию класса.
Base.metadata.create_all(engine)

# 5. А теперь самое интересное — работа с данными.
with Session(engine) as session:
    # Создаём новую Алису. Просто создаём объект, как обычно.
    new_user = User(name='Alice', email='alice@example.com')
    session.add(new_user)  # Говорим сессии: "Запомни эту тётю"
    session.commit()  # А тут уже происходит реальный INSERT в базу. Всё, Алиса записана!

    # Теперь хотим Алису найти. Делаем запрос.
    user = session.query(User).filter_by(name='Alice').first()  # "Дай мне первого пользователя по имени Alice"
    print(user.email)  # Выведет: alice@example.com. Работает, сука!

Ну и почему это вообще огонь?

  • Похуй на базу: Пишешь код один раз, а потом можешь с SQLite на PostgreSQL переключиться, поменяв одну строку подключения. Серьёзно.
  • Никаких инъекций: ORM сама всё экранирует. Можно спать спокойно, тебя не взломают через ' OR '1'='1.
  • Гибкость — пиздец: Если ORM не справляется со сложной аналитикой — всегда можно ручками SQL через Core написать или сырой запрос вставить. Никто не загоняет в рамки.
  • Миграции наше всё: Есть Alembic — отдельная бандура, которая помогает менять структуру базы (добавлять столбцы, таблицы), когда твои модели эволюционируют. Без него — просто пипец, чувак.