【初心者向け】Python仮想環境のDjangoとdockerコンテナのMySQLとの接続
Djangoアプリはデフォルトでsqlite3が使えるように設定されていますが、MySQLに変更したい場合があります。ホスト環境で動作しているMySQL(v8.0.41)との接続から検証します。設定変更は簡単ですが、専用のドライバーをインストールする必要があります。まずはここを押さえておいて、Dockerコンテナで起動しているMySQLと接続する場合を考えます。
Dockerコンテナにはバージョンの異なる2種類があったとします。今の開発環境ではどちらにも接続できるのか、どちらかにしか接続できないのか、ホスト側の接続方法との違いはあるのかなど、知っておかないと無駄に時間を費やすことになります。
ここではDjangoプロジェクトは全てPythonの仮想環境上で開発しているものとし、データベースのみを切り替える場合についてメモします。
目次
検証環境
- OS : Ubuntu 22.04
 - MySQL(Host) : v8.0.41
 - MySQL (Docker) : v5.7 / v8.0
 
検証模式図

Djangoの設定
まずは仮想環境に入って、何も考えず最新のDjangoをインストールします。
pip install django
pip freeze
  asgiref==3.8.1
  Django==5.1.6      # ⬅これを使用する
  sqlparse==0.5.3
  typing_extensions==4.12.2django-admin startproject <project_name>コマンドでprojectの作成と、python manage.py startapp <app_name>コマンドでアプリの作成、それとtemplatesフォルダの作成と、settings.pyの基本設定を行ってから、python manage.py runserver でサーバーが起動されることをURL:"localhost:8000"で確認します。
ホスト側のMySQLと接続
- settings.pyでデータベースをデフォルトのsqlite3からmysqlに変更します。
MySQLに切り替えるときは事前にデータベース側の設定は終えておいてください。 
settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_db', 
        'USER': 'django_user',
        'PASSWORD': 'django_pass',
        'HOST': 'localhost',
         'PORT': '3306', 
    }
}- 初期設定のまま、サーバー起動しようとしてもできません。
 
django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.
Did you install mysqlclient?ここでmysqlclientをインストールします。
pip install mysqlclient
 #....中略....
  Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> See above for output.
note: This error originates from a subprocess, and is likely not a problem with pip.しかしエラーが発生しました。Djangoアプリケーションが別のプロセス(サブプロセス)を起動した際に、そのサブプロセス内でエラーが発生したことを意味します。mysqlclient パッケージのインストール中にエラーが発生した模様。そこで、必要なモジュールをインストールします。
- 解決策
 
sudo apt update
sudo apt upgrade
sudo apt install libmysqlclient-dev    # ⬅ インストールされているDBがMySQLの場合
# または
sudo apt install libmariadb-dev    # ⬅ インストールされているDBがMariaDBの場合その後、pip install mysqlclient を実行すると、mysqlclientのインストールに成功!!
その後、python manage.py runserverで正常にサーバーが起動しました。
結論
- django(v5.16)にmysqlと接続するときはmysqlclientをインストールすること。
 - インストール中に「This error originates from a subprocess」のエラーが出るときは、libmysqlclient-devもしくはlibmariadb-devのどちらかを先にインストールします。
 
DockerコンテナのMySQLと接続
以下の"dopcker-compose.yml"ファイルから、コンテナを作成します。
# 起動
sudo docker compose up -d
# 停止
sudo docker compose stop
# 再起動
sudo docker compose restartversionが8.0系のとき
docker-compose.yml
version: "2.18"
services:
  mysql:
    image: mysql:latest  # 8.0.31
    ports:
      - '3326:3306'  # ← ローカルポート3326 とdockerコンテナ内部のポート3306とを接続
    volumes:
      - './mysql_data:/var/lib/mysql'  
    environment:
      MYSQL_ROOT_PASSWORD: root_pass
      MYSQL_DATABASE: django_db 
      MYSQL_USER: dbuser
      MYSQL_PASSWORD: dbuser_pass
  # -- phpmyadminで確認できるようにしています...
  phpmyadmin:
    image: phpmyadmin/phpmyadmin:latest
    depends_on:
      - mysql
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOSTS=mysql
      - PMA_USER=root
      - PMA_PASSWORD=root_pass
    ports:
      - "8098:80"
volumes:
  mysql_data:
    driver: local
このときの"settings.py"のデータベースに関する設定は以下の通りです。
settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_db', 
        #  -- ここを修正する! 
        'USER': 'root',  
        'PASSWORD': 'root_pass',  # ← rootユーザーのパスワード
        'HOST': '127.0.0.1',     #  ← IPアドレスを入れる (※普通は127.0.0.1に設定されているはず)
        'PORT': '3326',              #  ← local port を入れる
    }
}これで"python manage.py runserver"で起動すると正常に起動しました。動的に切り替えたいので、この間でもローカルホストではmysqlサーバーが起動しているものとします。
設定におけるポイント
- HOST名にはドメイン名(localhost)を使わずIPアドレス(127.0.0.1)で記述する。
 - PORT番号にはローカル側のポート番号を記入する。
 - USERは必ずrootユーザーで入る。
 
versionが5.7系のとき
docker-compose.yml
version: "2.18"
services:
  mysql:
    image: mysql:5.7  
    ports:
      - '3328:3306'
    volumes:
      - './mysql_data:/var/lib/mysql'  
    environment:
      MYSQL_ROOT_PASSWORD: root_pass
      MYSQL_DATABASE: django_db 
      MYSQL_USER: dbuser
      MYSQL_PASSWORD: dbuser_pass
  # -- phpmyadminで確認できるようにしています...
  phpmyadmin:
    image: phpmyadmin/phpmyadmin:latest
    depends_on:
      - mysql
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOSTS=mysql
      - PMA_USER=root
      - PMA_PASSWORD=root_pass
    ports:
      - "8099:80"
volumes:
  mysql_data:
    driver: local
このときの"settings.py"のデータベースに関する設定は以下の通りです。
settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_db', 
        #  -- ここを修正する! 
        'USER': 'root',  
        'PASSWORD': 'root_pass',  # ← rootユーザーのパスワード
        'HOST': '127.0.0.1',     #  ← IPアドレスを入れる
        'PORT': '3328',              #  ← local port を入れる
    }
}mysqlのversionのみをv8.0.31➡v5.7.42に変更した場合、先程と同様に"python manage.py runserver"で起動しても起動できません。
「django.db.utils.NotSupportedError: MySQL 8.0.11 or later is required (found 5.7.42).」のエラーが出ます。
これは、使用中のDjangoがv5.1.6と最新のVersionを使っているにも関わらず、MySQLコンテナのバージョンが5.7.42と古いことが原因です。MySQLのバージョンは8.0.11以降でないといけないと注意されています。
対策
- Djangoのversionを下げてプロジェクトを作る。
 - Django 4.1はMySQL 5.7をサポートしています。
 
省略しますが、実際にDjango 4.1に下げて検証したところ上手く起動できました😀
よって、Django v5.1.6でプロジェクトを組む場合はMySQLはv8.0.11以降にしてください。
以上になります。😀

