5.

ModuleNotFoundError: No module named 'MySQLdb' の原因と対処(Django + MySQL)

編集
この記事の要点
  • Django で MySQL を使う際に発生。MySQLdb は Python 2 用のドライバ名で、Python 3 では別物が必要
  • 解決策 A: pip install mysqlclient(C 拡張、要コンパイラ・最も高速)
  • 解決策 B: pip install PyMySQL(純 Python、コンパイラ不要) + pymysql.install_as_MySQLdb()
  • Ubuntu でビルドエラー → sudo apt install python3-dev default-libmysqlclient-dev build-essential pkg-config
  • macOS でビルドエラー → brew install mysql-client pkg-config + export PKG_CONFIG_PATH
  • Django 公式は mysqlclient を推奨(PyMySQL は性能・機能で見劣り)

エラーの全文

Traceback (most recent call last):
  File "manage.py", line 22, in 
    main()
  ...
  File "/usr/lib/python3.10/site-packages/django/db/backends/mysql/base.py", line 15, in 
    import MySQLdb as Database
ModuleNotFoundError: No module named 'MySQLdb'

原因

Django の django.db.backends.mysql ドライバは内部で import MySQLdb しています。しかし MySQLdb は Python 2 時代のパッケージ名で、現在は次のどちらかが提供する必要があります:

パッケージ実体長所短所
mysqlclientlibmysqlclient の C 拡張高速・Django 公式推奨C コンパイラと開発ヘッダ必要
PyMySQL純 Python 実装pip だけで入る性能劣・SSL 制限あり
mysql-connector-pythonOracle 公式純 PythonDjango が公式対応していない場合あり

対処A: mysqlclient をインストール(推奨)

# 仮想環境を有効化してから
source venv/bin/activate

# インストール
pip install mysqlclient

# 確認
python -c "import MySQLdb; print(MySQLdb.__version__)"
# 2.2.0

ビルドエラーが出る場合の OS 別対応:

# Ubuntu / Debian
sudo apt update
sudo apt install python3-dev default-libmysqlclient-dev build-essential pkg-config

# CentOS / RHEL / Rocky Linux
sudo yum install python3-devel mysql-devel gcc

# Fedora
sudo dnf install python3-devel mysql-devel gcc

# macOS(Homebrew)
brew install mysql-client pkg-config
export PKG_CONFIG_PATH="/opt/homebrew/opt/mysql-client/lib/pkgconfig"
# Apple Silicon の場合
export LDFLAGS="-L/opt/homebrew/opt/mysql-client/lib"
export CPPFLAGS="-I/opt/homebrew/opt/mysql-client/include"

# Windows
# wheel が公式に提供されているのでビルド不要
pip install mysqlclient
# 失敗するなら https://www.lfd.uci.edu/~gohlke/pythonlibs/ から wheel をダウンロード

対処B: PyMySQL を MySQLdb の代わりに使う

コンパイラを入れたくない場合、PyMySQL を「MySQLdb のフリ」をさせます:

pip install PyMySQL
# myproject/__init__.py(settings.py と同じ階層)
import pymysql
pymysql.install_as_MySQLdb()

これで Django から import MySQLdb しても PyMySQL が応答します。

注意: Django 4.0+ では PyMySQL のバージョンチェックで弾かれることがあります。その場合は:

# myproject/__init__.py
import pymysql

# Django のバージョンチェックを欺くため version_info を上書き
pymysql.version_info = (1, 4, 6, 'final', 0)
pymysql.install_as_MySQLdb()

settings.py の DATABASES 設定例

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mydb',
        'USER': 'myuser',
        'PASSWORD': 'mypass',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'OPTIONS': {
            'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
            'charset': 'utf8mb4',
        },
        'CONN_MAX_AGE': 60,
    }
}

requirements.txt への記載

# mysqlclient を使う場合(推奨)
Django>=4.2,<5.0
mysqlclient>=2.2.0

# PyMySQL を使う場合
Django>=4.2,<5.0
PyMySQL>=1.1.0
cryptography>=41.0.0   # PyMySQL で SSL/caching_sha2_password を使うなら必須

動作確認

# Python から接続テスト
python manage.py shell
>>> from django.db import connection
>>> connection.ensure_connection()
>>> print(connection.connection)


# マイグレーション実行
python manage.py migrate

# 接続情報表示
python manage.py dbshell

FAQ

Q: mysqlclient と PyMySQL どちらを選ぶ?
A: 本番ならmysqlclient。CI / Docker でビルド時間を惜しむなら PyMySQL。Django 公式ドキュメントは mysqlclient を推奨しています。

Q: caching_sha2_password エラーが出る
A: MySQL 8 のデフォルト認証方式。PyMySQL なら pip install cryptography も必須。mysqlclient なら標準対応。

Q: Docker で mysqlclient のビルドが遅い
A: マルチステージビルドにする、または FROM python:3.11-bookworm を使い apt install でヘッダを入れる。Alpine は apk add mariadb-dev

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. Invalid HTTP_HOST header: '...'. You may need to add '...' to ALLOWED_HOSTS
  2. CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False.
  3. django.utils.datastructures.MultiValueDictKeyError
  4. Forbidden (403) CSRF verification failed. Request aborted.
  5. ModuleNotFoundError: No module named 'MySQLdb'
  6. WARNINGS: ?: (mysql.W002) MySQL Strict Mode is not set for database connection
  7. Unknown column 'table_name.id' in 'field list'
  8. RuntimeError: Model class ~ doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
  9. get() returned more than one MynumberRegist -- it returned 2!
  10. django.db.utils.OperationalError: (2006, "Can't connect to MySQL server")
  11. 'include' is not defined