tags:

views:

1507

answers:

3

Hi,

I'm running a python script on a shared hosting server which until this morning had MySQL version 4. Now it has version 5. My python script can no longer connect to MySQL, as it can't find libmysqlclient_r.so.14:

$ python my_script.py
Traceback (most recent call last):
File "my_script.py", line 6, in ?
import MySQLdb
 File "/home/lib/python2.4/site-packages/PIL-1.1.6-py2.4-linux-i686.egg/__init__.py", line 19, in ?

 File "build/bdist.linux-i686/egg/_mysql.py", line 7, in ?
 File "build/bdist.linux-i686/egg/_mysql.py", line 6, in __bootstrap__
ImportError: libmysqlclient_r.so.14: cannot open shared object file: No such file or directory

There are various other versions of libmysqlclient in /usr/lib:

/usr/lib/libmysqlclient.so.15
/usr/lib/libmysqlclient.so.14
/usr/lib/mysql/libmysqlclient.la
/usr/lib/mysql/libmysqlclient.so
/usr/lib/mysql/libmysqlclient_r.so
/usr/lib/mysql/libmysqlclient_r.a
/usr/lib/mysql/libmysqlclient_r.la
/usr/lib/mysql/libmysqlclient.a
/usr/lib/libmysqlclient.so
/usr/lib/libmysqlclient_r.so
/usr/lib/libmysqlclient_r.so.15
/usr/lib/libmysqlclient_r.so.15.0.0
/usr/lib/libmysqlclient.so.15.0.0

So my question is this: how can I tell python (version 2.4.3) which version of libmysqlclient to use?

Thanks,

Ben

A: 

One solution is to set your PYTHONPATH environment variable to have some local directory, and copy over (or link, I suppose) the version of the mysql lib you want.

sykora
Hi Sykora, thanks -- I've tried that, but it doesn't seem to have worked. Is it definitely the case that python will look in PYTHONPATH for shared objects? I wonder if there's another env variable I'm missing...
Ben
According to the documentation, it will _always_ search the standard dirs _after_ any in PYTHONPATH, so if that's not working for you, it must be something else.
sykora
That's only for Python's own loadable modules though (.pyd on Windows, .so on *ix). libmysqlclient.so is another library *linked to* by the Python module _mysql.so. Only _mysql.so will be looked for in PYTHONPATH.
bobince
+1  A: 

You will have to recompile python-mysql (aka MySQLdb) to get it to link to the new version of libmysqlclient.

If your host originally set up the environment rather than you compiling it, you'll have to pester them.

/usr/lib/libmysqlclient.so.14

This looks like a remnant of the old libmysqlclient, and should be removed. The _r and .a (static) versions are gone and you don't really want a mixture of libraries still around, it will only risk confusing automake.

Whilst you could make a symbolic link from libmysqlclient_r.so.14 to .15, that'd only work if the new version of the client happened to have the same ABI for the functions you wanted to use as the old - and that's pretty unlikely, as that's the whole point of changing the version number.

bobince
+4  A: 

You can't tell the dynamic linker which version of a library to use, because the SONAME (full name of the library + interface) is part of the binary.

In your case, you can try to upload libmysqlclient_r.so.14 to the host and set LD_LIBRARY_PATH accordingly, so tell the dynamic linker which directories to search additionally to the system dirs when resolving shared objects.

You can use ldd to see if it LD_LIBRARY_PATH works:

$ ldd $path_to/_mysql.so
...
libmysqlclient_r.so.14 => $path_to_lib/libmysqlclient_r.so.14
...

Otherwise, there will be an error message about unresolved shared objects.

Of course that can only be a temporary fix until you rebuild MySQLdb to use the new libraries.

Torsten Marek
To any who might come across this. You can set your LD_LIBRARY_PATH like so: (assuming bash)export LD_LIBRARY_PATH=/usr/lib/mysql/:$LD_LIBRARY_PATHobviously your /usr/lib... would be the path to your library.