MongoX

MongoX is an async python ODM (Object Document Mapper) for MongoDB
which is built on top Motor and Pydantic.

The main features include:

  • Fully type annotated
  • Async support Python 3.7+ (since it’s built on top of Motor)
  • Elegant editor support (since it’s built on top of Pydantic)
  • Autocompletion everywhere, from object creation to query results
  • Custom query builder which is more intuitive and pythonic
  • 100% test coverage

MongoX models are at the same time Pydantic models and have the same functionalitties,
so you can use them with your existing Pydantic models.


Documentation: https://aminalaee.github.io/mongox


Installation

$ pip install mongox

Quickstart

You can define mongox models the same way you define Pydantic models.
The difference is they should inherit from mongox.Model now:

import asyncio

import mongox

client = mongox.Client(
    "mongodb://localhost:27017", get_event_loop=asyncio.get_running_loop
)
db = client.get_database("test_db")


class Movie(mongox.Model):
    name: str
    year: int

    class Meta:
        collection = db.get_collection("movies")

Now you can create some instances and insert them into the database:

movie = await Movie(name="Forrest Gump", year=1994).insert()

The returned result will be a Movie instance, and mypy
will understand that this is a Movie instance.
So you will have type hints and validations everywhere:

MongoX insert screenshot

Now you can fetch some data from the database.

You can use the same pattern as PyMongo/Motor:

movie = await Movie.query({"name": "Forrest Gump"}).get()

The returned result will be a Movie instance, and mypy
will understand that this is a Movie instance.

This will have great IDE support, autocompletion and validation.

MongoX get screenshot

Or you can use Movie fields instead of dictionaries in the query (less room for bugs):

movie = await Movie.query({Movie.name: "Forrest Gump"}).get()

And finally you can use a more intuitive query (limited yet):

movie = await Movie.query(Movie.name == "Forrest Gump").get()

Notice how we omitted the dictionary and passed the Movie fields in comparison.


Please refer to the documentation here or the full examples here.


GitHub

View Github