MotorEngine MongoDB Async ORM

MotorEngine is a port of the amazing MongoEngine.

https://travis-ci.org/heynemann/motorengine.png https://img.shields.io/pypi/v/motorengine.svg https://coveralls.io/repos/heynemann/motorengine/badge.png?branch=master

Supported Versions

MotorEngine is compatible and tested against python 2.7, 3.5, 3.6, pypy2 and pypy3.

MotorEngine requires MongoDB 2.2+ due to usage of the Aggregation Pipeline.

The tests of compatibility are always run against the current stable version of MongoEngine.

Why use MotorEngine?

If you are using tornado, most certainly you don’t want your ioLoop to be blocked while doing I/O to mongoDB.

What that means is that MotorEngine allows your tornado instance to keep responding to requests while mongoDB performs your queries.

That’s all fine and good, but why choose MotorEngine?

Mainly because MotorEngine helps you in defining consistent documents and makes querying for them really easy.

Defining Documents

Defining a new document is as easy as:

from motorengine import Document, StringField

class User(Document):
    __collection__ = "users"  # optional. if no collection is specified, class name is used.

    first_name = StringField(required=True)
    last_name = StringField(required=True)

    @property
    def full_name(self):
        return "%s, %s" % (self.last_name, self.first_name)

MotorEngine comes baked in with the same fields as MongoEngine.

What about compatibility?

MotorEngine strives to be 100% compatible with MongoEngine as far as the data in mongoDB goes.

What that means is that it does not feature the same syntax as MongoEngine and vice-versa.

It does not make sense to support the exact same syntax, considering the asynchronous nature of MotorEngine.

Let’s see how you query documents using MotorEngine:

def get_active_users(callback):
    User.objects.filter(active=True).find_all(callback)

def handle_get_active_users(users):
    # do something with the users
    pass

get_active_users(handle_get_active_users)

Or if you are using the new style of doing asynchronous operations in Tornado:

def get_active_users():
    users = yield User.objects.filter(active=True).find_all()
    return users