Fixing the “Symbol not found: _mysql_affected_rows” Error on macOS M1 with Python 3.6 and mysqlclient

Mac M1, Python, and the Mysterious _mysql_affected_rows Error

Akshay Gaikwad
AgroStar Technology
4 min readOct 31, 2023

--

Introduction

Developers who’ve transitioned to the new Apple Silicon M1 Macs have faced an array of challenges when it comes to software compatibility. One such issue is the “Symbol not found: _mysql_affected_rows” error when trying to use the mysqlclient library with Python 3.6. This blog post aims to resolve that issue by guiding you through a step-by-step process to get mysqlclient working smoothly on your M1 Mac.

Why Does This Issue Occur?

The underlying issue is rooted in architecture and compatibility. The Apple M1 chip is ARM-based, whereas most of the software libraries and dependencies are designed for Intel’s x86_64 architecture. This difference can lead to the “Symbol not found: _mysql_affected_rows” error.

Photo by Mia Baker on Unsplash

Step-by-Step Guide to Fix the Issue

Step 1: Install Python 3.6.8

First, you need to download and install Python 3.6.8 for macOS M1. You can get it here.

Step 2: Clone Homebrew and Install MySQL Client

cd /opt
git clone https://github.com/Homebrew/brew.git
arch -x86_64 brew/bin/brew install mysql-client@5.7

We are using `arch -x86_64` to specify that we want to install the package built for the x86_64 architecture since the M1-based package has problems. Note that even though the M1 chip cannot run x86_64 binaries directly, there is a software called Rosetta which is a dynamic binary translator and emulator developed by Apple for macOS. It allows users to run apps that contain x86–64 instructions on Apple silicon

Step 3: Update Environment Variables

Add the following lines to your `.zshrc`:

export LIBRARY_PATH=$LIBRARY_PATH:/opt/brew/opt/openssl@1.1/lib/
export PATH="/opt/brew/opt/mysql-client@5.7/bin:$PATH"
alias python86='CPPFLAGS="-I/opt/brew/opt/openssl@1.1/include" LDFLAGS="-L/opt/brew/opt/openssl@1.1/lib" MYSQLCLIENT_CFLAGS="-I/opt/brew/Cellar/mysql-client@5.7/5.7.42/include/mysql" MYSQLCLIENT_LDFLAGS="-L/opt/brew/Cellar/mysql-client@5.7/5.7.42/lib -lmysqlclient" arch -x86_64'

These lines are critical for directing the system to use the correct library paths and ensuring that the mysqlclient installation will be compatible with your M1 architecture.

Step 4: Virtual Environment Setup

Navigate to your project folder and set up a virtual environment:

python3.6 -m venv .env
source .env/bin/activate

Step 5: Update `requirements.txt`

Before installing the packages, comment out mysqlclient in your `requirements.txt` file. This allows us to install other packages first.

Step 6: Install mysqlclient

Finally, run the following command to install mysqlclient:

python86 python3.6 -m pip install mysqlclient==1.4.4

You can install a specific version by mentioning the version just like the normal pip install command.

Important Note: Always Use Custom Alias for Future Installations

After following the steps outlined above, it’s crucial to remember to always use your custom alias when installing mysqlclient in the future. If you default back to the regular installation command, you will inadvertently install the ARM architecture version of the library, which will result in the “Symbol not found: _mysql_affected_rows” error.

So, if you set up your alias as `python86` for Python 3.9, always use the following command for installing mysqlclient:

python86 python3.9 -m pip install mysqlclient  # Replace python86 and 3.9 with your custom alias and Python version

Failure to use this custom alias will negate all the compatibility work you’ve done, leading to errors and potential headaches.

And that’s it!

Congratulations! You’ve successfully navigated through the challenges posed by the architecture transition in Apple’s M1 chip and managed to install mysqlclient on Python 3.6. This setup ensures that you don’t run into the “Symbol not found: _mysql_affected_rows” error. While the transition to M1 has its complexities, solutions like these make it easier for developers to adapt and continue working efficiently.

Adapting for Other Python Versions

You might be wondering if these steps are exclusive to Python 3.6. The good news is that they can be adapted for other Python versions as well! Here’s how:

Install The Desired Python Version

First, download and install the version of Python you wish to use, just like we did for Python 3.6.8 in Step 1. The Python official website has various versions available for download.

Virtual Environment Setup

Set up a new virtual environment for your project using your desired Python version:

python3.9 -m venv .env
source .env/bin/activate

Install mysqlclient

Use your custom alias and the installed Python version to install mysqlclient:

python86 python3.9 -m pip install mysqlclient==1.4.4

And that’s it! You’ve successfully adapted the steps for another Python version.

Final Thoughts

Compatibility issues can be a major roadblock, but with a bit of tinkering and understanding of the underlying architecture, these challenges can be overcome. Whether you’re using Python 3.6, 3.9, or any other version, the steps outlined above can help you install mysqlclient seamlessly on your Apple M1 Mac.

Conclusion

By taking careful steps to navigate around the architectural differences in the Apple M1 chip, you can ensure smooth sailing with mysqlclient on Python 3.6 or any other version. Remember to always use the custom alias for installing mysqlclient to avoid running into compatibility issues. Happy coding!

--

--