Table Of Contents

Previous topic

MongoKit Documentation

Next topic

MongoKit Tutorial

This Page

MongoKit

MongoDB is a great schema-less document oriented database. It have a lot of driver for many langages (python, ruby, perl, java, php...).

MongoKit is a python module that brings structured schema and validation layer on top of the great pymongo driver. It has be written to be simpler and lighter as possible with the KISS and DRY principles in mind.

Features

  • schema validation (wich use simple python type for the declaration)
  • doted notation
  • nested and complex schema declaration
  • required fields validation
  • default values
  • custom validators
  • inheritance and polymorphisme support
  • delete cascade support
  • versionized document support (still in alpha stage)
  • partial auth support (it brings a simple User model)
  • Pylons Web Framework integration support
  • Operator for validation (currently : OR, NOT and IS)
  • Mongodb auth support
  • full relation support

A quick example

MongoDocument are enhanced python dictionnary with a validate() method. A MongoDocument declaration look like that:

>>> from mongokit import MongoDocument
>>> import datetime

>>> class BlogPost(MongoDocument):
...     db_name = 'test'
...     collection_name = 'tutorial'
...     structure = {
...             'title':unicode,
...             'body':unicode,
...             'author':unicode,
...             'date_creation':datetime.datetime,
...             'rank':int
...     }
...     required_fields = ['title','author', 'date_creation']
...     default_values = {'rank':0, 'date_creation':datetime.datetime.utcnow}
...
>>> blogpost = BlogPost()
>>> blogpost['title'] = u'my title'
>>> blogpost['body'] = u'a body'
>>> blogpost['author'] = u'me'
>>> blogpost.validate()
>>> blogpost # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
{'body': u'a body', 'title': u'my title', 'date_creation': datetime.datetime(...), 'rank': 0, 'author': u'me'}
>>> blogpost.save()

And you can use more complex structure:

>>> class ComplexDoc(MongoDocument):
...     db_name = 'test'
...     collection_name = 'tutorial'
...     structure = {
...         "foo" : {"content":int},
...         "bar" : {
...             int:{unicode:int}
...         }
...     }
...     required_fields = ['foo.content', 'bar.$int']

Please, see the tutorial for more examples.

Suggestion and patches are really welcome. If you find mistakes in the documentation (english is not my primary langage) feel free to contact me. You can find me (namlook) on the freenode #mongodb irc channel or on twitter.

Change Log

v.dev

(http://bytebucket.org/namlook/mongokit/wiki/html/tutorial.html#query) * a pymongo’s collection can now be pass to the constructor (http://bytebucket.org/namlook/mongokit/wiki/html/tutorial.html#changing-collection-dynamically)

v0.4

API change

Adding more authorized_types

authorized_types is not in the mongokit module anymore but has been integrated to the MongoDocument object. This allow to changed dynamically the authorized_types list at runtime.

So, if you wan to add more types in authorized_types, you need to do:

>>> class MyDoc(MongoDocument):
...     structure = {
...         "foo":str,
...     }
...     authorized_types = MongoDocument.authorized_types + [str]
>>> mydoc = MyDoc()
>>> mydoc['foo'] = 'bla'
>>> mydoc.validate()
New CustomType API
The CustomType api has little changed.
  • You must specify a mongo_type property in the CustomType class. this will describes the type of the value stored in the mongodb.
  • If you want more validation, you can specify a python_type property which is the python type the value will be converted. This is a good thing to specify it as it make a good documentation.
  • There is no custom_types descriptor anymore. The CustomType is set directly in the field. Plus, the CustomType must be instanciated.

So, the new way of using CustomType look like this:

>>> class CustomDate(CustomType):
...     mongo_type = unicode
...     python_type = datetime.datetime # optional, just for more validation
...     def to_bson(self, value):
...         """convert type to a mongodb type"""
...         return unicode(datetime.datetime.strftime(value,'%y-%m-%d'))
...     def to_python(self, value):
...         """convert type to a python object"""
...         if value is not None:
...            return datetime.datetime.strptime(value, '%y-%m-%d')

Now, let's create a MongoDocument:

>>> class Foo(MongoDocument):
...     db_name = 'test'
...     collection_name = 'tutorial'
...     structure = {
...         'foo':{
...             'date': CustomDate(),
...         },
...     }
...     default_values = {'foo.date':u'08-06-07'}
Autoreference

The internal structure of processing embeded document as changed and use the CustomType way. The advantage is that your data are not pollued by extra field anymore. So the ‘_ns’ field is not added any more.

v0.3.3

  • add autoref support (thanks to @bwmcadams)
  • add mongodb index support (thanks to @marcammann)
  • adding CustomType (original idea from Phillip Oldham)
  • support now all type of subclassed supported type
  • add “delete cascade” feature
  • add the possibility to skip the validation layer for more performances
  • fix issue while passing queries to fetch() and update tutorial
  • self._collection must not be None in __init__
  • fix #11 - pylons_env extension documentation typo
  • add more complete test + docstring
  • fix issue #9 - bug with custom_types and nested dict in list