Как правильно переводить объекты в классы SQLAlchemy?
Что проверяют
Понимаете ли вы, как данные попадают в ORM-модель и обратно: из словаря или схемы валидации в объект, из объекта в ответ API. Заодно смотрят, пишете ли вы в стиле SQLAlchemy 2.0 и знаете ли жизненный цикл объекта в сессии.
Как отвечать
Начните с объявления модели в современном стиле: класс Base(DeclarativeBase), поля через Mapped[int] и mapped_column(). Импорт declarative_base из sqlalchemy.ext.declarative устарел, а session.query() в 2.0 считается legacy: вместо него session.scalars(select(User).where(...)) и session.get(User, id).
Дальше пути преобразования:
- словарь в объект: конструктор по умолчанию принимает именованные аргументы для замапленных атрибутов, поэтому
User(**data)работает без своего__init__. Неизвестный ключ дастTypeError, так что данные сначала фильтруют; - Pydantic в объект:
User(**dto.model_dump())при создании, а для частичного обновления циклsetattrпо полям изmodel_dump(exclude_unset=True); - объект в Pydantic: в схеме
model_config = ConfigDict(from_attributes=True), затемUserOut.model_validate(user). В ответ уходят только поля схемы; session.merge(): копирует состояние в объект сессии, при необходимости делаяSELECT, и возвращает другой экземпляр. Дальше работают с ним, а не с исходным;- массовая вставка:
session.execute(insert(User), list_of_dicts)быстрее тысяч отдельных объектов.
Покажите знание состояний: transient, pending, persistent, detached. По умолчанию expire_on_commit=True, и после коммита атрибуты перечитываются при следующем обращении. Если сессия уже закрыта, это заканчивается DetachedInstanceError.
Где спотыкаются
Делают User(**request.json) без схемы. Клиент присылает is_admin, и поле честно записывается.
Возвращают ORM-объект из эндпоинта напрямую. Он не сериализуется в JSON, а ленивые связи порождают N+1 запросов или ошибку в закрытой сессии.
Обращаются к ленивой связи в асинхронном коде. С AsyncSession неявная подгрузка не работает, связи нужно загружать заранее через selectinload() или joinedload().