Что такое императивный маппинг в SQLAlchemy

Ответ

Императивный маппинг (Imperative Mapping) в SQLAlchemy — это классический способ явного связывания Python-класса с таблицей базы данных. В отличие от более современного декларативного подхода (Declarative Mapping), он строго разделяет определение схемы данных (таблицы) и определение бизнес-модели (класса).

Когда это полезно?

Этот подход используется реже, но незаменим в следующих случаях:

  • Интеграция с существующей базой данных: когда таблицы уже существуют и их нужно "отразить" (reflect) в коде.
  • Работа с legacy-кодом: когда Python-классы уже определены и их нельзя изменять, добавляя наследование от декларативной базы.
  • Сложные сценарии маппинга: когда требуется максимальная гибкость и явный контроль над процессом связывания.
  • Четкое разделение слоев: для строгого разграничения описания схемы данных (Table) и бизнес-логики (class).

Пример

Процесс состоит из трех шагов: определение таблицы, определение класса и их явное связывание.

from sqlalchemy import (
    create_engine, Table, Column, Integer, String, MetaData
)
from sqlalchemy.orm import registry, sessionmaker

# 1. Определение таблицы (описание схемы данных)
metadata_obj = MetaData()
user_table = Table(
    "users",
    metadata_obj,
    Column("id", Integer, primary_key=True),
    Column("name", String(50)),
)

# 2. Определение Python-класса (бизнес-логика)
# Класс не зависит от SQLAlchemy и может быть простым (POPO)
class User:
    pass

# 3. Явное связывание (маппинг)
# Используем registry для современных версий SQLAlchemy
mapper_registry = registry()
mapper_registry.map_imperatively(User, user_table)

# Пример использования
engine = create_engine("sqlite:///:memory:")
metadata_obj.create_all(engine)
Session = sessionmaker(bind=engine)

with Session() as session:
    new_user = User()
    new_user.name = 'john'
    session.add(new_user)
    session.commit()