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

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

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

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

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

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

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

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

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

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

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

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

Все подборки
  • Python5 973
  • Облачные технологии4 523
  • QA вакансии1 689
  • Android1 143
  • Инженер данных788
  • Продакт-менеджер308

Разработка

  • iOS1 093
  • Backend вакансии1 020
  • Fullstack вакансии448
  • AI вакансии378
  • Frontend вакансии369
  • Mobile вакансии27

По стеку

  • Go3 345
  • Java2 037
  • Kotlin908
  • Node.js746
  • Rust492
  • .NET481
  • PHP278
  • C++213
  • C#199

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

  • Kubernetes2 562
  • Linux-инфраструктура2 030
  • DevOps вакансии1 855
  • Terraform / IaC1 548
  • CI/CD876
  • Мониторинг и Observability709
  • SRE229
  • Кибербезопасность40

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

  • Аналитик данных479
  • Data Scientist443
  • Бизнес-аналитик342
  • Системный аналитик50

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

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

По регионам

  • Вакансии в США24 039
  • Вакансии в Европе9 373
  • Работа в России2 968
  • Вакансии в Канаде2 114

По формату

  • Удалённые вакансии41 595
  • Релокация в США24 039
  • Гибридная работа3 695
  • Офисная работа2 766

По уровню

  • Senior вакансии20 330
  • Middle вакансии11 778
  • Junior вакансии3 695

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

Все компании
  • Rakuten189 вакансий
  • ASML163 вакансии
  • Grab134 вакансии
  • Wise81 вакансия
  • Infobip28 вакансий
  • Darktrace17 вакансий
  • Spotify17 вакансий
  • Celonis14 вакансий
  • UiPath13 вакансий
  • Adyen9 вакансий

Вакансии из 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

Вакансии с этим навыком

  • Python developer

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

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