Python: MySQLdb 和“Library not loaded: libmysqlclient.16.dylib”问题

65

安装设置...

尝试在清洁的Mac OS X 10.6安装上进行Python/Django开发,我没有记得在10.5上遇到过这个问题。

在从mysql-5.5.8-osx10.6-x86_64.dmg安装程序安装MySQL后,我运行了以下命令:

$ sudo pip install MySQL-python

看起来一切进展顺利(下方为输出结果)

Downloading/unpacking MySQL-python
  Downloading MySQL-python-1.2.3.tar.gz (70Kb): 70Kb downloaded
  Running setup.py egg_info for package MySQL-python
    warning: no files found matching 'MANIFEST'
    warning: no files found matching 'ChangeLog'
    warning: no files found matching 'GPL'
Installing collected packages: MySQL-python
  Running setup.py install for MySQL-python
    building '_mysql' extension
    gcc-4.2 -fno-strict-aliasing -fno-common -dynamic -DNDEBUG -g -fwrapv -Os -Wall -Wstrict-prototypes -DENABLE_DTRACE -pipe -Dversion_info=(1,2,3,'final',0) -D__version__=1.2.3 -I/usr/local/mysql/include -I/System/Library/Frameworks/Python.framework/Versions/2.6/include/python2.6 -c _mysql.c -o build/temp.macosx-10.6-universal-2.6/_mysql.o -Os -g -fno-common -fno-strict-aliasing -arch x86_64
    In file included from _mysql.c:36:
    /usr/local/mysql/include/my_config.h:325:1: warning: "SIZEOF_SIZE_T" redefined
    In file included from /System/Library/Frameworks/Python.framework/Versions/2.6/include/python2.6/Python.h:9,
                     from pymemcompat.h:10,
                     from _mysql.c:29:
    /System/Library/Frameworks/Python.framework/Versions/2.6/include/python2.6/pymacconfig.h:33:1: warning: this is the location of the previous definition
    In file included from _mysql.c:36:
    /usr/local/mysql/include/my_config.h:419:1: warning: "HAVE_WCSCOLL" redefined
    In file included from /System/Library/Frameworks/Python.framework/Versions/2.6/include/python2.6/Python.h:8,
                     from pymemcompat.h:10,
                     from _mysql.c:29:
    /System/Library/Frameworks/Python.framework/Versions/2.6/include/python2.6/pyconfig.h:803:1: warning: this is the location of the previous definition
    gcc-4.2 -Wl,-F. -bundle -undefined dynamic_lookup build/temp.macosx-10.6-universal-2.6/_mysql.o -L/usr/local/mysql/lib -lmysqlclient_r -lpthread -o build/lib.macosx-10.6-universal-2.6/_mysql.so -arch x86_64
    warning: no files found matching 'MANIFEST'
    warning: no files found matching 'ChangeLog'
    warning: no files found matching 'GPL'
Successfully installed MySQL-python
Cleaning up...

之后我尝试了以下方法:

$ python -c "import MySQLdb"

然后它给我返回了错误信息:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/Library/Python/2.6/site-packages/MySQLdb/__init__.py", line 19, in <module>
    import _mysql
ImportError: dlopen(/Library/Python/2.6/site-packages/_mysql.so, 2): Library not loaded: libmysqlclient.16.dylib
  Referenced from: /Library/Python/2.6/site-packages/_mysql.so
  Reason: image not found

那么进入我的问题...

我做错了什么?/我还需要做什么?

在谷歌上搜索(以及在这里搜索)会返回很多结果,其中许多使用Ruby会出现此错误信息,但Python不会。


使用libmysqlclient.16.dylib代替10.5版本。 - user593086
7个回答

97

在运行pip installeasy_install后,只需设置DYLD_LIBRARY_PATH

export DYLD_LIBRARY_PATH=/usr/local/mysql/lib/

假设你的MySQL安装路径为/usr/local/mysql,那么这段代码应该可以正常工作。


1
这个修复方法对我有效,但每次启动 Django 时都需要这样做。有没有一个地方可以设置它(将其保存在文件中),使其成为永久设置? - thomallen
2
@thomallen 如果你使用 virtualenv,你可以在 bin/activate 脚本中设置/取消它,否则我建议使用 ~/.bash_profile - lukmdo
which mysql 的输出是 /usr/local/bin/mysql,所以我的路径应该是 export DYLD_LIBRARY_PATH=/usr/local/bin/mysql,对吗? - Ava
@Ava 这很可能只是一个符号链接。检查它指向哪里 ls -l \which mysql`,很可能你会在那里找到一个 **lib** 文件夹,比如 /usr/local/mysql/lib/`。 - lukmdo

56
_mysql.so 指的是 libmysqlclient.16.dylib,即作为 Python 和 MySQL 客户端库之间桥梁的共享库 _mysql.so 引用了 MySQL 客户端库动态库,并且由于某种原因无法加载该库。
需要回答的问题:
  • 你的系统上是否有 libmysqlclient.16.dylib 文件?如果没有,则需要安装 MySQL 客户端软件。
  • 如果有,则包含该库文件的目录是否已添加到 DYLD_LIBRARY_PATH 设置中?如果没有,请尝试添加它。
  • 如果有,您需要确保 libmysqlclient.16.dylib 文件没有损坏。我的副本通过 MacPorts 安装在 /opt/local/lib/mysql5/mysql/libmysqlclient.16.dylib 中,具有 MD5 签名 c79ee91af08057dfc269ee212915801a,大小为 1,462,376 字节。你的副本是什么样子的?

