(MONGO + TORnado) is an asynchronous toolkit for accessing mongo with tornado.
- ORM like to map documents and fields orm
- Advanced connection management (replica sets, slave okay)
- Automatic reconnection
- Connection pooling
- Support for running database commands (find, find_one, count, sum, mapreduce etc...)
- Signals for pre_save, post_save, pre_remove, post_remove, pre_update and post_update
- 100% of code coverage by test
MongoTor supports installation using standard Python “distutils” or “setuptools” methodologies. An overview of potential setups is as follows:
When easy_install or pip is available, the distribution can be downloaded from Pypi and installed in one step:
easy_install mongotor
Or with pip:
pip install mongotor
This command will download the latest version of MongoTor from the Python Cheese Shop and install it to your system.
Otherwise, you can install from the distribution using the setup.py script:
python setup.py install
The version of MongoTor installed can be checked from your Python prompt like this:
>>> import mongotor
>>> mongotor.version
This tutorial is meant to introduce you to the basic concepts of using MongoTor using an example application. The example application is a simple user database where people could fill in their information and register themselves.
- Ensure that an instance of MongoDB is running in an accessible location. This tutorial assumes that such an instance is running on the localhost.
A MongoDB Collection is the rough equivalent of a table in a relational database. Though MongoDB collections are schemaless documents in them usually have a similar structure. This “similar structure” could be defined as a Collection.
In this example application we define the structure of Users collection with the required field (s)
class User(Collection):
__collection__ = "user"
_id = ObjectIdField()
name = StringField()
active = BooleanField()
created = DateTimeField()
A connection to the MongoDB database needs to be established before MongoTor can manage collections or do any other operations. A connection is established using a Database object
from mongotor.database import Database
Database.connect('localhost:27017', 'test_db')
A new document can be created in the collection by creating an instance of the Collection, assigning values to the fields and then calling the save method
new_user = User()
new_user.name = "New user"
new_user.active = True
new_user.save()
A new instance would also be created from a dictionary (for example from a Form handler in your web application):
>>> new_user = User.create({'name': 'Some user name'})
>>> new_user.name
u'Some user name'
>>> new_user.save()
from mongotor.orm import Collection
from mongotor.orm.field import StringField, ObjectIdField, BooleanField, DateTimeField
from mongotor.database import Database
from datetime import datetime
import tornado.web
from tornado import gen
# A connection to the MongoDB database needs to be established before perform operations
# A connection is stabilished using a Databse object
Database.connect(['localhost:27017'], 'asyncmongo_test')
class User(Collection):
__collection__ = "user"
_id = ObjectIdField()
name = StringField()
active = BooleanField()
created = DateTimeField()
class Handler(tornado.web.RequestHandler):
@tornado.web.asynchronous
@gen.engine
def get(self):
user = User()
user.name = "User name"
user.active = True
user.created = datetime.now()
yield gen.Task(user.save)
# update date
user.name = "New name"
yield gen.Task(user.update)
# find one object
user_found = yield gen.Task(User.objects.find_one, user._id)
# find many objects
new_user = User()
new_user.name = "new user name"
new_user.user.active = True
new_user.created = datetime.now()
users_actives = yield gen.Task(User.objects.find, {'active': True})
users_actives[0].active = False
yield gen.Task(users_actives[0].save)
# remove object
yield gen.Task(user_found.remove)
MongoTor supports Client for direct access to mongo, without orm layer
from mongotor.database import Database
from bson import ObjectId
from tornado import gen, web
class Handler(web.RequestHandler):
def initialize(self):
self.db = Database.connect(['localhost:27017'], 'asyncmongo_test')
@web.asynchronous
@gen.engine
def get(self):
user = {'_id': ObjectId, 'name': 'User Name'}
yield gen.Task(self.db.user.insert, user)
yield gen.Task(self.db.user.update, user['_id'], {"$set": {'name': 'New User Name'}})
user_found = yield gen.Task(self.db.user.find_one, user['_id'])
assert user_found['name'] == 'New User Name'
yield gen.Task(self.db.user.remove, user['_id'])
MongoTor supports signals for pre_save, post_save, pre_remove, post_remove, pre_update, post_update to which receivers could bind to.
from mongotor.orm import collection, field
from mongotor.orm.signal import pre_save, receiver
from mongotor.database import Databas
from bson import ObjectId
import tornado.web
from tornado import gen
class User(collection.Collection):
__collection__ = "user"
_id = field.ObjectIdField()
name = field.StringField()
active = field.BooleanField()
created = field.DateTimeField()
@receiver(pre_save, User)
def set_object_id(sender, instance):
if not instance._id:
instance._id = ObjectId()
class Handler(tornado.web.RequestHandler):
@tornado.web.asynchronous
@gen.engine
def get(self):
user = User()
user.name = "User name"
user.active = True
user.created = datetime.now()
yield gen.Task(user.save)
str(object=’‘) -> string
Return a nice string representation of the object. If the argument is a string, the return value is the same object.
Alias for mongotor.database.Database.
Sub-modules:
Database object
connect database
this method is deprecated, use init to initiate a new database
Disconnect to database
>>> Database.disconnect()
Issue a MongoDB command.
Send command command to the database and return the response. If command is an instance of basestring then the command {command: value} will be sent. Otherwise, command must be an instance of dict and will be sent as is.
Any additional keyword arguments will be added to the final command document before it is sent.
For example, a command like {buildinfo: 1} can be sent using:
>>> db.command("buildinfo")
For a command where the value matters, like {collstats: collection_name} we can do:
>>> db.command("collstats", collection_name)
For commands that take additional arguments we can use kwargs. So {filemd5: object_id, root: file_root} becomes:
>>> db.command("filemd5", object_id, root=file_root)
Parameters: |
|
---|
Insert a document
Parameters: |
|
---|
remove a document
Parameters: |
---|
Update a document(s) in this collection.
Parameters: |
|
---|
Get a single document from the database.
All arguments to find() are also valid arguments for find_one(), although any limit argument will be ignored. Returns a single document, or None if no matching document is found.
Parameters: |
|
---|
Query the database.
The spec argument is a prototype document that all results must match. For example:
Parameters: |
|
---|
Get the size of the results among all documents.
Returns the number of documents in the results set
Get a list of distinct values for key among all documents in this collection.
Raises TypeError if key is not an instance of basestring (str in python 3).
To get the distinct values for a key in the result set of a query use distinct().
Parameters: |
|
---|
Perform an aggregation using the aggregation framework on this collection.
Parameters: |
|
---|
Note
Requires server version >= 2.1.0
Perform a query similar to an SQL group by operation.
Returns an array of grouped items.
The key parameter can be:
- None to use the entire document as a key.
- A list of keys (each a basestring (str in python 3)) to group by.
- A basestring (str in python 3), or Code instance containing a JavaScript function to be applied to each document, returning the key to group by.
Parameters: |
|
---|
Collection is the base class
This class map a mongo collection into a python class. You only need to write a class and starts to use the orm advantages.
For example, a simple users collection can be mapping using:
>>> from mongotor.orm import collection, field
>>> class Users(collection.Collection):
>>> __collection__ = 'users'
>>> name = field.StringField()
Save a document
>>> user = Users()
>>> user.name = 'should be name'
>>> user.save()
Parameters: |
|
---|
Remove a document
Parameters: |
---|
Update a document
Parameters: |
---|
Base class for all mongotor exceptions.
Raised when a connection to the database cannot be made or is lost.
Raised when a pool is busy.
Raised when a client attempts to perform an invalid operation.
Raised when a safe insert or update fails due to a duplicate key error.
Please report any issues via github issues