库未加载:@rpath/libmysqlclient.21.dylib 原因:找不到图像 使用mysqlclient DB驱动程序和MySQL 8在macOS上使用Django迁移时出现错误

13

当我试图从Django默认使用的SQLite数据库更改为MySQL数据库时,运行python manage.py migrate --database mysql时遇到了这个棘手的错误:

Traceback (most recent call last):
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/db/backends/mysql/base.py", line 15, in <module>
    import MySQLdb as Database
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/MySQLdb/__init__.py", line 18, in <module>
    import _mysql
ImportError: dlopen(/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/_mysql.cpython-37m-darwin.so, 2): Library not loaded: @rpath/libmysqlclient.21.dylib
  Referenced from: /Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/_mysql.cpython-37m-darwin.so
  Reason: image not found

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 20, in <module>
    execute_from_command_line( sys.argv )
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/core/management/__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/core/management/base.py", line 316, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/core/management/base.py", line 350, in execute
    self.check()
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/core/management/base.py", line 379, in check
    include_deployment_checks=include_deployment_checks,
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/core/management/commands/migrate.py", line 59, in _run_checks
    issues = run_checks(tags=[Tags.database])
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/core/checks/registry.py", line 71, in run_checks
    new_errors = check(app_configs=app_configs)
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/core/checks/database.py", line 9, in check_database_backends
    for conn in connections.all():
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/db/utils.py", line 217, in all
    return [self[alias] for alias in self]
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/db/utils.py", line 217, in <listcomp>
    return [self[alias] for alias in self]
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/db/utils.py", line 202, in __getitem__
    backend = load_backend(db['ENGINE'])
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/db/utils.py", line 110, in load_backend
    return import_module('%s.base' % backend_name)
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/db/backends/mysql/base.py", line 20, in <module>
    ) from err
django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.
Did you install mysqlclient?

我已经通过pip install mysqlclient安装了mysqlclient,并通过Homebrew使用brew install mysql-connector-c安装了它的连接器,但仍然收到了这个错误。即使按照连接器说明修改了连接器bin文件夹中的mysql_config文件,我仍然遇到了这个问题。鉴于这个连接器已知的bug文档,这似乎与我正在运行的macOS有关。

进一步检查我的堆栈跟踪后,我注意到顶部出现了Library not loaded: @rpath/libmysqlclient.21.dylib错误。紧接着是另一个可能的线索:Reason: image not found,但我不确定这是什么意思。

我在/usr/local/Cellar/mysql-connector-c中查看了一下我安装的连接器是否有什么可能丢失的东西,果然,libmysqlclient.21.dylib文件丢失了。取而代之的是我认为是旧版本的文件,因为它被命名为libmysqlclient.18.dylib。出于好奇,我复制了MySQL安装所带的.dylib并将该副本移动到相同名称的连接器文件夹和/usr/local/lib,在那里我还找到了另一个libmysqlclient.18.dylib文件。然而,我的迁移仍然失败了,但我确实得到了稍微不同的堆栈跟踪:

Traceback (most recent call last):
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/db/backends/mysql/base.py", line 15, in <module>
    import MySQLdb as Database
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/MySQLdb/__init__.py", line 18, in <module>
    import _mysql
ImportError: dlopen(/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/_mysql.cpython-37m-darwin.so, 2): Library not loaded: @rpath/libmysqlclient.21.dylib
  Referenced from: /Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/_mysql.cpython-37m-darwin.so
  Reason: no suitable image found.  Did find:
    /usr/local/lib/libmysqlclient.21.dylib: file too short
    /usr/local/lib/libmysqlclient.21.dylib: file too short

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 20, in <module>
    execute_from_command_line( sys.argv )
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/core/management/__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/core/management/base.py", line 316, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/core/management/base.py", line 350, in execute
    self.check()
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/core/management/base.py", line 379, in check
    include_deployment_checks=include_deployment_checks,
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/core/management/commands/migrate.py", line 59, in _run_checks
    issues = run_checks(tags=[Tags.database])
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/core/checks/registry.py", line 71, in run_checks
    new_errors = check(app_configs=app_configs)
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/core/checks/database.py", line 9, in check_database_backends
    for conn in connections.all():
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/db/utils.py", line 217, in all
    return [self[alias] for alias in self]
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/db/utils.py", line 217, in <listcomp>
    return [self[alias] for alias in self]
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/db/utils.py", line 202, in __getitem__
    backend = load_backend(db['ENGINE'])
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/db/utils.py", line 110, in load_backend
    return import_module('%s.base' % backend_name)
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/Users/xoadra/Programming/Syntax/Python/Environments/pfitzer/lib/python3.7/site-packages/django/db/backends/mysql/base.py", line 20, in <module>
    ) from err
django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.
Did you install mysqlclient?

这次我遇到了以下错误:

Reason: no suitable image found.  Did find:
        /usr/local/lib/libmysqlclient.21.dylib: file too short
        /usr/local/lib/libmysqlclient.21.dylib: file too short