1
非常感谢Brian!我的副本位于/usr/local/mysql-5.5.8-osx10.6-x86_64/lib/libmysqlclient.16.dylib,大小为3,787,328字节,具有MD5签名9007ca637b74fd2b6c91c681cd4f22b0,因此它肯定不同...但是我的DYLD_LIBRARY_PATH为空,将/usr/local/mysql-5.5.8-osx10.6-x86_64/lib/添加到其中似乎让我再次运行。这之前为什么DYLD_LIBRARY_PATH是空的? - rennat
1
默认情况下是空的,我相信。我的也是空的,但我已经有一段时间没有尝试在Python中加载mysql库了。查看dyld的man页面(man dyld),并查看DYLD_LIBRARY_PATH的文档。 - Brian Clapper
30
我在Snow Leopard 10.6.6上遇到了类似的问题,使用Xcode4(不支持PPC),最终我不得不将DYLD_LIBRARY_PATH添加到我的bash配置文件中,方法如下:“export DYLD_LIBRARY_PATH=/usr/local/mysql/lib:$DYLD_LIBRARY_PATH”。以前的安装从未需要过这样做。我讨厌这个包太古老而且笨重。 - Ben Keating
2
在类 Unix Bourne shell 的 shell(例如 bash)中,默认情况下,shell 变量是本地的;也就是说,它们不会被放入环境变量中,而是保留在进程中。export 关键字将变量标记为“导出到环境变量”。因此,链接器(作为 shell 的子进程)实际上可以看到该变量。仅设置 DYLD_LIBRARY_PATH 而不导出它意味着它仅对该 shell 本地有效,因此无法帮助解决此问题。 - Brian Clapper
我有同样的问题,但是将DYLD_LIBRARY_PATH=/usr/local/mysql/lib:$DYLD_LIBRARY_PATH添加到我的bash_profile或etc/profile并没有帮助。我使用的是OSX 10.8。 - IdeoREX
显示剩余7条评论

42

在使用 easy_install 后,我创建了一个软链接以解决这个问题。

sudo ln -s /usr/local/mysql/lib/libmysqlclient.18.dylib /usr/local/lib/libmysqlclient.18.dylib

1
我不知道这做了什么,但当其他方法都失败时,它解决了我的问题!谨向您致以崇高的感谢!! - DavidJB
最佳和最简单的解决方案 - Andrey
1
这是唯一一个对我有效的,其他的都试过了。 - speedyrazor
创建软链接也解决了我的问题。非常感谢! - sjsupersumit
这个解决方案适用于较新版本的Mac OS,因为它们限制了操作系统搜索dynlibs的目录。 - John Y.

8
如果你的MySQL客户端比MySQL-python包更新,也可能会出现这种情况。在我的情况下,我的机器上有一个libmysqlclient_r.18.dylib,但没有一个libmysqlclient_r.16.dylib。运行pip search mysql,得到以下结果:

MySQL-python - Python接口 to MySQL 已安装: 1.2.3 最新版本: 1.2.3c1

运行pip install --upgrade MySQL-python解决了我的问题。

1
这解决了与上述动态库hack相同的问题。看起来通过pip install MySQL-python安装的默认版本是1.2.3,而不是最新版本1.2.3c1。要获取最新版本,请使用:pip install MySQL-python==1.2.3c1。 - Emil Stenström
2
这真是个好发现,这就是我的问题所在。值得一提的是,使用"--upgrade"似乎并没有正确地升级它,而使用"install MySQL-python==[最新版本]"则成功了。 - G.S.
我遇到了与@G.Moore相同的问题--升级似乎没有捕捉到新的.dylib引用。pip uninstall MySQL-python && pip install MySQL-python也可以解决这个问题。 - Lucian Thorr

8

在我的设置中(使用brew安装的mysql 5.7.x和pyenv),我有一个更新的库文件libmysqlclient.20.dylib。解决方法是先执行pip uninstall MySQL-python,再执行pip install MySQL-python


如果有缓存问题,也可以尝试使用 pip --no-cache-dir install MySQL-python - dezhi

7

在最新版本的MySQL 5.7.9中,不再支持MySQL-python,我改用PyMySQL库。另外,在Django项目的manage.py中,我添加了以下代码以模拟MySQL-python的API:

try:
    # load MySQLdb interface emulation
    import pymysql
    pymysql.install_as_MySQLdb()
except ImportError:
    pass

0

对于像我这样需要或已经安装了MySQLdb和PyMySQL的人(在我的情况下,我需要同时安装两者,因为我使用PyMySQL连接到我的本地MySQL实例,而使用MySQLDb连接远程/在线实例):

请确保你正在使用正确的URI方案。要访问本地实例:

LOCAL_DATABASE_URI = 'mysql+pymysql://username:password@hostname/dbname'

并且用于实时:

REMOTE_DATABASE_URI = 'mysql+mysqldb://username:password@hostname/dbname'

区分这一点解决了我的问题


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接