Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

+717новых вакансий за сутки·60 871вакансия открыта сейчас·Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Новые вакансии в TelegramРаботодателям
Talanto
Вакансии
Компании5 951
РезюмеAIПодготовкаСтатьи
ТарифыТарифы
Войти

Не нашли подходящее?

Пусть нужная вакансия найдёт вас сама.

  1. Подборка в TelegramНовые вакансии по вашему фильтру — сразу в бота.Подключить
  2. Мэтчи по резюмеЗагрузите резюме — покажем, где вы подходите лучше всего.Загрузить
  3. Сохранить фильтрНастройте поиск один раз и возвращайтесь к новым вакансиям.Настроить
Что нового на TalantoTalanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Для работодателей

Опубликуйте вакансию — отклики придут в ваш кабинет.

  1. Вакансиябесплатно
  2. Откликиконтакты бесплатно
  3. Наймэтапы и интервью

40 компаний публикуют вакансии напрямую · 4 391 кандидат открыт к предложениям

Разместить вакансию

Популярные направления

Все подборки
  • Python9 224
  • Облачные технологии4 076
  • QA вакансии1 588
  • Android1 322
  • Инженер данных805
  • Продакт-менеджер368

Разработка

  • Backend вакансии1 317
  • iOS1 239
  • AI вакансии608
  • Fullstack вакансии523
  • Frontend вакансии456
  • Mobile вакансии28

По стеку

  • Go5 445
  • Java3 175
  • Kotlin1 119
  • Node.js1 026
  • Rust949
  • .NET666
  • PHP311
  • C++273
  • C#210

DevOps и инфраструктура

  • DevOps вакансии2 713
  • Kubernetes2 308
  • Linux-инфраструктура1 890
  • Terraform / IaC1 406
  • CI/CD919
  • Мониторинг и Observability645
  • SRE226
  • Кибербезопасность84

Аналитика и данные

  • Аналитик данных483
  • Data Scientist469
  • Бизнес-аналитик349
  • Системный аналитик48

Другие направления

  • Проджект-менеджер139
  • UI/UX дизайн71
  • Ручное тестирование14

По регионам

  • Вакансии в США24 791
  • Вакансии в Европе9 439
  • Работа в России2 924
  • Вакансии в Канаде2 178

По формату

  • Удалённые вакансии43 505
  • Релокация в США24 791
  • Гибридная работа3 370
  • Офисная работа2 525

По уровню

  • Senior вакансии20 898
  • Middle вакансии12 438
  • Junior вакансии3 864

Сейчас нанимают

Все компании
  • Wise191 вакансия
  • Rakuten188 вакансий
  • ASML163 вакансии
  • Grab134 вакансии
  • Celonis48 вакансий
  • Spotify37 вакансий
  • Adyen28 вакансий
  • Infobip28 вакансий
  • Monzo20 вакансий
  • Darktrace17 вакансий

Вакансии из 344 источников: карьерные страницы компаний и джоб-борды.

КомпанииО насНовостиПубличная офертаУсловия использованияПолитика конфиденциальностиПоддержка
←К теме SQLAlchemyВсе вопросы
SQLAlchemyJuniorТеория

В чём разница между Session.add(), Session.merge() и Session.get()?

В закладки
Сначала попробуйте ответить сами30 секунд
Сравнить с ответом ↓

add() регистрирует новый объект (INSERT при flush), merge() переносит detached-объект в сессию с возможным SELECT+UPDATE, get() ищет по PK с кэшем identity map.

Session.add()

Помещает объект в сессию со статусом pending (новый) или переводит detached-объект обратно в persistent. Не делает INSERT немедленно — запрос уйдёт при flush() или commit().

from sqlalchemy.orm import Session
from models import User

with Session(engine) as session:
    user = User(name="Alice", email="alice@example.com")
    session.add(user)          # статус: pending
    session.commit()           # flush + commit → INSERT выполнен
    print(user.id)             # id заполнен после flush

Если объект уже persistent (привязан к этой же сессии), повторный add() — нет-оп.

Session.add(), Session.merge() и Session.get() — три разных контракта

Эти три метода решают разные задачи в рамках Unit of Work — паттерна, лежащего в основе SQLAlchemy Session.

