Урок 84. MongoDB и Python. Модули
⚡ Кратко: что меняется
- SQL: таблицы, строки, фиксированная схема, JOIN-запросы. NoSQL (MongoDB): документы, словари, гибкая схема, вложенные данные.
- Старый подход: один большой скрипт, где всё смешано — подключение, логика и вывод.
- Новый подход: код разбит на модули: подключение, бизнес-логика, запуск. Используй
if __name__ == "__main__".
⚖️ SQL vs NoSQL: разный подход к данным
В реляционных базах данных данные хранятся в таблицах, а связи между ними описываются через внешние ключи и JOIN-запросы. В MongoDB данные хранятся в документах, и часто связанные данные можно хранить вместе.
SQL-мышление
# Реляционный подход: две таблицы и JOIN
SELECT p.name, c.name
FROM products p
JOIN categories c ON p.category_id = c.id
WHERE p.price < 5
Недостатки:
- Нужно заранее проектировать схему.
- Изменение структуры требует миграций.
- Сложные связи делают запросы громоздкими.
NoSQL-мышление
# MongoDB: документ содержит все нужные поля
for doc in products.find({"price": {"$lt": 5}}):
print(doc["name"], doc.get("category"))
Преимущества:
- Нет жёсткой схемы — документы могут иметь разные поля.
- Запросы ближе к структурам данных Python.
- Легко добавлять новые поля без миграций.
⚠️ Проверить по документации: MongoDB поддерживает агрегации и ссылки между коллекциями через
DBRef и $lookup. Для сложных отношений иногда всё же используют нормализацию данных, как в SQL.
📜 Монолитный скрипт vs модульный код
Когда программа маленькая, удобно держать всё в одном файле. Но по мере роста проекта код становится сложно читать и поддерживать.
Старый подход: всё в одном файле
from pymongo import MongoClient
client = MongoClient("mongodb://...")
db = client["ich_edit"]
products = db["products"]
product = {"name": "Notebook", "price": 5.99, "stock": 120}
products.insert_one(product)
for doc in products.find():
print(doc)
client.close()
Недостатки:
- Подключение к базе смешано с бизнес-логикой.
- Код нельзя переиспользовать в других скриптах.
- Секреты (логин, пароль) хранятся прямо в основном файле.
Новый подход: разделение на модули
Файл: db.py
from pymongo import MongoClient
MONGO_URI = "mongodb://..."
def get_collection(name):
client = MongoClient(MONGO_URI)
return client["ich_edit"][name]
Файл: products_service.py
from db import get_collection
def add_product(name, price, stock):
products = get_collection("products")
result = products.insert_one({
"name": name,
"price": price,
"stock": stock,
})
return result.inserted_id
def list_products():
products = get_collection("products")
return list(products.find())
Файл: main.py
from products_service import add_product, list_products
if __name__ == "__main__":
add_product("Notebook", 5.99, 120)
for product in list_products():
print(product)
Преимущества:
- Каждый модуль отвечает за одну задачу.
- Логику легко тестировать и переиспользовать.
- Точка входа в программу отделена от реализации.
📊 Сравнение в таблице
| Аспект | Старый подход | Новый подход |
|---|---|---|
| Структура данных | Таблицы и строки (SQL) | Документы и словари (NoSQL) |
| Схема | Фиксированная | Гибкая |
| Организация кода | Один большой скрипт | Несколько модулей и пакетов |
| Повторное использование | Сложно | Легко через import |
| Тестирование | Сложно изолировать части | Можно тестировать модули отдельно |
| Точка входа | Код выполняется при импорте | Код выполняется только под if __name__ == "__main__" |
⚠️ Проверить по документации: в production-проектах для управления конфигурацией и секретами используют переменные окружения, файлы
.env и библиотеки вроде pydantic-settings. Выбор между SQL и NoSQL зависит от задачи: для сложных транзакций часто выбирают SQL, для гибких схем — NoSQL.