因此,我怀疑问题可能与MySQL连接器安装的.dylib版本有关,但我不确定如何确切地解决这个问题。我发现仅仅复制一个文件就能微调我的堆栈跟踪,所以我想我应该更深入地研究一下这个问题。你有什么想法吗?

9个回答

22

只需在 /usr/local/lib 中创建一个符号链接。

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

完美运行,只需确保MySQL文件夹名称与您所拥有的相同。在我的情况下,它是 sudo ln -s /usr/local/mysql-8.0.19-macos10.15-x86_64/lib/libmysqlclient.21.dylib /usr/local/lib/libmysqlclient.21.dylib - Ziyad Sfaxi
非常感谢,这节省了我很多时间。 - Daniel Charles Mwangila

12

我最近在尝试在我的MacBook Pro(macOS Catallina)上安装Django和mod_wsgi时遇到了问题。设置LD_LIBRARY_PATH、DYLD_LIBRARY_PATH、添加符号链接以及将libmysqlclient.21.dylib文件移动到/usr/lib目录下都没有解决问题。我挣扎了几天,但最终找到了解决方案。关键是我需要修改libmysqlclient.21.dylib中的库路径,幸运的是我们有一个工具可以做到这一点。罪魁祸首是@rpath/libmysqlclient.21.dylib。看起来@rpath无法正常工作。

好的,您可以使用Xcode自带的otool检查.so文件中引用的路径。当您在mysql .so文件上运行它时,您会得到以下结果(应该在site-packages下的MySQLdb目录中)。

$ otool -L _mysql.cpython-38-darwin.so

_mysql.cpython-38-darwin.so:
    @rpath/libmysqlclient.21.dylib (compatibility version 21.0.0, current version 21.0.0)
    libssl.1.1.dylib (compatibility version 1.1.0, current version 1.1.0)
    libcrypto.1.1.dylib (compatibility version 1.1.0, current version 1.1.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.100.1)

因此,我们在 _mysql.cpython-38-darwin.so 中修改了文件路径。有一个工具可以实现这一点,它就是 install_name_tool。我运行了以下命令:基本上我将 @rpath 更改为绝对路径,还将 libssl 和 licrypto 的路径更改为绝对路径。

$ install_name_tool -change @rpath/libmysqlclient.21.dylib /usr/local/mysql/lib/libmysqlclient.21.dylib _mysql.cpython-38-darwin.so

$ install_name_tool -change libssl.1.1.dylib /usr/local/mysql/lib/libssl.1.1.dylib  _mysql.cpython-38-darwin.so

$ install_name_tool -change libcrypto.1.1.dylib /usr/local/mysql/lib/libcrypto.1.1.dylib _mysql.cpython-38-darwin.so

在这些更改后,我的Django运行得非常好。


1
谢谢!这是在 Mac 上唯一有效的解决方案。 - Chris H
1
谢谢!对我也起作用了(MacOS Big Sur,MySQL 8,Python 3.8,Django 3.2.2)。虽然我只运行了你解决方案的第一行。看起来已经足够了。 - sipi09
1
老兄,你真是救星啊。我之前卡在这个问题上整整一天了。 - Pratik Saxena
这最好使用现有的通用软链接完成。类似于install_name_tool -change @rpath/libmysqlclient.21.dylib /usr/local/mysql/lib/libmysqlclient.dylib /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/MySQLdb/_mysql.cpython-39-darwin.so - Konchog
1
对于任何MacOS 14 - Sonoma的情况,答案是使用第一个命令将/opt/homebrew/opt/mysql/lib/libmysqlclient.21.dylib文件更改为/opt/homebrew/opt/mysql/lib/libmysqlclient.22.dylib,并将其应用于_mysql.cpython-310-darwin.so文件。 - Nicholas Gooding Rios

4
对我来说,在升级MySQL版本后,我遇到了一个问题。解决方法是重新安装mysqlclient Python依赖项,但只有在禁用缓存的情况下才有效,例如使用命令pip install --no-cache-dir mysqlclient。因为libmysqlclient.21.dylib已经被移除并替换为libmysqlclient.22.dylib,所以符号链接在这里无法起作用。

3
符号链接的解决方案对我有用,但在链接第一个文件后,我对于另一个文件名得到了相同的错误消息。总共,我需要符号链接三个不同的文件。
sudo ln -s /usr/local/mysql/lib/libmysqlclient.21.dylib /usr/local/lib/libmysqlclient.21.dylib
sudo ln -s /usr/local/mysql/lib/libssl.1.1.dylib /usr/local/lib/libssl.1.1.dylib
sudo ln -s /usr/local/mysql/lib/libcrypto.1.1.dylib /usr/local/lib/libcrypto.1.1.dylib

感谢您提供的解决方案!我用它来安装DBD::mysql Perl模块,在MySQL 8.0.22,macOS Catalina和Perl 5.32中也遇到了这个问题。 - RickJansen

