The group I work with has thought about using Django a few times, but our biggest concern has been the lock-in you get with their base components. We’re already happy using SQLAlchemy and Genshi for a system application in our project. Besides liking the tools we’ve picked, we’d like to avoid using multiple tools for the same task. On the other hand, if a second set of tools provides a framework we’ll totally rock with, sign us up!

A few days ago, Zed Shaw spooged about how rad Django is. There isn’t a lot of meat to his story, but there are enticing morsels like generic views, the Pinax component list, and:

Django has been pushing the idea of having discrete “applications” that act within a “site” as cooperating but separate components.

Inspired, the first thing I looked at was the ORM. The schema we’ve inherited and need to redesign is absurdly complex1 so I suspected this is where I’d first hit limitations.

The redesign will use natural keys when possible and reasonable to help protect against duplicate data entry2 — the system we inherited uses only surrogate keys and has duplicate data in a variety of places. Also, we add protection (against errors, bad data, etc.) at multiple layers, so this approach fits well with our philosophy.

When choosing a natural key, sometimes more than one column is needed to guarantee uniqueness. This is called a composite primary key. Unfortunately, composite primary keys are not supported by Django3 and their wiki page about Multi-Column Primary Key support is disheartening. The only reason they might implement this feature is to support “legacy databases (whose schema cannot be changed)”. This plus the automatic generation of primary key “id” columns tells me they have made a choice for us: use surrogate keys.

Our model is now outside Django’s current scope and there is no way to leverage another ORM that can support our needs. Sadder still, the brilliance of an entire database toolkit4 perfectly suited to work with the M in our MVC project is inaccessible.

This is the problem with frameworks like Django, Ruby on Rails, and others; they enforce their “pragmatic design”5 on you. You must use their ORM, their template language, their request dispatcher, etc. You are sequestered within their community.

In frameworks like Pylons (and others) where you get both structure and choice of base components, all the different communities of ORM creators, template engine writers, and etc. are available and intermingling. Communication between projects is high and even the frameworks themselves are mixing!6

Our project will be growing for years, the longevity and flexibility of the community is critical. The last thing we want is 4 years from now realizing we’re dependent on a suite of core components nobody is using.


  1. We actually blew the Python call stack with our relation references when using SQLAlchemy and declarative. You might be thinking that’s because the model is crap, and you’d be right. We are actually keeping a tally how many times we exclaim “WTF!?” each day as we try to beat the beast into submission. ↩︎

  2. See Josh Berkus’ Primary Keyvil series for explanation of how natural keys can provide a database level way of protecting against duplicate data. ↩︎

  3. “Each model requires exactly one field to have primary_key=True.” ↩︎

  4. SQLAlchemy is not just an ORM, it’s an expression language and more↩︎

  5. From the Django project homepage. ↩︎

  6. TurboGears 2 was rewritten on top of Pylons. ↩︎