Using MongoDB in your Django app
- implications and benefits

By Peter Bengtsson, Fry-IT
www.peterbe.com

About me

  • 10 years RDBMS experience
  • 10 years NoSQL experience (ZODB)
  • 10 years Python experience

But I've never written my own ORM, templating language, web framework or blog engine

Why it matters

Crash course on MongoDB

  • "MongoDB is a scalable, high-performance, open source, document-oriented database. Written in C++"
  • BSON (JSON + datetime)
  • Auto-sharding (July 2010), Master/Slave
  • MapReduce
  • Document-oriented, not key/value
  • Replication Acknowledgement
  • DBRef

Crash course on MongoDB (2)

Compared to...

  • PostgreSQL/MySQL/Oracle etc.
  • CouchDB (slow, JSON)
  • Cassandra (Java)
  • BigTable/Dynamo (Google/Amazon)
  • ZODB (Python pickles)

Bob Ippolito's talk Drop ACID and think about data PyCon 2009

But what does it mean to use MongoDB?

Next step: Implications

Implications

  1. No joins
    change the way you browse data

    (note: foreign keys is not the problem)

Implications

  1. No joins
  2. Transactions
    change what your views do; to do less

Implications

  1. No joins
  2. Transactions
  3. Polymorphism
    inheritance of structure (awesome!)

Implications

  1. No joins
  2. Transactions
  3. Polymorphism
  4. Hashed IDs
    e.g. 4bebe6e26b2ded78ec00000a
0123456 7891011
timemachine pidinc

Implications

  1. No joins
  2. Transactions
  3. Polymorphism
  4. Hashed IDs
  5. Django Admin
    Haystack, Celery, pagination, flatpages, Piston, etc.
    ...but don't lose hope (Done)

Let's assume we decide to use MongoDB

Next step: Python

Python

pymongo!

(TxMongo - asynchronous variant based on Twisted)

Next step: "ORM"

http://api.mongodb.org/python/1.6/tools.html

"ORM"

  • Ming
    SQLAlchemy like
  • MongoKit
    pymongo like
  • MongoEngine
    Django ORM like
  • django-mongodb
    100% transparent, active?
  • django-nonrel
    99% transparent, GSoC

Next step: Django

Django

  • Ming → Ming
  • MongoKit → django-mongokit
  • MongoEngine → MongoEngine

Next step: code

http://www.peterbe.com/plog/mongoengine-vs.-django-mongokit

Ming

from ming.datastore import DataStore
from ming import Session
from ming import Document, Field, schema

bind = DataStore('mongo://localhost:27017/tutorial')
session = Session(bind)

class WikiPage(Document):

    class __mongometa__:
        session = session
        name = 'wiki_page'

    _id = Field(schema.ObjectId)
    title = Field(str)
    text = Field(str, if_missing='')
    metadata = Field(dict(
            tags=[str],
            revisions=[int]))
>>> for page in WikiPage.m.find()
>>>     print page['title']

django-mongokit

from django_mongokit import connection
from django_mongokit.document import DjangoDocument

class WikiPage(DjangoDocument):
    structure = {'title': unicode,
                 'text': unicode,
		 'metadata': {'tags':[unicode],
                              'revisions':[int]},
    }
    required_fields = ['title']
    default_values = {'text': u""}
    
connection.register([WikiPage])    
>>> collection = get_database()['wiki']
>>> for page in collection.WikiPage.find():
>>>     print page.title

MongoEngine

from mongoengine import *

class Metadata(EmbeddedDocument):
    tags = ListField(StringField())
    revisions = ListField(IntField())

class WikiPage(Document):
    title = StringField(required=True)
    text = StringField()
    metadata = EmbeddedDocumentField(Metadata)
>>> for page in WikiPage.objects:
>>>     print page.title
So which one should I use?
MongoEngine!

Next step: why

Advantages

  1. Least verbose
    pretend you didn't see the import *
  2. Automatic collection management
    (collection=table)
  3. django-mongoforms
  4. automatic "query inheritance"
  5. Great documentation

But! ...

  1. No signals
    django-mongokit has this
  2. Test database
    again, django-mongokit has this
  3. Maturity?
    applicable to all