2
所以事实证明,我设法解决了我的问题,尽管方法有点不正规。如果其他人正在使用Python 3和MySQL 8的mysqlclient,请尝试一下,看看是否有帮助!:)
我只是在我的MySQL 8.0.13安装中复制了位于/usr/local/mysql/lib中的libmysqlclient.21.dylib文件,并将该副本移动到同名的/usr/lib目录下。
但是,您需要暂时禁用Mac上的安全完整性保护才能执行此操作,因为您无法在不禁用它的情况下拥有或更改/usr/lib中的任何权限。您可以通过启动恢复系统,在菜单上单击“实用工具”,然后打开终端并在终端中输入csrutil disable来执行此操作。完成此操作后,请记得重新启用安全完整性保护!与上述过程唯一的区别将是您运行csrutil enable而不是csrutil disable。
我完成了这个步骤后,在新数据库上像以前一样运行了我的迁移,它奏效了!老实说,我不知道这到底是一个多好的解决方案,但自从我更改了连接器使用的 .dylib 副本以来,一切都一直完美运行。如果你也遇到了这个问题,希望这可以帮到你!
你可以在这里阅读更多关于如何禁用和启用 macOS 安全完整性保护的信息。

此外,您可以按照本文所述创建符号链接,我认为这比复制是一个稍微更好的解决方案: https://afshinm.name/2016/02/05/how-to-fix-library-not-loaded-libmysqlclient-18-dylib-in-mac-os-x/ - hellter

2

MacOS 14 - Sonoma的修复方法

经过大量搜索和艰难的时间,我终于找到了一个可能适用于任何MacOS用户的解决方案。如果您正在使用Sonoma MacOS 14,请按照以下步骤进行操作。

  1. 检查出现的具体错误,并寻找以...开头的部分
ImportError: dlopen(.../_mysql.cpython-310-darwin.so) Library not loaded: /opt/homebrew/opt/mysql/lib/libmysqlclient.21.dylib

这两个部分非常重要,一个是尝试加载库的.so文件,另一个是被加载的.dylib库。
  1. 在终端中进入包含so文件的文件夹

  2. 在该文件夹中运行以下命令

otool -L _mysql.cpython-310-darwin.so

并搜索当前dylib版本它正在尝试查找

  1. 转到/opt/homebrew/opt/mysql/lib/文件夹,并查找您的实际文件。在我的情况下,是一个名为libmysqlclient.22.dylib的符号链接文件,其实际文件名为libmysqlclient.dylib

  2. 使用以下命令切换到正确的文件:

install_name_tool -change /opt/homebrew/opt/mysql/lib/{previous}.dylib /opt/homebrew/opt/mysql/lib/libmysqlclient.dylib _mysql.cpython-310-darwin.so

再次运行otool命令以查看更改。
otool -L _mysql.cpython-310-darwin.so

输出应为:
_mysql.cpython-310-darwin.so:
        /opt/homebrew/opt/mysql/lib/libmysqlclient.dylib (compatibility version 21.0.0, current version 21.0.0)
        /usr/lib/libresolv.9.dylib (compatibility version 1.0.0, current version 1.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1292.60.1)

这样做将解决错误,并让您继续进行DJango的迁移过程,或者让服务器再次正常运行,避免出现500错误。

1
成功了!在我的情况下,文件路径是/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundle,错误信息为/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundle,0x0009):无法加载库:/opt/homebrew/opt/mysql/lib/libmysqlclient.21.dylib(LoadError) - undefined

1
我的Python 3.6项目需要使用libmysqlclient.21.dylib库。我使用brew install mysql-client进行安装,它安装了mysql-client 8.0版本,并且其中包含了libmysqlclient.21.dylib库。但是我想要使用mysql@5.6。因此,我将/usr/local/Cellar/mysql-client/8.0.19/lib中的libmysqlclient.21.dylib复制到了/usr/local/lib/目录下。
然后我使用以下命令:sudo ln -s /usr/local/Cellar/mysql-client/8.0.19/lib/libmysqlclient.21.dylib /usr/local/lib/libmysqlclient.21.dylib

0

我尝试了很多方法,但最终发现只需要将文件夹mysql-8.0.26-macos11-x86_64重命名为“mysql”,放在usr/local/mysql-8.0.26-macos11-x86_64/lib/libmysqlclient.21.dylib中即可。一旦我这样做了,一切都正常了。


0
在我的情况下,我发现问题的根本原因是相对路径。所以将其更改为绝对路径解决了这个问题。
进入包含 `_mysql.cpython-310-darwin.so` 文件的目录。
使用以下命令检查路径:
otool -L _mysql.cpython-310-darwin.so

在我的情况下,这就是返回的内容。
@rpath/libmysqlclient.21.dylib (compatibility version 21.0.0, current version 21.0.0)

将此更改为绝对路径解决了问题。
install_name_tool -change @rpath/libmysqlclient.21.dylib /usr/local/mysql/lib/libmysqlclient.21.dylib _mysql.cpython-310-darwin.so

现在当你再次使用上述相同的命令检查路径时
otool -L _mysql.cpython-310-darwin.so

绝对路径应该像这样返回
/usr/local/mysql/lib/libmysqlclient.21.dylib (compatibility version 21.0.0, current version 21.0.0)

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