Урок 84. MongoDB и Python. Модули
⚡ Кратко: суть темы
MongoDB и Python — работаем с документоориентированной базой данных через библиотеку pymongo: подключаемся, добавляем, читаем, обновляем и удаляем документы.
- Устанавливаем
pip install pymongoи подключаемся черезMongoClient(...). - База и коллекция выбираются как
client["db_name"]иdb["collection_name"]. - Документы — обычные Python-словари. CRUD-методы:
insert_one,insert_many,find_one,find,update_one,update_many,delete_one,delete_many. - Обрабатывай ошибки через
pymongo.errors, а не голыйException. - Модуль — любой
.pyфайл. Пакет — папка с модулями и__init__.py. Используйif __name__ == "__main__", чтобы код не выполнялся при импорте.
Что запомнить: MongoDB не требует заранее заданной схемы, но документы нужно правильно фильтровать словарями-условиями.
Частая ошибка: перепутать фильтр и проекцию в find() или забыть, что find() возвращает курсор, а не список.
🗄️ MongoDB — документоориентированная база данных
Реляционные базы данных хранят данные в таблицах со строгой схемой: нужно заранее описать столбцы и их типы. MongoDB работает иначе: данные хранятся в документах — JSON-подобных записях, которые в Python представляются обычными словарями dict.
Такой подход удобен, когда:
- структура данных может меняться;
- записи содержат вложенные объекты или списки;
- нужно быстро прототипировать приложение без создания таблиц.
🔌 Подключение к MongoDB из Python
Для работы с MongoDB в Python используется библиотека pymongo. Установите её через pip:
pip install pymongo
Чтобы подключиться к серверу, создаём объект MongoClient и передаём строку подключения. В строке указываются логин, пароль, адрес сервера и параметры авторизации:
from pymongo import MongoClient
client = MongoClient(
"mongodb://ich_editor:verystrongpassword"
"@mongo.itcareerhub.de/?readPreference=primary"
"&ssl=false&authMechanism=DEFAULT&authSource=ich_edit"
)
Основные параметры строки подключения:
ich_editor— имя пользователя;verystrongpassword— пароль;mongo.itcareerhub.de— адрес сервера;authSource=ich_edit— база данных, в которой хранятся учётные данные.
Проверить подключение можно командой ping:
client.admin.command("ping")
print("Connection successful!")
🗂️ Выбор базы данных и коллекции
Базу данных и коллекцию можно выбрать через квадратные скобки:
db = client["ich_edit"]
products = db["products"]
Особенности MongoDB:
- Если база данных не существует, она создаётся автоматически при первой записи.
- Если коллекция не существует, она тоже создаётся при первой записи.
- Подключение устанавливается лениво — реальное соединение происходит при первом запросе.
В конце работы соединение можно закрыть вручную:
client.close()
➕ Добавление данных
В MongoDB данные добавляются в виде словарей. Можно добавить один документ или сразу несколько:
# Один документ
product = {"name": "Notebook", "price": 5.99, "stock": 120}
result = products.insert_one(product)
print("Inserted ID:", result.inserted_id)
# Несколько документов
items = [
{"name": "Pen", "price": 1.50, "stock": 300},
{"name": "Pencil", "price": 0.99, "stock": 500},
]
result = products.insert_many(items)
print("Inserted IDs:", result.inserted_ids)
Если поле _id не указано, MongoDB создаёт его автоматически. В отличие от SQL, не нужно заранее описывать структуру коллекции.
🔍 Чтение данных
Для чтения используются методы find_one() и find():
doc = products.find_one() # первый документ или None
docs = products.find({"price": {"$lt": 5}}) # курсор с фильтром
for item in docs:
print(item)
Метод find() возвращает не список, а курсор — объект-итератор. Это позволяет обходить документы по одному, не загружая всё в память сразу. Курсор поддерживает методы sort(), skip() и limit():
for doc in products.find().sort("price", -1).skip(1).limit(2):
print(doc)
Чтобы ограничить набор возвращаемых полей, используется проекция:
# Только name, price и _id (по умолчанию)
for doc in products.find({}, {"name": 1, "price": 1}):
print(doc)
# Все поля, кроме _id
for doc in products.find({}, {"_id": 0}):
print(doc)
✏️ Обновление данных
Для изменения документов используются update_one() и update_many(). Первый аргумент — фильтр, второй — модификатор:
# Изменить один документ
result = products.update_one(
{"name": "Notebook"},
{"$set": {"price": 24.99}}
)
print("Matched:", result.matched_count)
print("Modified:", result.modified_count)
# Увеличить цену всех товаров на 1
result = products.update_many(
{},
{"$inc": {"price": 1}}
)
🗑️ Удаление данных
Удаление работает аналогично обновлению: один документ или все подходящие под условие:
result = products.delete_one({"name": "Notebook"})
print("Deleted:", result.deleted_count)
result = products.delete_many({"price": {"$lt": 2}})
print("Deleted:", result.deleted_count)
⚠️ Обработка ошибок
При работе с MongoDB могут возникать ошибки подключения, авторизации или запросов. Их нужно перехватывать через try ... except:
from pymongo import MongoClient, errors
try:
client = MongoClient("mongodb://ich_editor:wrong_pass@mongo.itcareerhub.de/?authSource=ich_edit")
db = client["store"]
products = db["products"]
products.insert_one({"name": "Lamp", "price": 15.99})
except errors.ConnectionFailure:
print("Ошибка подключения к MongoDB")
except errors.OperationFailure:
print("Ошибка авторизации или запроса")
Основные исключения:
errors.ConnectionFailure— ошибка подключения к серверу;errors.OperationFailure— ошибка выполнения запроса или неправильные права;errors.DuplicateKeyError— попытка вставить документ с уже существующим_id;errors.PyMongoError— базовый класс для всех исключений pymongo.
📦 Модули в Python
Модуль — это любой файл с расширением .py, содержащий переменные, функции, классы и другие конструкции Python.
Модули позволяют:
- разделять код по смыслу;
- повторно использовать готовые решения;
- использовать стандартную библиотеку Python (
math,random,datetime); - устанавливать сторонние библиотеки через
pip(pymongo,requestsи др.); - упрощать тестирование и поддержку кода.
Виды модулей:
| Тип | Примеры | Как получить |
|---|---|---|
| Встроенные | math, random, datetime | Входят в состав Python |
| Сторонние | pymongo, requests | Устанавливаются через pip |
| Пользовательские | Любые .py-файлы | Пишутся самостоятельно |
Пример пользовательского модуля math_utils.py:
def average(numbers):
return sum(numbers) / len(numbers)
def maximum(numbers):
return max(numbers)
Использование в другом файле:
import math_utils
from math_utils import maximum
values = [10, 20, 30]
print(math_utils.average(values))
print(maximum(values))
🚀 Прямой запуск модуля
Конструкция if __name__ == "__main__" позволяет отделить код, который выполняется только при прямом запуске файла, от кода, который работает при импорте:
def average(numbers):
return sum(numbers) / len(numbers)
if __name__ == "__main__":
# Этот блок выполнится только при запуске файла напрямую
print(average([1, 2, 3]))
При импорте модуля переменная __name__ равна имени модуля. При прямом запуске она равна "__main__".
⚙️ Компиляция модулей и __pycache__
Когда Python импортирует модуль, он компилирует его в байт-код и сохраняет в файл .pyc внутри папки __pycache__:
__pycache__/math_utils.cpython-312.pyc
Байт-код загружается быстрее, чем исходный .py файл. Файл .pyc пересоздаётся:
- при первом импорте модуля;
- если изменился исходный
.pyфайл; - если обновилась версия Python.
📁 Пакеты и папки
Пакет — это папка, содержащая модули и файл __init__.py. Пакеты позволяют группировать модули по смыслу и создавать вложенную структуру.
Пример структуры:
modules/
├── main.py
├── math_utils.py
├── analyzer.py
└── tools/
├── __init__.py
├── text_utils.py
└── helpers/
├── __init__.py
└── string_tools.py
Файл __init__.py может быть пустым, но часто в нём делают удобные импорты:
# tools/__init__.py
from .text_utils import count_words
from .helpers.string_tools import reverse
Тогда вне пакета можно писать:
import tools
print(tools.count_words("Hello world"))
print(tools.reverse("Python"))
__init__.py может считаться пространством имён (namespace package), но для обычных учебных проектов файл __init__.py остаётся стандартом.
✨ Современные практики
mongoengine или beanie).
- Храните пароли и логины в переменных окружения, а не в коде.
- Для локальной разработки удобна библиотека
python-dotenv: положите секреты в файл.envи загрузите черезload_dotenv(). - Закрывайте соединение с MongoDB через
client.close()или используйте контекстный менеджер. - Разделяйте код на модули: подключение к базе, бизнес-логика и запуск приложения — в разных файлах.
- Используйте
if __name__ == "__main__", чтобы тестовый код не выполнялся при импорте.