Session.merge()

Принимает объект (часто detached или вообще не привязанный к сессии) и возвращает managed копию. SQLAlchemy сначала ищет объект в identity map по первичному ключу, затем при необходимости делает SELECT, и наконец копирует атрибуты. Используется при работе с объектами, пришедшими извне (десериализация, другая сессия, кэш).

with Session(engine) as session:
    # detached_user пришёл из другой сессии или был десериализован
    managed_user = session.merge(detached_user)
    managed_user.name = "Bob"
    session.commit()   # UPDATE выполнен для managed_user

Важно: merge() может генерировать SELECT перед UPDATE. Если нужна только upsert-семантика без лишних запросов, смотрите на insert().on_conflict_do_update() из SQLAlchemy Core.

Session.get()

Загружает объект по первичному ключу. Сначала проверяет identity map (кэш сессии) — если объект уже загружен, SELECT не делается. Возвращает None, если запись не найдена.

with Session(engine) as session:
    user = session.get(User, 42)        # SELECT, если нет в identity map
    if user is None:
        raise ValueError("User not found")

    # Второй вызов — из кэша, без SQL:
    same_user = session.get(User, 42)   # нет SELECT
    assert user is same_user            # один и тот же объект

Для SQLAlchemy 2.0 можно передать опции загрузки:

from sqlalchemy.orm import joinedload

user = session.get(
    User,
    42,
    options=[joinedload(User.orders)]
)

Сравнение

  • add() — регистрирует новый или возвращённый объект; INSERT при flush.
  • merge() — копирует состояние detached-объекта в managed; может SELECT + UPDATE.
  • get() — поиск по PK с кэшированием в identity map; SELECT только при промахе кэша.

Подводные камни

  • session.add(detached_obj) вместо merge() бросит DetachedInstanceError при обращении к lazy-атрибутам после повторного attach.
  • merge() делает SELECT по PK даже если вы знаете, что запись существует — это лишний roundtrip в hot path.
  • get() обходит фильтры soft-delete: если строка есть в БД, она вернётся, даже если ваш query-default добавляет WHERE deleted_at IS NULL.
  • После commit() все persistent-объекты становятся expired (при expire_on_commit=True). Следующее обращение к атрибуту вызовет lazy SELECT — неожиданно для кода, который «просто читает поле».
  • session.add() на объект с уже занятым PK (конфликт) упадёт только при flush, а не сразу — ошибка может всплыть далеко от места добавления.
  • В async-коде (AsyncSession) get() становится await session.get(...) — синхронные привычки ломают event loop.
  • merge() не подходит для bulk upsert: при 1000 записей это 1000 SELECT + 1000 UPDATE. Используйте insert().on_conflict_do_update().

Типичные ошибки

  • Описывать add merge get только как термин и не показывать механизм на минимальном примере.
  • Игнорировать ошибки, пустые данные, конкурентный доступ или границы транзакции.
  • Не связывать поведение с официальным контрактом SQLAlchemy и реальной эксплуатацией.

Что проверяет интервьюер

  • Объясняет add merge get через последовательность действий, а не через набор ключевых слов.
  • Приводит короткий кодовый пример или production-сценарий с ожидаемым поведением.
  • Называет хотя бы один риск: производительность, безопасность, транзакции, память или сопровождение.

Как вы знаете этот вопрос?

Проверить себя по теме SQLAlchemy →

Источники

  • https://docs.sqlalchemy.org/en/20/orm/session_basics.html
←Предыдущий вопросВ чём разница между `expire_on_commit=True` и `expire_on_commit=False`?Следующий вопрос→Расскажите о случае, когда SQLAlchemy помог или помешал вам при миграциях, транзакциях, оптимизации запросов или борьбе с N+1.

Связанные темы

SQLAlchemydatabase-designtechnical-reasoning

Частые вопросы на собеседовании

  • Как решить проблему N+1 запросов в SQLAlchemy с помощью selectinload или joinedload?
  • Как работает Session в SQLAlchemy и что такое паттерн Unit of Work?
  • Как делать zero-downtime миграции с Alembic и SQLAlchemy models?
  • Что такое Engine в SQLAlchemy и как работает пул соединений?