Какие основные библиотеки для работы с базами данных в Python существуют
Что проверяют
Понимаете ли вы, что библиотеки для работы с базой живут на разных уровнях: драйвер, построитель запросов, ORM. И умеете ли выбрать уровень под задачу. Следом обычно спрашивают, чем SQLAlchemy Core отличается от ORM и как работать с базой из асинхронного кода.
Как отвечать
Разложите ответ по слоям, от нижнего к верхнему:
- драйверы DB-API 2.0 (PEP 249): единый интерфейс
connect(),cursor(),execute(),commit(). Его реализуютsqlite3из стандартной библиотеки,psycopgтретьей версии для PostgreSQL (psycopg2живёт в старых проектах),PyMySQLиmysqlclientдля MySQL; - асинхронные драйверы:
asyncpgдля PostgreSQL со своим API вне DB-API,aiosqlite, асинхронный режимpsycopg3; - SQLAlchemy 2.x: два слоя. Core собирает SQL из выражений и держит пул соединений, ORM маппит классы на таблицы и ведёт
Sessionпо схеме unit of work. Модели объявляются черезDeclarativeBaseиMapped[...], запросы черезselect()иsession.execute(), для asyncio естьAsyncSession. Миграции делает Alembic; - Django ORM: встроен во фреймворк, миграции из коробки через
makemigrationsиmigrate; - лёгкие ORM: Peewee для небольших проектов, SQLModel поверх SQLAlchemy и Pydantic для FastAPI;
- NoSQL:
pymongoдля MongoDB (у него теперь есть свой асинхронный клиент, а Motor выводится из поддержки),redis-pyс модулемredis.asyncio.
Закончите правилом выбора: сырой драйвер там, где важны скорость и полный контроль над SQL, ORM там, где много сущностей и связей. И упомяните, что из ORM всегда можно выполнить свой SQL через text().
Где спотыкаются
Показывают код с declarative_base() из sqlalchemy.ext.declarative и session.query(). Первое устарело ещё в 1.4, второе в 2.x числится legacy API, и интервьюер видит, что вы давно не открывали документацию.
Собирают запрос f-строкой вместо параметров. Плейсхолдеры %s в psycopg и ? в sqlite3 существуют ровно для защиты от SQL-инъекций.
Зовут синхронный драйвер внутри асинхронного обработчика FastAPI и блокируют event loop. Рядом вторая ошибка: ленивая загрузка связей в цикле, классический N+1, его лечат selectinload() или joinedload().