问题现象

使用 Python 连接 MySQL 数据库时,明明密码输入正确,却一直报错:

mysql.connector.errors.ProgrammingError: 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

命令行登录却完全正常:

mysql -u root -p
Enter password: ****
Welcome to the MySQL monitor...

为什么同样的密码,命令行能进,Python 就不能?

原因分析

1. 查看 MySQL 用户的身份验证插件

在 MySQL 命令行中执行:

USE mysql;
SELECT User, Host, plugin FROM user WHERE User='root';

+------+-----------+-----------------------+
| User | Host      | plugin                |
+------+-----------+-----------------------+
| root | localhost | caching_sha2_password |
+------+-----------+-----------------------+

关键点:MySQL 8.0 默认将 root 用户的身份验证插件设置为 caching_sha2_password。这是一种更安全的加密方式。

2. Python 驱动默认使用的加密方式

  • 旧版本的 mysql-connector-python(如 8.0.20 之前)默认使用 mysql_native_password

  • PyMySQL 默认也是 mysql_native_password

  • 即使新版本驱动支持 caching_sha2_password,也可能因为连接参数或环境问题退回到旧方式。

当客户端使用 mysql_native_password 与服务端的 caching_sha2_password 进行认证时,服务端不认可,即使密码正确也直接拒绝,抛出 1045。

3. 为什么命令行能登录?

MySQL 命令行客户端(mysql.exe)默认支持新的认证协议,能够正确处理 caching_sha2_password。所以它能登录。

解决方案

修改 MySQL 用户的加密方式为 mysql_native_password

以 root 或其他管理员用户登录 MySQL,执行:

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码';
FLUSH PRIVILEGES;

然后再次尝试 Python 连接,问题解决。

优点:一劳永逸,不影响现有数据,所有旧驱动都能连。
缺点:安全性略低于 caching_sha2_password,但对于本地开发环境完全可以接受。

验证步骤

  1. 修改加密方式后,再次执行 SQL 查看 plugin:

  2. SELECT User, Host, plugin FROM user WHERE User='root';

    应显示为 mysql_native_password

  3. 运行 Python 测试脚本:

  4. import mysql.connector
    
    try:
        conn = mysql.connector.connect(
            host='localhost',
            user='root',
            password='your_new_password',
            database='mysql'
        )
        print("连接成功!")
        conn.close()
    except Exception as e:
        print(f"连接失败: {e}")

    输出 连接成功! 即代表问题解决。

希望这篇文章能帮到被加密方式折磨的你。如果还有问题,欢迎评论区交流!

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