Waldemar Kornewald on February 22, 2010

4 things to know for NoSQL Django coders

Update 2: Take a look at the django-dbindexer. Since its release it's possible to use __month= queries so you don't have to use tricky code which uses a date range query for example. Additionally django-dbindexer adds support for simple JOINs.

Update: MongoDB backend is now available too :)

This is the first post in a series that should give you an impression of what non-relational / NoSQL model code looks like with django-nonrel. As mentioned in the previous post, you can see django-nonrel in action on our new website (we use it ourselves in the spirit of dogfooding).

While everything discussed here should work on all nonrel DBs we currently only have an App Engine backend and soon a MongoDB backend (more on that once it's finished). If you want to help with other backends (Redis, SimpleDB, CouchDB, etc.) please join the discussion group.

We'll dive into the source of our website which contains a very simple "CMS" and a blog app which can host multiple independent blogs. It runs the admin interface unmodified, but with some limitations. Overall, the code is surprisingly similar to normal Django code, but you'll also find that nonrel-compatible models need their own way of thought. What does it take to write a website that is nonrel-compatible? Let's get rolling.

Setting up the environment

You need Python 2.5 or 2.6. Just download and unpack allbuttonspressed.zip and adjust settings.py. This package contains Django nonrel and all other dependencies except for the App Engine SDK. If you want to use the latest repository code you can alternatively take a look at the manual installation instructions. That page also describes how to install the latest App Engine SDK on different operating systems.

You can now simply use manage.py syncdb , manage.py createsuperuser , and manage.py runserver as usual. Finally, you can deploy the site to App Engine via manage.py deploy . This will automatically run syncdb on the production server. If you need to execute a command on the production server prefix it with "remote". For example: "manage.py remote shell". This only works once you've deployed your website, though.

Now, let's dive into the actual code and experience the differences.

JOINs are evil

As our first app we wrote a minimal CMS. Now you might ask, why can't we just use django.contrib.flatpages ?