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.
- 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
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.
- add possibility to fetch raw data efficiently (http://bytebucket.org/namlook/mongokit/wiki/html/tutorial.html#getting-raw-data)
- add connection sharing beetween documents (http://bytebucket.org/namlook/mongokit/wiki/html/tutorial.html#changing-collection-dynamically)
- add connection size validation ()
- fix issue with compound keys indexes. Some indexes description are deprecated. (http://bytebucket.org/namlook/mongokit/wiki/html/tutorial.html#indexes)
- collection are now passed to the result objects when making a query.
(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)
- add autoref support to belong_to (delete cascade) (http://bytebucket.org/namlook/mongokit/wiki/html/cascade.html#delete-cascade)
- changing collection dynamically (http://bytebucket.org/namlook/mongokit/wiki/html/tutorial.html#changing-collection-dynamically)
- add immutable field (python tuple support) (http://bytebucket.org/namlook/mongokit/wiki/html/tutorial.html#case-of-tuple-or-immutable-field)
- add direction and ttl to index support (http://bytebucket.org/namlook/mongokit/wiki/html/tutorial.html#indexes)
- add connection sharing support (http://bytebucket.org/namlook/mongokit/wiki/html/tutorial.html#sharing-connection)
- add json import/export for MongoDocument (http://bytebucket.org/namlook/mongokit/wiki/html/tutorial.html#json-support)
- full relation support (related_to) (http://bytebucket.org/namlook/mongokit/wiki/html/relations.html)
- add long type support
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()
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'}
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.
- 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