How to use PyMySQL as a Drop-in Replacement for mysqlclient in Django
If you have ever tried to deploy a Django project to a budget friendly shared hosting provider such as the common cPanel environments, you have probably encountered a frustrating obstacle. The mysqlclient installation error.
You run pip install mysqlclient and the terminal immediately starts complaining about missing mysql_config, libmysqlclient, or C compilers that you do not have permission to install. This happens because mysqlclient is a C extension package that requires system libraries and build tools to compile during installation.
In most shared hosting environments using cPanel, you usually do not have SSH or root access to install these dependencies. In many cases the server does not include them at all. As a result, installing mysqlclient becomes difficult and sometimes completely impossible.
Fortunately, there is a simple workaround that does not require upgrading to a VPS or changing your database.
The Problem: The C Dependency Trap
The standard way to connect Django to MySQL is through mysqlclient. It performs well because it is written in C, but that advantage becomes a problem on restricted hosting environments.
To install mysqlclient, the server typically needs:
- Python development headers
- MySQL client development libraries
- A C compiler such as
gcc
Shared hosting environments usually provide none of these. You are limited to installing pure Python packages through pip. If a package requires compilation during installation, it will almost always fail.
The Alternative: PyMySQL
PyMySQL is a pure Python MySQL client library. Because it does not rely on C extensions, it installs easily with pip even in restricted environments such as shared hosting.
However, Django’s MySQL backend expects a module called MySQLdb, which is provided by mysqlclient. If Django cannot import MySQLdb, it will refuse to start even if PyMySQL is installed.
The Solution: Monkey Patching Django
The solution is to make Django believe that PyMySQL is actually MySQLdb. This technique is known as monkey patching in Python. It works by registering PyMySQL under the name Django expects.
1. Install PyMySQL
Install the package in your environment:
pip install PyMySQLIf you are using shared hosting with cPanel, you can also add PyMySQL to your requirements.txt file and install it using the Python selector.
2. The Magic Lines
Open your project folder and locate the __init__.py file in the same directory as settings.py. Add the following lines at the top of the file.
import pymysql
pymysql.version_info = (1, 4, 2, "final", 0)
pymysql.install_as_MySQLdb()When install_as_MySQLdb() is executed, PyMySQL registers itself in Python’s module system as MySQLdb. Later, when Django tries to import MySQLdb, Python loads PyMySQL instead.
From Django’s perspective everything works normally. Django believes it is using MySQLdb, while PyMySQL handles the database communication internally.
The version_info line is a compatibility adjustment. It makes PyMySQL report a version number that Django expects from MySQLdb, preventing potential version checks from failing.
3. Update your Database Engine
Ensure your DATABASES setting in settings.py is still using the standard MySQL backend. You don’t need to change the engine name to anything else keep it as the default:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'your_db_name',
'USER': 'your_db_user',
'PASSWORD': 'your_db_password',
'HOST': 'localhost',
'PORT': '3306',
}
}Why this is a Lifesaver for Shared Hosting
I discovered this approach while helping a friend deploy a small Django application on a local Nepali hosting provider. Since it was a typical shared hosting environment, we did not have SSH or root access to install system level packages. The only available tool was the Python selector inside cPanel.
Another challenge was that many cPanel environments either do not include mysqlclient or do not allow installing Python packages that require C extensions. The mysqlclient package depends on the system library libmysqlclient and must be compiled during installation. Without SSH access or build tools on the server, installation becomes extremely difficult.
Using PyMySQL solves this problem because it is implemented entirely in Python and does not require any compilation
- No Root Required: Everything works within normal user permissions.
- Portability: Your
requirements.txtfile stays simple and works across different environments. - Compatibility:
PyMySQLsupports the features Django requires for typical database operations.
Are there any Downsides?
While this workaround is excellent for shared hosting, there are a couple of things to keep in mind.
- Performance: Since
PyMySQLis implemented in Python, it is technically slower than the C basedmysqlclient. In practice, most small and medium sized applications will not notice any meaningful difference. - Advanced MySQL Features: In rare cases involving advanced MySQL behavior or specialized extensions, there might be small differences. For standard Django models and queries, PyMySQL works reliably.
Production and Development Tip
If you want to keep using the faster mysqlclient locally but fallback to PyMySQL on restricted server, you can use a conditional import.
try:
import MySQLdb
except ImportError:
import pymysql
pymysql.version_info = (1, 4, 2, "final", 0)
pymysql.install_as_MySQLdb()This allows your project to automatically use mysqlclient when available and switch to PyMySQL when it is not.
Final Thoughts
Shared hosting can be restrictive for Django deployments, but it is still one of the most affordable ways to launch a small project. Using PyMySQL as a replacement for mysqlclient removes one of the most common deployment barriers without requiring server level access or additional costs.
If you are deploying Django on a cPanel based host and encounter mysqlclient installation errors, this approach can save a significant amount of time and frustration.
Give it a try on your next deployment.
Happy Coding!