⚡ Кратко
Сравниваем старые и современные подходы при разработке консольного магазина книг.
- Монолитный скрипт → модули по ответственности.
- Пароль в коде → переменные окружения.
- Python-агрегация в памяти → MongoDB aggregation pipeline.
- Конкатенация SQL → параметризованные запросы.
⚖️ Монолитный скрипт vs модульная архитектура
| Монолит | Модули | Зачем менять |
Весь код в одном bookstore.py |
main.py, auth.py, user_actions.py, search_logs.py |
Легче читать, тестировать и искать ошибки |
| Переменные и функции общего назначения перемешаны |
Каждый файл отвечает за одну задачу |
Разделение ответственности |
| При импорте выполняется весь скрипт |
Используется if __name__ == "__main__" |
Можно импортировать функции без побочных эффектов |
⚖️ Ручное подключение vs переменные окружения
| Старый подход | Современный подход | Риск старого |
MongoClient("mongodb://user:pass@host...") прямо в коде |
Хранить URI в .env и загружать через os.environ или python-dotenv |
Пароль попадает в Git и становится публичным |
| Конфигурация разбросана по файлам |
Централизованный config.py |
Сложно менять настройки и следить за секретами |
⚖️ Агрегация на Python vs пайплайн MongoDB
| Агрегация на Python | MongoDB aggregation | Когда что |
Загружаем все документы, считаем Counter |
Считаем прямо на сервере через $group, $sort, $limit |
Python удобен для небольших данных; MongoDB — для больших объёмов |
| Простая для понимания, не требует знания операторов |
Экономит память и сеть |
Учебный проект может использовать любой способ |
⚖️ Inline-SQL vs параметризованные запросы
| Конкатенация строк | Параметризованный запрос |
f"SELECT * FROM books WHERE title LIKE '%{keyword}%'" |
cursor.execute("SELECT * FROM books WHERE title LIKE %s", (f"%{keyword}%",)) |
| Уязвим к SQL-инъекциям; ломается на кавычках |
Библиотека экранирует значения сама |