| Info: | MongoEngine is an ORM-like layer on top of PyMongo. |
|---|---|
| Repository: | https://github.com/MongoEngine/mongoengine |
| Author: | Harry Marr (http://github.com/hmarr) |
| Maintainer: | Bastien Gerard (http://github.com/bagerard) |
MongoEngine is a Python Object-Document Mapper for working with MongoDB. Documentation is available at https://mongoengine-odm.readthedocs.io - there is currently a tutorial, a user guide, and an API reference.
MongoEngine is currently tested against MongoDB v3.6, v4.0, v4.4, v5.0, v6.0, v7.0 and v8.0. Future versions should be supported as well, but aren't actively tested at the moment. Make sure to open an issue or submit a pull request if you experience any problems with a more recent MongoDB versions.
We recommend the use of virtualenv and of
pip. You can then use python -m pip install -U mongoengine.
You may also have setuptools
and thus you can use easy_install -U mongoengine. Another option is
pipenv. You can then use pipenv install mongoengine
to both create the virtual environment and install the package. Otherwise, you can
download the source from GitHub and
run python setup.py install.
For async support, you need PyMongo 4.13+ and can install it with:
# Install MongoEngine with async support
$ python -m pip install mongoengine[async]The support for Python2 was dropped with MongoEngine 0.20.0
All of the dependencies can easily be installed via python -m pip. At the very least, you'll need these packages to use MongoEngine:
- pymongo>=3.12 (for synchronous operations)
- pymongo>=4.13 (for asynchronous operations)
If you utilize a DateTimeField, you might also use a more flexible date parser:
- dateutil>=2.1.0
If you need to use an ImageField or ImageGridFsProxy:
- Pillow>=7.0.0
If you need to use signals:
- blinker>=1.3
Some simple examples of what MongoEngine code looks like:
MongoEngine provides comprehensive asynchronous support using PyMongo's AsyncMongoClient. All major database operations are available with async/await syntax:
import datetime
import asyncio
from mongoengine import *
async def main():
# Connect asynchronously
await connect_async('mydb')
# Document operations
post = TextPost(title='Async Post', content='Async content')
await post.async_save()
await post.async_reload()
await post.async_delete()
# QuerySet operations
post = await TextPost.objects.async_get(title='Async Post')
posts = await TextPost.objects.filter(tags='python').async_to_list()
count = await TextPost.objects.async_count()
# Async iteration
async for post in TextPost.objects.filter(published=True):
print(post.title)
# Bulk operations
await TextPost.objects.filter(draft=True).async_update(published=True)
await TextPost.objects.filter(old=True).async_delete()
# Reference field async fetching
# In async context, references return AsyncReferenceProxy
if hasattr(post, 'author'):
author = await post.author.async_fetch()
# Transactions
from mongoengine import async_run_in_transaction
async with async_run_in_transaction():
await post1.async_save()
await post2.async_save()
# GridFS async operations
from mongoengine import FileField
class MyDoc(Document):
file = FileField()
doc = MyDoc()
await MyDoc.file.async_put(file_data, instance=doc)
# Context managers
from mongoengine import async_switch_db
async with async_switch_db(MyDoc, 'other_db'):
await doc.async_save()
asyncio.run(main())Supported Async Features:
- Document Operations: async_save(), async_delete(), async_reload()
- QuerySet Operations: async_get(), async_first(), async_count(), async_create()
- Bulk Operations: async_update(), async_delete(), async_update_one()
- Async Iteration: Support for
async forwith QuerySets - Reference Fields: async_fetch() for explicit dereferencing
- GridFS: async_put(), async_get(), async_read(), async_delete()
- Transactions: async_run_in_transaction() context manager
- Context Managers: async_switch_db(), async_switch_collection()
- Aggregation: async_aggregate(), async_distinct()
- Cascade Operations: Full support for all delete rules (CASCADE, NULLIFY, etc.)
Current Limitations:
The following features are intentionally not implemented due to low priority or complexity:
async_values(), async_values_list(): Field projection methods
Reason: Low usage frequency in typical applications. Can be implemented if needed.
async_explain(): Query execution plan analysis
Reason: Debugging/optimization feature with limited general use.
Hybrid Signal System: Automatic sync/async signal handling
Reason: High complexity due to backward compatibility requirements. Consider as separate project if needed.
ListField with ReferenceField: Automatic AsyncReferenceProxy conversion
Reason: Complex implementation requiring deep changes to ListField. Manual async dereferencing is required for now.
Migration Guide:
- Use
connect_async()instead ofconnect() - Add
async_prefix to all database operations:save()→async_save() - Use
async forfor QuerySet iteration - Explicitly fetch references with
await ref.async_fetch()in async context - Existing synchronous code remains 100% compatible when using
connect()
To run the test suite, ensure you are running a local instance of MongoDB on
the standard port and have pytest installed. Then, run pytest tests/.
To run the test suite on every supported Python and PyMongo version, you can
use tox. You'll need to make sure you have each supported Python version
installed in your environment and then:
# Install tox
$ python -m pip install tox
# Run the test suites
$ toxWe welcome contributions! See the Contribution guidelines