Skip to content
Happy Programming Guide
Start learning
Python

ModuleNotFoundError: No Module Named ‘mysql’

The MySQL connector is not installed in the Python you are running. Here is how to install the right package, check which Python is active, and avoid the three lookalike packages.

The inside of a computer with its parts visible

ModuleNotFoundError: No module named 'mysql' means the MySQL connector is not installed in the interpreter running your script. The package you almost certainly want is mysql-connector-python, and the most common cause of the error persisting after installing it is that pip installed into a different Python than the one running your code.

The quick fix#

Terminal
python -m pip install mysql-connector-python
Python
import mysql.connector

conn = mysql.connector.connect(
    host="localhost", user="root", password="secret", database="shop"
)
print(conn.is_connected())
conn.close()

Use python -m pip rather than plain pip. It guarantees the install goes into the same interpreter you are about to run, which removes the single most common cause of this error surviving the fix.

Why the names do not match#

You install mysql-connector-python but import mysql.connector. That mismatch is normal in Python — the name on PyPI and the name you import are set independently. It is why searching for the error text alone often leads people to install the wrong thing.

The three MySQL libraries#

Install Import Notes
mysql-connector-python mysql.connector Official from Oracle, pure Python, easiest to install
PyMySQL pymysql Pure Python, popular with SQLAlchemy and Django
mysqlclient MySQLdb C extension, fastest, needs build tools installed

Pick one. Installing all three does not help and makes it harder to work out what your code is actually using.

When installing did not fix it#

The install almost always succeeded — into a different Python. Check both sides:

Terminal
python -c "import sys; print(sys.executable)"
python -m pip --version

The path printed by the first command and the path inside the second should share a prefix. If they do not, you have more than one Python and pip belongs to the other one.

Terminal
python -m pip show mysql-connector-python

If that reports nothing while pip show finds it, that is the mismatch confirmed. Always install with python -m pip.

Virtual environments#

Packages installed globally are not visible inside a virtual environment, and the other way round:

Terminal
python -m venv .venv

source .venv/bin/activate        # macOS and Linux
.venv\Scripts\activate           # Windows

python -m pip install mysql-connector-python
python -m pip freeze > requirements.txt

If the prompt does not start with (.venv), activation did not take effect and you are installing somewhere else.

VS Code#

VS Code picks its own interpreter, which is often not the one in your terminal. Open the command palette with Ctrl+Shift+P, run Python: Select Interpreter, and choose the one inside your project’s .venv. Then check from inside the editor:

Python
import sys
print(sys.executable)

Jupyter#

A notebook has its own kernel, which may be a different environment again. Install from inside the notebook so it cannot disagree:

Python
import sys
!{sys.executable} -m pip install mysql-connector-python

Then restart the kernel. Python caches imported modules, so a newly installed package is not visible until the kernel restarts.

Docker#

The package has to be installed inside the image, not on your machine:

Output
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]

If you added the dependency after building, rebuild — the layer is cached and will not pick up a new requirements file on its own.

Connecting properly once it imports#

Python
import os
import mysql.connector
from mysql.connector import Error

try:
    conn = mysql.connector.connect(
        host=os.environ.get("DB_HOST", "localhost"),
        user=os.environ["DB_USER"],
        password=os.environ["DB_PASSWORD"],
        database=os.environ["DB_NAME"],
    )

    cursor = conn.cursor(dictionary=True)
    cursor.execute("SELECT id, name FROM products WHERE price < %s", (20,))
    for row in cursor.fetchall():
        print(row["id"], row["name"])

except Error as error:
    print("Database error:", error)

finally:
    if "conn" in locals() and conn.is_connected():
        cursor.close()
        conn.close()

Two things worth copying: credentials come from environment variables rather than the source file, and the query uses %s placeholders rather than string formatting. Building SQL with f-strings is how SQL injection happens.

Questions people ask#

Which connector should I choose?

mysql-connector-python if you want the fewest installation problems. PyMySQL if you are using SQLAlchemy or Django. mysqlclient only when you have measured that connector speed matters.

Does this work with MariaDB?

Yes. MariaDB speaks the MySQL protocol and all three libraries connect to it. There is also a dedicated mariadb package if you need MariaDB-specific features.

Why does it work in the terminal but not in my IDE?

Different interpreter. Print sys.executable in both places — the paths will differ, and pointing the IDE at the right one fixes it.

I get a build error installing mysqlclient

That package compiles C code and needs MySQL development headers plus a compiler. Unless you specifically need it, switch to mysql-connector-python, which is pure Python and installs anywhere.

Where to go next#

Python virtual environments, and why imports keep failing without themRead next

Keep reading

Keep going — pick your next guide

The fastest way to improve is to read one guide, then build the thing it describes. Start with the basics, or jump straight to a project.

Ask a question or share what worked

Your email address will not be published. Required fields are marked *