Sunday, December 30, 2007

Django with PostgreSQL on Mac OS X Tiger

Most of the time, when I have worked on django projects, I've used the SQLite backend for development on my PowerBook and deployed to PostgreSQL on my Linux server. For the project I'm working on right now, though, that turned into an issue when some of the queries that ran fine on my dev system didn't work at all on the production box. Apparently the backend code responsible for assembling the SQL query strings was producing different text for SQLite and PostgreSQL. So I could avoid similar issues in the future, I set out to install PostgreSQL on my laptop today.

Installing PostgreSQL itself turned out to be very easy indeed. I downloaded the universal installer from Andy Satori's "PostgreSQL for Mac" site. Some of the GUI clients included don't work because I'm on a PPC PowerBook instead of an x86 MacBook or MacBook Pro, but that's OK. I can use the CLI tools, which work fine.

The next thing I needed to do was set up psycopg. That turned out to be a bit of an issue, since initd.org is having some sort of server problem on their site. I was eventually able to download the tarball with the sources for psycopg 1.1.21.

In order to compile psycopg, I also needed mxDateTime from eGenix. They offer several pre-compiled packages, but none would install for me. Working from the source for 3.0.0, I was able to compile it myself via "python setup.py install" into my virtualenv sandbox.

Back in the psycopg build directory, I was able to use these instructions, but had to hack around a bit to get the mxDateTime headers in a place that matched the psycopg build expectations. I tried several variations of path names into the mx source tree, but eventually gave up and copied them all to one directory:

$ cd egenix-mx-base-3.0.0
$ mkdir include
$ find . -name '*.h' -exec cp {} `pwd`/include/ \;


I then tried to configure psycopg with:

$ ./configure --with-postgres-libraries=/Library/PostgreSQL8/lib --with-postgres-includes=/Library/PostgreSQL8/include --with-mxdatetime-includes=../egenix-mx-base-3.0.0/include/


That failed to find the Python.h header until I ran configure outside of my virtualenv environment, using the copy of Python 2.5 I had installed ages ago from python.org. Obviously your path to the mx includes may vary, but that installer package for the PostgreSQL server will put everything in /Library/PostgreSQL8.

Once I had configure running, I ran make (still outside of my virtualenv). The build succeeded, and then I went over to the shell running my virtual environment to install from there (via a simple "make install").

The end result of all of that was PostgreSQL 8.2.5 installed globally, and the mx 3.0.0 and psycopg 1.1.21 packages installed only in my virtual environment.

After a quick createdb, and edit to my settings.py file, I was able to sync up my dev server against the new database and get back to work. I suspect, but can't verify, that I would have had fewer issues if I was on an x86 Mac of some sort or running Leopard, since many of these packages seem to have moved on ahead of my platform. The whole thing took just over an hour, most of which was me fumbling around trying to find compatible versions of the source for the various pieces since it has been so long since I've compiled any of this stuff.

7 comments:

Steve said...

If psycopg2 is available for Tiger you might find it more satisfactory, as I believe it can use the built-in datetime module instead of mxDateTime, removing a dependency and making configuration easier.

I've found installation and use of PostgreSQL much easier with psycopg2 but I am a Windows and GNU/Linux user, so your mileage may vary.

Doug Hellmann said...

Ah, I wondered what the difference between psycopg and psycopg2 was. I'll give that a try when the initd.org site comes back and see if it's easier.

zgoda said...

Psycopg2 seems to be a bit slower than psycopg(1), but this should not matter for dev/testing environment. Also, it is not as extensively tested, so some quirks may appear (like "Cannt adapt" error on django's SafeString objects lately)

Doug Hellmann said...

Thanks for the tip zgoda. I have psycopg working now, so I'm going to leave well enough alone and work on my project. It's good to know that the (not so great) effort I've already put out to compile everything was worth it, though, since the point of all of this is to have my dev system better reflect the production environment so I don't end up with code that works in dev but not in production.

Kent said...

You might like to try PgAdmin3, it is a very capable GUI client for Postgres available in a universal binary for Mac OS X:
http://www.pgadmin.org/

Doug Hellmann said...

Thanks for reminding me of that, Kent. I've used it once or twice in the past, and still have it installed, but forgot all about it! I'll crank it up and give it another look.

Doug Hellmann said...

Oh, and TextMate also has some SQL/PostgreSQL support which I have experimented with. The DB browser is pretty nice, and the "run this query" for SQL files works well.

I haven't tried running queries embedded in Python code, yet, though. Has anyone else?