MongoEngine – работа с MongoDB

онлайн тренер по питону
Онлайн-тренажер Python 3 для начинающих

Теория без воды. Задачи с автоматической проверкой. Подсказки на русском языке. Работает в любом современном браузере.

начать бесплатно

Введение

С развитием NoSQL баз данных всё больше Python-разработчиков выбирают MongoDB для хранения данных. Это объясняется гибкостью, масштабируемостью и документо-ориентированной структурой. Чтобы упростить взаимодействие с MongoDB, создана библиотека MongoEngine — объектно-документный маппер (ODM), позволяющий работать с документами MongoDB, как с Python-объектами.

MongoEngine – работа с MongoDB предоставляет мощный, но в то же время простой интерфейс для определения моделей, выполнения запросов и валидации данных без необходимости писать сложный MongoDB-специфичный код.

Основы MongoDB и роль MongoEngine

NoSQL и документо-ориентированное хранение

MongoDB — это документо-ориентированная база данных, в которой данные хранятся в формате BSON (бинарный JSON). Это делает MongoDB гибкой, особенно при работе со сложными вложенными структурами данных.

Объектно-документное отображение (ODM)

ODM (Object Document Mapper) работает по аналогии с ORM, но вместо таблиц и строк оперирует документами и коллекциями. MongoEngine реализует ODM-абстракции для MongoDB, предоставляя чистый и питоничный API.

Установка и настройка MongoEngine

Установка библиотеки:

bash
pip install mongoengine

Подключение к базе:

python
from mongoengine import connect connect(db='library', host='localhost', port=27017)

Также поддерживаются строки подключения:

python
connect(host='mongodb://localhost:27017/library')

Создание моделей в MongoEngine

Пример модели Author:

python
from mongoengine import Document, StringField, DateField class Author(Document): name = StringField(required=True) birth_date = DateField()

MongoEngine использует классы Python для описания структуры документов, а поля определяются как объекты типа StringField, DateField, IntField, ListField и т.д.

CRUD-операции в MongoEngine

  • Создание:

python
author = Author(name="Лев Толстой", birth_date="1828-09-09") author.save()
  • Чтение:

python
authors = Author.objects()
  • Фильтрация:

python
Author.objects(name="Лев Толстой")
  • Обновление:

python
author.update(set__name="Толстой Лев Николаевич")
  • Удаление:

python
author.delete()

Работа с вложенными документами

Вложенные документы описываются через EmbeddedDocument:

python
from mongoengine import EmbeddedDocument, EmbeddedDocumentField, ListField class Address(EmbeddedDocument): city = StringField() street = StringField() class Reader(Document): name = StringField() addresses = ListField(EmbeddedDocumentField(Address))

Валидация данных и ограничения

Поля могут иметь ограничения:

python
name = StringField(required=True, max_length=100, unique=True)

Можно реализовать кастомную валидацию через метод clean():

python
def clean(self): if self.name == "": raise ValidationError("Имя не может быть пустым")

Связи между документами

MongoEngine поддерживает связи между коллекциями:

  • ReferenceField: ссылка на другой документ

  • GenericReferenceField: динамическая ссылка

python
from mongoengine import ReferenceField class Book(Document): title = StringField() author = ReferenceField(Author)

Индексация и производительность

  • Индексация:

python
class Meta: indexes = ['name']
  • Уникальные индексы:

python
name = StringField(unique=True)

MongoDB автоматически использует индексы при выполнении запросов, что ускоряет выборку.

Интеграция с Flask и FastAPI

Flask

python
from flask import Flask from mongoengine import connect app = Flask(__name__) connect(db='mydb', host='localhost', port=27017)

FastAPI

Для FastAPI можно использовать MongoEngine совместно с motor для async, или выполнять действия через зависимости.

Пример через BackgroundTasks:

python
from mongoengine import Document class Task(Document): title = StringField()

Работа с транзакциями и сессиями MongoDB

MongoEngine поддерживает работу с сессиями начиная с MongoDB 4.0:

python
with Author._get_collection().database.client.start_session() as session: with session.start_transaction(): Author(name="Иван Тургенев").save()

Тестирование с MongoEngine

Можно использовать mongomock:

bash
pip install mongomock

И подключать тестовую базу:

python
connect('testdb', host='mongomock://localhost')

Сравнение с другими ODM и драйверами

