You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python从MySQL取密码返回None的原因分析及解决方法

问题原因分析及解决办法

我来帮你拆解下代码里的问题,这两个关键点导致你拿到的DbPassword是None,还会引发后续的密码比对失败:

1. 参数传递错误,导致查询匹配不到任何用户

你执行SQL的代码是这样的:

cur.execute(sql,(User))

这里的坑在于:单个元素的元组必须在末尾加逗号,不然(User)只是把变量加了个括号,不是元组。MySQL连接器会把字符串User当成序列来遍历,把每个字符拆成单独的参数传给SQL,最终执行的SQL会变成类似:

SELECT password FROM users WHERE user_name = 'H' 'e' 'm' 'a' 'n' 't'

这种条件根本找不到对应的用户,所以cur.fetchone()自然返回None。

2. 密码比对的逻辑错误

就算运气好查到了结果,fetchone()返回的是一个元组(比如密码是qwerty的话,返回('qwerty',)),你直接转成字符串会得到"('qwerty',)",和用户输入的纯密码字符串肯定不相等,这也会导致登录验证失败。


修复后的完整代码

下面是修正后的searchdb函数,我还加了一些边界情况的处理:

def searchdb(self):
    User = self.Username.get()
    pas = self.Password.get()
    myconn = mysql.connector.connect(host="localhost", user="root", passwd="qwerty321", database="admin")
    if len(User) == 0 and len(pas) == 0 :
        tkinter.messagebox.showinfo("Pharmacy Management System","Please fill in the Login Details")
    elif len(User) == 0 and len(pas) != 0 :
        tkinter.messagebox.showinfo("Pharmacy Management System","Please Enter a Username")
    elif len(User) != 0 and len(pas) == 0:
        tkinter.messagebox.showinfo("Pharmacy Management System","Please enter a Password")
    else:
        try:
            # 注意:这里的%s不需要加引号,连接器会自动处理
            sql = "SELECT password FROM users WHERE user_name = %s"
            cur = myconn.cursor()
            # 单元素元组必须加逗号,确保参数正确传递
            cur.execute(sql, (User,))  
            DbPassword = cur.fetchone()
            
            # 先判断是否查到用户
            if DbPassword is not None:
                # 取出元组里的第一个元素,也就是数据库中存储的密码
                db_stored_pwd = DbPassword[0]
                print(db_stored_pwd)
                if pas == db_stored_pwd :
                    self.btnRegistration.config(state=NORMAL)
                    self.btnHospital.config(state=NORMAL)
                else:
                    tkinter.messagebox.askokcancel("Pharmacy Management System","You have entered an invalid login details")
                    self.btnRegistration.config(state=DISABLED)
                    self.btnHospital.config(state=DISABLED)
                    self.Username.set("")
                    self.Password.set("")
                    self.txtUsername.focus()
            else:
                # 没有查到对应用户的情况
                tkinter.messagebox.askokcancel("Pharmacy Management System","No user found with this username")
                self.Username.set("")
                self.Password.set("")
                self.txtUsername.focus()
        except Error as e:
            print(f"数据库错误信息: {e}")
            myconn.rollback()
            Window1.Reset(self)
        finally:
            # 无论成功还是失败,都要关闭数据库连接,避免资源浪费
            myconn.close()

额外的几个小建议

  • 绝对不要用字符串拼接的方式写SQL(比如你原来的sql = "SELECT password FROM users WHERE user_name = '%s'"),这会有SQL注入的风险,用参数化查询才是安全的做法。
  • 数据库连接一定要记得关闭,用finally块能保证无论代码是否报错,连接都会被关闭。
  • 处理查询结果时,先判断fetchone()是否为None,不然直接取元素会抛出TypeError异常。

内容的提问来源于stack exchange,提问作者Hemant kumar Pandit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 00:17:47