1.

Django から MySQL / MariaDB に接続する設定方法|mysqlclient / pymysql

編集
この記事の要点
  • Django から MySQL / MariaDB に接続する設定方法
  • パッケージ: pip install mysqlclient(推奨)または pymysql
  • settings.pyDATABASESENGINEdjango.db.backends.mysql
  • NAME / USER / PASSWORD / HOST / PORT を本番値に合わせる
  • 文字コードは OPTIONScharset=utf8mb4 を指定(絵文字対応)

前提

  • MySQL / MariaDB がインストール済み・起動中
  • データベースとユーザーが作成済み
  • Django プロジェクトが既に django-admin startproject 済み

1. パッケージインストール

Django から MySQL に繋ぐにはドライバが必要です:

# 推奨: mysqlclient (C 実装で高速)
pip install mysqlclient

# Ubuntu / Debian で C ヘッダが必要
sudo apt install python3-dev default-libmysqlclient-dev build-essential pkg-config

# Mac (Homebrew)
brew install mysql pkg-config

# Windows は wheel が公式配布されているので普通に
pip install mysqlclient

# 代替: pymysql (Pure Python、ビルド不要)
pip install pymysql

pymysql を使う場合の追加設定

pymysql は MySQLdb のドロップイン代替なので、Django に「mysqlclient のフリ」をさせます:

# myproject/__init__.py (プロジェクトのルート)
import pymysql
pymysql.install_as_MySQLdb()

2. settings.py の DATABASES 設定

# myproject/settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mydb',
        'USER': 'myuser',
        'PASSWORD': 'mypassword',
        'HOST': '127.0.0.1',       # またはサーバ IP / ホスト名
        'PORT': '3306',
        'OPTIONS': {
            'charset': 'utf8mb4',
            'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
        },
    }
}

# 環境変数経由が安全
import os
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': os.environ['DB_NAME'],
        'USER': os.environ['DB_USER'],
        'PASSWORD': os.environ['DB_PASSWORD'],
        'HOST': os.environ.get('DB_HOST', '127.0.0.1'),
        'PORT': os.environ.get('DB_PORT', '3306'),
        'OPTIONS': {
            'charset': 'utf8mb4',
        },
    }
}

3. データベースとユーザーを作成

-- MySQL に root でログイン
mysql -u root -p

-- DB 作成(utf8mb4 で絵文字対応)
CREATE DATABASE mydb
    CHARACTER SET utf8mb4
    COLLATE utf8mb4_unicode_ci;

-- ユーザー作成
CREATE USER 'myuser'@'localhost' IDENTIFIED BY 'mypassword';

-- 権限付与(DB 全体)
GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'localhost';

-- リモート接続も許可するなら(本番では注意)
CREATE USER 'myuser'@'%' IDENTIFIED BY 'mypassword';
GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'%';

-- 反映
FLUSH PRIVILEGES;
\q

4. マイグレーション実行

# 接続確認 + 標準テーブル作成
python manage.py migrate

# 出力例:
# Operations to perform:
#   Apply all migrations: admin, auth, contenttypes, sessions
# Running migrations:
#   Applying contenttypes.0001_initial... OK
#   ...
#   Applying sessions.0001_initial... OK

# 接続成功!

5. 動作確認

# シェルから直接 SQL を叩く
python manage.py dbshell
mysql> SHOW TABLES;
mysql> exit

# Django shell から
python manage.py shell
>>> from django.db import connection
>>> with connection.cursor() as c:
...     c.execute("SELECT VERSION()")
...     print(c.fetchone())
...
('8.0.36',)

本番用の追加設定

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': os.environ['DB_NAME'],
        'USER': os.environ['DB_USER'],
        'PASSWORD': os.environ['DB_PASSWORD'],
        'HOST': os.environ['DB_HOST'],
        'PORT': os.environ.get('DB_PORT', '3306'),

        # コネクション維持(最大 600 秒)
        'CONN_MAX_AGE': 600,

        # SSL 接続
        'OPTIONS': {
            'charset': 'utf8mb4',
            'ssl': {
                'ca': '/etc/mysql/ca.pem',
                'cert': '/etc/mysql/client-cert.pem',
                'key': '/etc/mysql/client-key.pem',
            },
            # 文字コード周りの厳密設定
            'init_command': "SET sql_mode='STRICT_TRANS_TABLES', "
                            "NAMES utf8mb4 COLLATE utf8mb4_unicode_ci",
        },
    }
}

# 接続プール(django-db-connection-pool 等を利用)
# pip install django-db-connection-pool

複数 DB の同居(読み書き分離など)

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mydb_master',
        'HOST': 'mysql-master.example.com',
        # ...
    },
    'replica': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mydb_replica',
        'HOST': 'mysql-replica.example.com',
        # ...
    },
}

DATABASE_ROUTERS = ['myapp.routers.MasterReplicaRouter']

# myapp/routers.py
class MasterReplicaRouter:
    def db_for_read(self, model, **hints):
        return 'replica'
    def db_for_write(self, model, **hints):
        return 'default'
    def allow_relation(self, obj1, obj2, **hints):
        return True
    def allow_migrate(self, db, app_label, model_name=None, **hints):
        return db == 'default'

よくあるエラー

エラー原因対処
Can't connect to MySQL serverMySQL 未起動 / ポート不一致systemctl status mysql
Access denied for userUSER / PASSWORD 間違い / 権限不足GRANT 確認
Unknown database 'xxx'DB が存在しないCREATE DATABASE 実行
NameError: name '_mysql' is not definedmysqlclient ビルド失敗libmysqlclient-dev インストール
django.db.utils.OperationalError: (2002, ...)HOST が違う / ソケット権限HOST=127.0.0.1 で TCP 接続
(1366, "Incorrect string value")charset 不一致(絵文字を入れた)utf8mb4 に統一

utf8mb4 が必須な理由

  • MySQL の utf8 は実は 3 バイト UTF-8 だけ → 絵文字(4 バイト)が入らない
  • utf8mb4 が真の UTF-8(4 バイト)— 絵文字も OK
  • MariaDB 10.6 / MySQL 8.0 では utf8mb4 がデフォルトになりつつある
  • DB / テーブル / カラム / 接続 すべてを utf8mb4 に揃える

関連

  • django-environ: DATABASE_URL=mysql://user:pass@host/db 形式の環境変数を自動展開
  • dj-database-url: 同上のパッケージ
  • django-db-geventpool: 非同期環境用接続プール
  • Django Migrations: モデル変更を SQL に変換
編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. MySQL/MariaDBへの接続
  2. sqliteへの接続
  3. SELECT, INSERT, UPDATE, DELETE
  4. 素のSQLを直接実行する方法
  5. Order by DESCの指定方法
  6. limit, offsetの指定方法
  7. filterの検索オプション
  8. django-filterのlookup_expr検索オプション
  9. モデルの内部結合(1対1)