MySQL 8.0 默认认证插件 caching_sha2_password 不兼容 Django,需改为 mysql_native_password;必须使用 mysqlclient 驱动并配置 utf8mb4 字符集、127.0.0.1 主机及严格 SQL 模式。
Django 3.2+ 原生支持 MySQL 8.0,但前提是 MySQL 用户不能使用 caching_sha2_password 插件——这是 MySQL 8.0 的默认认证方式,而 Django(包括 mysqlclient)目前只支持 mysql_native_password。
常见错误现象:django.db.utils.OperationalError: (1045, "Access denied for user 'myuser'@'localhost' (using password: YES)"),即使密码正确也会报这个错。
mysql -u root -p
ALTER USER 'myuser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password';
FLUSH PRIVILEGES;
SELECT host, user, plugin FROM mysql.user WHERE user = 'myuser';,确保 plugin 列值为 mysql_native_password
Django 官方推荐且性能更优的 MySQL 驱动是 mysqlclient,它基于 C 扩展;PyMySQL 虽纯 Python、可直接 pip install,但不支持 MySQL 8.0 的部分特性(如某些 JSON 函数),且在高并发下表现较差。
安装前需确保系统级依赖已就位:
sudo apt-get install python3-dev default-libmysqlclient-dev build-essential
brew install mysql-client,再设置环境变量:export PATH="/opt/homebrew/opt/mysql-client/bin:$PATH"
pip install mysqlclient
若仍编译失败,检查 mysql_config 是否在 $PATH 中,或用 mysql_config --version 确认其输出为 8.0.x。
settings.py 中的 DATABASES 必须显式指定 ENGINE 和 OPTIONS,否则可能触发隐式编码问题或连接超时。
最小可用配置示例:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'myproject_db', 'USER': 'myuser', 'PASSWORD': 'your_password', 'HOST': '127.0.0.1', 'PORT': '3306', 'OPTIONS': { 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'", 'charset': 'utf8mb4', }, 'TEST': { 'CHARSET': 'utf8mb4', 'COLLATION': 'utf8mb4_unicode_ci', } }}
关键点说明:
charset 和 TEST.CHARSET 必须设为 utf8mb4,否则 emoji 或四字节 UTF-8 字符会截断或报错init_command 可防止因 MySQL 8.0 严格模式导致的 Field 'xxx' doesn't have a default value 类错误localhost 当 HOST——它会触发 Unix socket 连接,可能绕过 TCP 设置;改用 127.0.0.1 更可控Django 的 migrate 在 MySQL 8.0 上失败,往往不是代码问题,而是服务端限制。
进入 MySQL 执行以下检查:
SHOW VARIABLES LIKE 'sql_mode'; —— 若含 NO_ZERO_DATE 或 NO_ZERO_IN_DATE,Django 3.2+ 的 DateField(null=True) 可能报错,建议保留 STRICT_TRANS_TABLES 即可SHOW VARIABLES LIKE 'max_allowed_packet'; —— 若小于 64M,大 migration 文件(如含 BLOB 字段)会中断SELECT @@collation_database; —— 应为 utf8mb4_unicode_ci,否则新建表默认排序规则不一致这些参数需在 /etc/mysql/my.cnf(Linux)或 /usr/local/etc/my.cnf(macOS)中持久化设置,仅 session 级修改在重启后失效。
MySQL 8.0 的权限模型更细粒度,GRANT ALL PRIVILEGES ON myproject_db.* TO 'myuser'@'127.0.0.1'; 比 GRANT ALL ON *.* 更安全,也避免因权限缓存导致的偶发拒绝连接。