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!

kasimir 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.

mahasiswa teladan said...

hi...Im student from Informatics engineering nice article,
thanks for sharing :)