Django
MySQL
Database Integration
Web Development
Python

Setting Django up to use MySQL

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Configuring Django for MySQL is mostly a matter of installing the client driver, creating the database and user, and pointing settings.py at the correct connection details. The important part is to get the database encoding and privileges right early, because those choices affect every migration and every text field you store later.

Install the MySQL Driver

Django needs a Python driver to talk to MySQL. The standard choice is mysqlclient.

bash
python -m pip install mysqlclient

After installation, verify the package imports:

bash
python -c "import MySQLdb; print('ok')"

If you are on a system where mysqlclient compilation is difficult, you may need the platform's MySQL development headers first. It is better to fix that environment issue directly than to guess at Django settings.

Create the Database and Application User

Do not point Django at the MySQL root account. Create a dedicated database and a dedicated user instead.

sql
1CREATE DATABASE mysite CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
2CREATE USER 'mysite_user'@'localhost' IDENTIFIED BY 'strong-password';
3GRANT ALL PRIVILEGES ON mysite.* TO 'mysite_user'@'localhost';
4FLUSH PRIVILEGES;

Using utf8mb4 matters because it supports the full Unicode range, including emoji and supplementary characters.

Configure settings.py

In your Django project, replace the default SQLite configuration with MySQL connection settings.

python
1DATABASES = {
2    "default": {
3        "ENGINE": "django.db.backends.mysql",
4        "NAME": "mysite",
5        "USER": "mysite_user",
6        "PASSWORD": "strong-password",
7        "HOST": "127.0.0.1",
8        "PORT": "3306",
9        "OPTIONS": {
10            "charset": "utf8mb4",
11        },
12    }
13}

Using 127.0.0.1 instead of localhost can matter on some systems because it forces TCP instead of a local socket. Either can be correct, but pick the one that matches how your MySQL server is configured.

Run Migrations

Once the connection is configured, apply Django's schema:

bash
python manage.py migrate

If that succeeds, create an admin user:

bash
python manage.py createsuperuser

Then start the development server:

bash
python manage.py runserver

At that point, Django is using MySQL as the default database backend.

Environment Variables for Real Projects

Hardcoding passwords in settings.py is fine for a quick local example, but real applications should read secrets from environment variables.

python
1import os
2
3DATABASES = {
4    "default": {
5        "ENGINE": "django.db.backends.mysql",
6        "NAME": os.environ["DB_NAME"],
7        "USER": os.environ["DB_USER"],
8        "PASSWORD": os.environ["DB_PASSWORD"],
9        "HOST": os.environ.get("DB_HOST", "127.0.0.1"),
10        "PORT": os.environ.get("DB_PORT", "3306"),
11        "OPTIONS": {
12            "charset": "utf8mb4",
13        },
14    }
15}

That keeps sensitive settings out of source control and makes deployment easier.

Verifying the Connection From Django

After configuration, it is worth testing the connection path directly from Django before you build application features on top of it. A quick database shell check confirms that Django can authenticate and reach the server:

bash
python manage.py dbshell

If that command opens a MySQL prompt, your driver, credentials, and connection settings are lined up correctly. It is a faster diagnostic step than guessing from later ORM failures.

Common Pitfalls

The most common mistake is forgetting to install the MySQL driver in the same Python environment that runs Django. The settings can be correct and manage.py migrate still fails if the package is missing.

Another issue is using MySQL root credentials for the application. That works initially but creates unnecessary risk and makes least-privilege access harder later.

A third pitfall is skipping utf8mb4. Older MySQL defaults can silently limit stored characters, which becomes painful after data already exists.

Finally, check whether your host value implies a socket or TCP connection on your platform. A mismatch there often shows up as confusing connection failures even though the username and password are correct.

Summary

  • Install mysqlclient so Django can talk to MySQL.
  • Create a dedicated database and non-root application user.
  • Configure DATABASES with the MySQL backend and utf8mb4.
  • Run Django migrations to initialize the schema.
  • Move credentials to environment variables for real deployments.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.