Ever since I started using SQLAlchemy at work, I've been keeping an eye out for information about Django eventually using SQLAlchemy. Unfortunately, the django-sqlalchemy SVN branch is all but dead. On Friday, the first non-stiflingly-hot day in a while, I sat down, got rid of lighttpd (which never worked satisfactorily as a fastcgi/Python server for me, at least on my laptop) and installed Apache2 and mod_python, which I have a lot more familiarity with. A couple of tweaks to my .bashrc later (to get the PYTHONPATH right) and I had the django-sqlalchemy code running on my laptop. It's actually more-or-less identical to the main branch; the Django ORM is all there and there wasn't any SQLAlchemy code I could see.
I originally toyed with the idea of looking at Django-SQLAlchemy a couple of weeks ago, but decided I probably didn't know enough - and I didn't, and I don't, and if I ever do it will almost surely be at the expense of my schoolwork, which would be The End Of The World. So, instead of doing what the django-sqlalchemy branch was working on - a API-compatible rewrite of django.db.models and associated files - I decided to ignore all of the django.db code and just write a plain, regular SQLAlchemy model.
Now, the way I like to layout my SQLAlchemy code (in Pylons) is like so: I make a directory for models (named, appropriately enough, models/) with a models/__init__.py file that contains an __all__ directive of ['classes', 'mappers', 'tables']. classes.py contains regular, inheriting1 Python classes. mappers.py contains (you guessed it) all the mappers, usually done with assign_mapper(). tables.py contains all the SQLAlchemy SQL construction code.
mappers.py will import tables, classes and use
assign_mapper to fill in the rest. I decided to the basically the same
thing with Django. Instead of using the models.py file provided with
Django apps, I instead created the directory structure I prefer with
the (lower-level and more verbose (but also more flexible))
SQLAlchemy. Each of those files can reach a hundred lines and fifty
lines, if not more, and I like being able to see everything in a file
on one screen (eighty lines vertically, two buffers horizontally, so
about 150 lines) if at all possible. Incidentally, this is another
reason I like the Django views; they can be defined pretty anywhere,
your urls can point to views in any file, and you can even import and
dynamically generate views. A common use of this is to have a
dedicated module for RSS-related functions. In contrast, I have a 500
line Pylons controller, and because of the __before__ function that
handles authentication, among other ways that the actions are tied to
the controller object, and the object to the file2, it would
be very much ill-advised of me to move the logic anywhere else. Doing
so would start hitting edge cases very fast.
Of course, if we're speaking of edge cases, than SQLAlchemy models with Django's URL dispatcher, request handler and views (although with Mako templating) is going to hit edge cases like crazy. And indeed it does; it's been working for a few hours, but I'm note entirely sure what solved the tough-to-debug error about the column not existing. It's an SQLite3 db... The file wasn't missing - there's a separate error for that - it's just wasn't finding my column. And judging by the debug information, it wasn't finding any info at all.
I also spent a couple of hours looking through the Django backends and thinking about the feasibility of using SQLAlchemy as a Django backend. I didn't really understand the difficulties until I tried writing said backend; a couple of hours later they were quite clear. But that's the point, isn't it? I think rewriting from django.db on down is too high a level for SQLAlchemy, but more is needed than a simple backend. Once the semester is out, hopefully I'll have more time to look at it in full and see where SQLAlchemy fits in to Django.
Things I still need to write about: Frustrations with Routes, places where the Django way is actually right4, the mess in the the django.db.models.fields module5, and my hopefully-soon-ready VPS.
-
Django's models notoriously couldn't inherit - they all had to be direct subclasses of django.db.models.Model. This was the case a few months ago; it was on the to-do list to fix and I'd imagine it's either fixed at this point or will soon be so. ↩
-
The URLS, because of Routes' controller keyword arg, are also inflexible about the controller's filename. ↩
-
Did you know that SQLite cannot drop columns from tables, period? Neither did I. ↩
-
Specifically URL dispatching and request dispatching, with the exception of the 'middleware', which really needs a rename and a scope adjustement ↩
-
There's actually code for the admin interface - apparently not a plain old app - in there! Oh, the horror. ↩
Comments
209 spam comments omitted.
I am no longer accepting new comments.
Ravi Gidwani
#10953, 2008-12-29T02:53:45Z
Hey.. I am infact trying to use SQLAlchemy as an alternate ORM to speak with a legacy DB and using django ORM for regular DB (since I am still on 0.96 I cant use two DBs). Came across your blog. do write further about ur findings. BTW were u able to use the django views with SQLAlchemy models without any issues?
codeape
#11652, 2009-01-17T17:26:26Z
Hi, a couple of question abt. the use of SqlAlchemy: