Monday 3 January 2011

Issues with Django and MySQL on Mac OS X

Today, I spent more time than planned setting up a Django installation with MySQL database backend. Below are the problems I encountered and the ways how I dealt with them.

mysql_config

I'm using what's supposed to be the simplest MySQL installation out there - the official dmg from http://dev.mysql.com/. The installer puts all the files into
/usr/local/mysql
(with the regular bin, lib and include directories inside). The installation also includes the usual mysql_config executable which takes care for pointing out all the paths required by the MySQL-python package. The problem is that without the system path preconfigured the MySQL-python installer isn't able to find it. I had to point out to the package where mysql_config is. Luckily, there's a setting for that. I downloaded the package:
bin/pip install MySQL-python --no-install
(it raised an error but downloaded the files just fine). Then, in a file called site.cfg, I switched the following line
#mysql_config = /usr/local/bin/mysql_config
into
mysql_config = /usr/local/mysql/bin/mysql_config
- uncommenting it and putting the right path in place. I was free to continue with the installation:
bin/pip install build/MySQL-python

The library path

Unfortunately, this didn't solve all the problems, as I kept getting the following error when trying to run any code that used the package:
Error loading MySQLdb module: dlopen(/path/to/site-packages/_mysql.so, 2): Library not loaded: libmysqlclient.16.dylib

As it turns out, the Ruby guys have a similar problem with that, and it's in a Rails-related post, where I found a solution. For some mysterious reason, the name of mysqlclient library was saved without the full absolute path, as I could see running the otool command:
$otool -L lib/python2.6/site-packages/_mysql.so 
lib/python2.6/site-packages/_mysql.so:
 libmysqlclient.16.dylib (compatibility version 16.0.0, current version 16.0.0)
 /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.1)

When I changed it to the full path with the install_name_tool command:
sudo install_name_tool -change libmysqlclient.16.dylib /usr/local/mysql/lib/libmysqlclient.16.dylib lib/python2.6/site-packages/_mysql.so

all worked fine. Hope that helps someone in similar trouble.

7 comments:

Sergey Timoshin said...

Thanks a lot! You saved my day.

ssspiochld said...

AFAIC this is only a MySQL-python on OS X and nothing particular related to Django.

Regarding The library path probably setting export DYLD_LIBRARY_PATH=/usr/local/mysql/lib/ should also work.

Konrad said...

@ssspiochld - both of these are true

the title might be a misleading, but it's meant to describe where I got the issues, not what exactly caused them. Plus, it makes the post more google'able (if someone needs it)

as for the library path: yes it works. I'd say I like the other solution better :)

Michael said...
This comment has been removed by the author.
Michael said...

Horray! Thanks so much for this. I was having exactly the same problem. I have an xgrid process that needs to run as nobody. Wasted far too much time looking at how to set a global environment variable for nobody (/etc/bashrc does not work) before coming across this. Bravo!

Unknown said...

Actually, this IS the best solution. Thank you! The other one, involving the library path, didn't work for me.

I came across the 'Ruby solution' as well but decided to try some other stuff first before changing that one to work without Ruby. Luckily, I found this post and could easily adapt it to finally get it working!

Annoyingly, this kind of stuff costs you a fair amount of time... I can't believe that the MySQL guys endlessly refactoring every single bit can allow this to happen... Oh, well.

Tejuteju said...

Nice post! Thanks for sharing valuable information with us. Keep sharing... Ruby on Rails Online Training