Характеристика MongoEngine Pymongo Motor Beanie
Стиль Классы Низкоуровневый Асинхронный Асинхронный + Pydantic
Подходит для Простых проектов Полного контроля Async API FastAPI
Валидация Да Нет Нет Да
Асинхронность Нет (по умолчанию) Нет Да Да

Будущее MongoEngine и активность проекта

MongoEngine — зрелая и стабильная библиотека, поддерживаемая сообществом. Разработка ведётся на GitHub, и библиотека регулярно обновляется.

Часто задаваемые вопросы (FAQ)

1. Что такое MongoEngine?
ODM-библиотека для работы с MongoDB в Python.

2. Поддерживает ли MongoEngine связи между коллекциями?
Да, через ReferenceField, GenericReferenceField.

3. Можно ли использовать MongoEngine с Flask?
Да, легко интегрируется.

4. Есть ли поддержка асинхронности?
Нет, но можно использовать в FastAPI через BackgroundTasks или заменить на Beanie/Motor.

5. Как тестировать MongoEngine?
С помощью mongomock или тестовой базы MongoDB.

6. Чем MongoEngine лучше Pymongo?
Более высокий уровень абстракции, лаконичный синтаксис и валидация данных.

Полный справочник по ключевым функциям и модулям библиотеки MongoEngine для Python

Установка

bash
pip install mongoengine

Также установите MongoDB и запустите сервер MongoDB локально или удалённо.


Подключение к базе данных

Функция Описание
connect(db_name) Подключается к локальной MongoDB.
connect(db, host, port) Подключение с параметрами.
disconnect() Закрывает соединение.
python
from mongoengine import connect connect("mydatabase")

Определение моделей (документов)

Компонент Описание
Document Базовый класс для модели (сохранение в коллекцию).
EmbeddedDocument Вложенный документ (хранится внутри других документов).
class MyModel(Document) Определение коллекции и её структуры.
meta = {'collection': 'имя_коллекции'} Задание имени коллекции.
python
from mongoengine import Document, StringField, IntField class User(Document): name = StringField(required=True) age = IntField(min_value=0)

Типы полей

Поле Описание
StringField() Строка.
IntField() / FloatField() Числа.
BooleanField() Булев тип.
DateTimeField() Дата и время.
EmailField() Проверка e-mail.
URLField() Проверка URL.
ListField(Field) Список вложенных значений.
DictField() Словарь.
ReferenceField(Model) Связь с другим документом.
EmbeddedDocumentField() Вложенный документ.
ObjectIdField() ObjectId MongoDB.

Сохранение, обновление и удаление

Метод Описание
.save() Сохраняет или обновляет документ.
.update(**fields) Обновляет значения в БД.
.delete() Удаляет документ.
Model.objects.update(...) Массовое обновление.
python
user = User(name="Ваня", age=25) user.save() user.update(age=26) user.delete()

Запросы и фильтрация

Метод Описание
User.objects(...) Все документы.
.filter(field=value) Фильтрация.
.get(field=value) Один объект (или исключение DoesNotExist).
.first() / .last() Первый / последний результат.
.count() Количество.
.order_by('+field') Сортировка по возрастанию (-field — по убыванию).
.only('field') / .exclude('field') Выбор/исключение полей.
python
users = User.objects(age__gte=18) user = User.objects.get(name="Ваня")

Условия поиска (операторы)

Синтаксис Описание
field__lt=5 Меньше 5
field__lte=5 Меньше или равно
field__gt=5 Больше
field__in=[...] Вхождение в список
field__contains="подстрока" Поиск подстроки
field__exists=True Наличие поля

Вложенные документы (EmbeddedDocument)

python
from mongoengine import EmbeddedDocument, EmbeddedDocumentField, ListField class Address(EmbeddedDocument): city = StringField() zip = StringField() class User(Document): name = StringField() address = EmbeddedDocumentField(Address)

Связи между коллекциями

Тип Описание
ReferenceField Однонаправленная связь на другой документ.
LazyReferenceField Отложенная загрузка (экономит ресурсы).
CASCADE, DENY, NULLIFY Поведение при удалении связанных объектов.
python
class Post(Document): title = StringField() author = ReferenceField(User, reverse_delete_rule=CASCADE)

Валидация

Возможности Описание
required=True Обязательное поле.
min_length, max_length Длина строки.
min_value, max_value Ограничения чи