本文解决的报错
RuntimeError: 'cryptography' package is required for sha256_password or caching_sha2_password auth methods
连 MySQL 报 "cryptography package is required"
本地 SQLite 跑得好好的,换成服务器上的 MySQL 就起不来。原因不在代码,在 MySQL 8 换了默认的密码认证方式。
现象
本地用 SQLite 一切正常,把 .env 里的 DATABASE_URL 换成服务器上的 MySQL 之后,启动直接崩:
RuntimeError: 'cryptography' package is required for sha256_password
or caching_sha2_password auth methods
原因
MySQL 8.0 把默认的密码认证插件从 mysql_native_password 换成了 caching_sha2_password。
新的认证方式在传密码时要做 RSA 加密,而 PyMySQL 自己不带加密实现,它依赖 Python 的 cryptography 库。没装这个库,PyMySQL 就没法完成认证握手,于是直接抛异常。
所以这个报错的真实含义是:「我看得懂服务器要求的认证方式,但我缺少完成它所需要的工具。」
解决
装上就行:
pip install cryptography
然后把它写进 requirements.txt,否则换台机器部署又会踩一遍:
PyMySQL==1.1.1
cryptography==44.0.0 # PyMySQL 连 MySQL 8 的 caching_sha2_password 需要
装完重启服务:
systemctl restart blog
journalctl -u blog -n 30
另一条路(不推荐)
网上很多答案会让你把用户的认证方式改回旧的:
ALTER USER 'bloguser'@'localhost'
IDENTIFIED WITH mysql_native_password BY '你的密码';
这样确实也能连上,但是在降级安全性。caching_sha2_password 比 mysql_native_password 更安全,而且后者在 MySQL 8.4 里已经被默认禁用了。
装一个库 vs 降低数据库安全等级,选前者。
顺手学到的
pip install装上了不等于解决了——没写进requirements.txt的依赖,等于没装,下次换环境照样炸- 报错信息里的
caching_sha2_password是个可以直接拿去搜的关键词。看到不认识的名词先搜它,而不是搜整句报错 - 「本地能跑,服务器不能跑」,九成是环境差异:Python 版本、依赖版本、数据库版本、系统差异
排查清单
下次再遇到「本地好好的,服务器就报错」,按这个顺序查:
python3 --version # Python 版本一样吗
pip list | grep -i pymysql # 依赖装了吗、版本一样吗
mysql --version # 数据库版本一样吗
journalctl -u blog -n 50 # 完整报错是什么