Reputation: 353
While changing to a MySQL database from the default SQLite one that Django uses by default, I ran into this tricky error while trying to run 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?
I received this error after having already installed mysqlclient via pip install mysqlclient
and its connector through Homebrew with brew install mysql-connector-c
, so this is a bit of a puzzling error. Even after following the connector instructions by modifying the mysql_config
file in the connector's bin folder, I still ran into this issue. This does appear to be at least somewhat related to that I'm running macOS given the documentation on this connector's known bug.
Upon inspecting my stack trace further, I noticed the Library not loaded: @rpath/libmysqlclient.21.dylib
error up near the top. Shortly after that is another possible clue I found: Reason: image not found
, but I'm not quite sure what that's supposed to mean.
I did poke around in /usr/local/Cellar/mysql-connector-c
to see if there was anything possibly missing with the connector I installed, and sure enough, the libmysqlclient.21.dylib
file was missing. In its place was what I assume is an older version of the file since it was named libmysqlclient.18.dylib
. Out of curiosity, I copied the .dylib
that my MySQL install came with and moved that copy under the same name to the connector's folder and to /usr/local/lib
where I also found another libmysqlclient.18.dylib
file. However, my migration still failed, but I did get a slightly different stack trace:
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?
This time I get the following error:
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
With that, I suspect the problem may have something to do with the .dylib
version that my MySQL connector installed with, but I'm not sure how to fix this exactly. I do find it curious that simply copying a file over managed to change my stack trace ever so slightly so I guess I ought to look into that more. Thoughts?
Upvotes: 16
Views: 13887
Reputation: 555
I encountered this error while using diesel setup
as well.
I fixed the issue with the following command:
install_name_tool -add_rpath /usr/local/mysql/lib ~/.cargo/bin/diesel
Upvotes: 0
Reputation: 327
In my case, I found out its the relative path that was the root cause of the problem. so changing this to the absolute path fixed the issue.
Navigate into the directory that has _mysql.cpython-310-darwin.so
file.
Check the path with this command:
otool -L _mysql.cpython-310-darwin.so
In my case this is what was returned
@rpath/libmysqlclient.21.dylib (compatibility version 21.0.0, current version 21.0.0)
Changing this to the absolute path fixed the issue
install_name_tool -change @rpath/libmysqlclient.21.dylib /usr/local/mysql/lib/libmysqlclient.21.dylib _mysql.cpython-310-darwin.so
And now when you check the path again using the same command above
otool -L _mysql.cpython-310-darwin.so
The absolute path should be returned like so
/usr/local/mysql/lib/libmysqlclient.21.dylib (compatibility version 21.0.0, current version 21.0.0)
Upvotes: 2
Reputation: 543
After a lot of searching and a difficult time I was able to find a possible answer for any MacOS user. If you are using Sonoma MacOS 14, then here is the step by step.
ImportError: dlopen(.../_mysql.cpython-310-darwin.so) Library not loaded: /opt/homebrew/opt/mysql/lib/libmysqlclient.21.dylib
This two parts are very important the .so
file where the library is trying to be loaded, and the .dylib
library being loaded.
Inside the terminal go to the folder the so
file is located
Inside that folder run the command
otool -L _mysql.cpython-310-darwin.so
and search for the current dylib version it's trying to find
Go to the /opt/homebrew/opt/mysql/lib/
folder and look for your actual file. In my case libmysqlclient.22.dylib
with a symlink named libmysqlclient.dylib
Change to the correct file with the command:
install_name_tool -change /opt/homebrew/opt/mysql/lib/{previous}.dylib /opt/homebrew/opt/mysql/lib/libmysqlclient.dylib _mysql.cpython-310-darwin.so
otool
command againotool -L _mysql.cpython-310-darwin.so
The output should be:
_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)
And that will get the error resolved and will let you continue with the migration process in DJango or get the server running again without the 500 error.
Upvotes: 5
Reputation: 9868
For me, I've got a problem after upgrading the MySQL
version, what worked for me is reinstalling the mysqlclient
python dependency but only when I disabled the cache like pip install --no-cache-dir mysqlclient
because the libmysqlclient.21.dylib
was already removed and replaced by the libmysqlclient.22.dylib
so symlinking doesn't help in here.
Upvotes: 8
Reputation: 21
I tried a lot of things but it ended up being as simple as renaming the folder mysql-8.0.26-macos11-x86_64 to "mysql" in usr/local/mysql-8.0.26-macos11-x86_64/lib/libmysqlclient.21.dylib. As soon as I did that, everything worked fine.
Upvotes: 0
Reputation: 7550
The symlink solution worked for me, but after linking the first file, I got the same error message for a different file name. In total, I had to symlink three different files.
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
Upvotes: 3
Reputation: 303
My project with Python 3.6 was lookin for libmysqlclient.21.dylib. I installed brew install mysql-client. It installed mysql-client 8.0. it has libmysqlclient.21.dylib. Where as i wanted to use [email protected]. So I copied the libmysqlclient.21.dylib from /usr/local/Cellar/mysql-client/8.0.19/lib to /usr/local/lib/
sudo ln -s /usr/local/Cellar/mysql-client/8.0.19/lib/libmysqlclient.21.dylib /usr/local/lib/libmysqlclient.21.dylib
Upvotes: 1
Reputation: 1110
I've recently had this issue when I was trying to install Django and mod_wsgi on my MacBook pro (MacOS Catallina). Setting LD_LIBRARY_PATH, DYLD_LIBRARY_PATH, adding sym link and moving the libmysqlclient.21.dylib to /usr/lib/ didn't work. I had to struggle for a few days but finally I got this solution. The thing is I had to modify the library path in the libmysqlclient.21.dylib. Fortunately we have a tool to do it. The culprit was @rpath/libmysqlclient.21.dylib. It looked like @rpath wasn't working.
Ok you can check the paths referred in a .so file using otool. It comes with Xcode. This is what you get when you run it on the mysql .so file (should be in the MySQLdb directory under your site-packages).
$ 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)
So we modify the filepath in the _mysql.cpython-38-darwin.so. There is a tool for that. It is install_name_tool. I ran these commands. Basically I changed @rpath to absolute path, and also the libssl and the licrypto paths to absolute path.
$ 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
My Django worked great after these changes.
Upvotes: 15
Reputation: 2809
Just create a symbolic link in /usr/local/lib
sudo ln -s /usr/local/mysql/lib/libmysqlclient.21.dylib /usr/local/lib/libmysqlclient.21.dylib
Upvotes: 22
Reputation: 353
So it turns out that I managed to solve my issue albeit in a bit of an unorthodox manner. If anyone else is using mysqlclient with a version of Python 3 and MySQL 8, give this a try and see if it helps! :)
I simply made a copy of the libmysqlclient.21.dylib
file located in my installation of MySQL 8.0.13 which is was in /usr/local/mysql/lib
and moved that copy under the same name to /usr/lib
.
You will however need to temporarily disable security integrity protection on your mac to do this since you won't have or be able to change permissions to anything in /usr/lib
without disabling it. You can do this by booting up into the recovery system, click Utilities on the menu at the top, and open up the terminal and enter csrutil disable
into the terminal. Just remember to turn security integrity protection back on when you're done doing this! The only difference from the above process will be that you run csrutil enable
instead.
After I did this, I ran my migrations like I did before on the new database and it worked! I honestly don't know how good of a solution this really is, but so far everything's been working perfectly since I changed the copy of .dylib
the connector was using. I hope this helps if you also have this issue!
You can read more about how to disable and enable macOS's security integrity protection here.
Upvotes: 2