怎样在Django项目中配置MySQL 8.0作为后端数据库?

作者:袖梨 2026-07-16
MySQL 8.0 默认认证插件 caching_sha2_password 不兼容 Django,需改为 mysql_native_password;必须使用 mysqlclient 驱动并配置 utf8mb4 字符集、127.0.0.1 主机及严格 SQL 模式。

确认 MySQL 8.0 默认认证插件是否兼容 Django

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: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

安装并配置 mysqlclient(不是 PyMySQL)

Django 官方推荐且性能更优的 MySQL 驱动是 mysqlclient,它基于 C 扩展;PyMySQL 虽纯 Python、可直接 pip install,但不支持 MySQL 8.0 的部分特性(如某些 JSON 函数),且在高并发下表现较差。

安装前需确保系统级依赖已就位:

  • Ubuntu/Debian:sudo apt-get install python3-dev default-libmysqlclient-dev build-essential
  • macOS(Homebrew):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。

修改 Django 的 DATABASES 配置

settings.py 中的 DATABASES 必须显式指定 ENGINEOPTIONS,否则可能触发隐式编码问题或连接超时。

最小可用配置示例:

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',        }    }}

关键点说明:

  • charsetTEST.CHARSET 必须设为 utf8mb4,否则 emoji 或四字节 UTF-8 字符会截断或报错
  • init_command 可防止因 MySQL 8.0 严格模式导致的 Field 'xxx' doesn't have a default value 类错误
  • 不要用 localhostHOST——它会触发 Unix socket 连接,可能绕过 TCP 设置;改用 127.0.0.1 更可控

运行 migrate 前务必检查 MySQL 全局配置

Django 的 migrate 在 MySQL 8.0 上失败,往往不是代码问题,而是服务端限制。

进入 MySQL 执行以下检查:

  • SHOW VARIABLES LIKE 'sql_mode'; —— 若含 NO_ZERO_DATENO_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 *.* 更安全,也避免因权限缓存导致的偶发拒绝连接。

相关文章

精彩推荐