Hacker News new | past | comments | ask | show | jobs | submit login
Shortcomings in the Django ORM and a look at Peewee, a lightweight alternative (charlesleifer.com)
37 points by coleifer on Dec 15, 2012 | hide | past | web | favorite | 9 comments

Is there a reason you didn't use SQLAlchemy, as that's what I turn to when I'm not in Django-land. It's also closer to a competitor to Peewee than Django's ORM is.

I mean, when I use Django, even though I could switch out the ORM, I'd be ditching a lot of freebies (integration with auth, forms, South, all the reusable apps in the wild). Thus, you really don't see people ripping out the Django ORM except in the very extreme cases. It also explains why it'll be really difficult to switch out the Django ORM, as there is just so much integration to rewrite and legacy apps to lose.

If I wanted/needed/was willing to reinvent all of that, I'd probably start with a smaller framework (like Tornado, Flask) where the only stable game - so far - is SQLAlchemy.

Thus, I don't think it's in your benefit to consider/advertise yourself a lightweight alternative to the Django ORM, as there aren't many folks looking for an alternative (and even though most people aren't 100% happy with Django's ORM the bar to competing is really high). Your users are most likely not using Django, and deciding between Peewee and SQLAlchemy.

I've looked at Peewee (albeit before the rewrite mentioned here), and, more to the point, my first response was "why didn't he write this in SQLAlchemy." SQLAlchemy is a battle hardened toolkit that's both broad and deep. At its lowest levels, its a toolkit for building ORMs. IMHO, if you're doing SQL in python, there's almost no reason to look anywhere else. That's how good it is.

And in view of that, how is Peewee better than SQLAlchemy? It doesn't appear to be at all.

I wouldn't call these shortcomings of Django's ORM as much as design decisions that may or may not be agreed with. I've found Django's ORM pretty useful in that, it reduces the amount of typing you need to do. BlogPost.objects.filter() is shorter than "SELECT * from BlogPost where ....". Of-course, Django's ORM gives you a few ways to implement complex SQL statements. However, ORMs in my opinion aren't that great with dealing with complexity. They can take you only so far before you realize that "Hey, I could write this query much better manually". At the point where you need that, ORMs are pretty useless. There've been times that I've manually enforced database level constraints and enforced uniqueness on 2 or more columns with a replace statement to avoid race conditions. An ORM wouldn't be able to handle that kind of thing. Not at the moment anyway.

But that brings me to my point. Do we need to keep running after abstraction (ORMs) when the needs become sufficiently complex and the abstraction ends up making things more opaque ?

ORMs are great for simple stuff. Raw SQL rules for complex stuff. Yes/No ?

I agree with you about the use of raw SQL when a query gets too complex. Often I find that the ORM is capable of expressing a query I have in mind, but it might do it inefficiently. Sometimes I will rewrite this using SQL. Usually what limits me is how much post processing I will have to do on the results to attain my desired goal.

Often I avoid putting any work on my db beyond filtering and grouping of results. Its typically much easier to scale out app/web servers than it is to scale out databases to support a heavy query workload.

I think it's cool that you wrote a solution to a problem that was affecting you. For me I've been using the Django ORM for quite some time now and have been able to use it in 99% of situations. For the situations where it doesn't fit Django allows me to drop down to raw SQL for a solution.

I do think it would be nice though to get rid of things like Q objects and move to something else. Maybe something such as objects.filter(text='hello' | text='goodbye'). Either way Q objects are extremely useful and the Django documentation does a nice job of showing how to use all the queryset features.

It's weird to single out Q objects since they're the most functional, composable, flexible parts of that API. Passing around clauses lets you do things like build a list of them then reduce that list into a single query via |. There's a lot of mental gymnastics involved in learning Django's ORM but the Q object is not something I would ever suggest as a candidate for dismissal.

As far as I can tell, neither this article nor Alex Gaynor's slides mention another big problem with Django's ORM: lack of support for composite primary keys and composite foreign keys.

We were layering some web stuff on top of a database that worked flawlessly with SQLAlchemy and ended up changing our data model to accommodate Django's weaknesses.

I mostly like Peewee's API, it is like a mixture of the Django ORM and SQLAlchemy. It could be a sane path forward for Django's ORM, but backwards compatibility will still be hard. Django's ORM has a lot in it's API that are hard to or shouldn't really be replicated like extra(), annotate(), aggregate(), F(), exclude(), raw().

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact