You need to enable JavaScript to run this app. 树莓派Python智能锁复用MySQL游标报Unread result found怎么办
优惠活动
大模型
产品
解决方案
定价
更多

树莓派Python智能锁复用MySQL游标报Unread result found怎么办

问题原因与修复方案

报错触发逻辑

Unread result found是mysql-connector-Python的内置校验规则:同一个数据库游标在上一次执行SELECT查询后,如果没有把结果集全部消费读取完,就直接执行下一次SQL语句,连接器就会抛出该错误。
触发该错误的具体代码问题有两点:

  • 匹配到用户的分支中,执行了cursor.execute("Select secret From users Where rfid_uid="+str(id)),但完全没有对这次查询的结果做任何fetch读取操作,这次查询的返回结果会一直残留在游标的未读缓冲区里,等下一次循环用同一个游标执行新的SELECT语句时,就会触发报错。
  • 这行二次查询本身完全冗余:第一次执行Select id, name, secret From users Where rfid_uid=...时,已经把secret字段从数据库取出存在result[2]变量里,根本不需要再单独查询一次secret。

具体修复步骤

  1. 删除冗余的二次查询代码
    直接删除cursor.execute("Select secret From users Where rfid_uid="+str(id))这一行,保留secret = result[2]的赋值逻辑即可,从根源上消除残留未读结果的触发源。
  2. 给游标加状态兜底,避免后续出现同类问题
    两种方式二选一即可:
    • 方式一:初始化游标时开启缓冲模式,将原来创建游标的代码cursor = conn.cursor()修改为cursor = conn.cursor(buffered=True)。该参数会让mysql-connector自动缓存查询的全部结果,执行下一次查询前自动清空上次的未读结果,不会再触发未读结果报错。
    • 方式二:每一次查询取完需要的结果后,主动调用cursor.fetchall()把剩余的未读结果全部读出,将游标重置为可执行下一次查询的状态。
  3. 修复代码中的潜在隐患
    • 现有SQL通过字符串拼接传入RFID UID,存在SQL注入风险,需要改成参数化查询,将原来的拼接SQL:
      cursor.execute("Select id, name, secret From users Where rfid_uid="+str(id))
      修改为参数化写法:
      cursor.execute("Select id, name, secret From users Where rfid_uid=%s", (str(id),))
    • 原有通过cursor.rowcount >=1判断是否匹配到用户的逻辑,在调用fetchone()后判断结果并不可靠,直接判断result变量是否为None即可:如果返回结果为None,说明数据库中没有匹配的RFID UID;否则就走正常的用户匹配流程。

修复后的核心循环参考代码

while True:
    print("Place card near the scanner")
    mylcd.lcd_display_string("Place card near",1)
    mylcd.lcd_display_string("the scanner",2)
    id, text = reader.read()
    # 参数化查询
    cursor.execute("Select id, name, secret From users Where rfid_uid=%s", (str(id),))
    result = cursor.fetchone()
    # 主动清空游标未读结果,避免状态卡住
    cursor.fetchall()

    if result:
        _, user_name, secret = result
        mylcd.lcd_clear()
        print("Welcome, ", user_name)
        mylcd.lcd_display_string("Welcome",1)
        mylcd.lcd_display_string(user_name,2)
        time.sleep(2)
        mylcd.lcd_clear()
        print("Type the code from your authenticator")
        mylcd.lcd_display_string("Type in the code",1)

        totp = pyotp.TOTP(str(secret))
        otp = totp.now()
        your_code = input('')
        mylcd.lcd_display_string(your_code,2)

        if your_code == otp:
            mylcd.lcd_clear()
            print("Code Valid, Opening the door")
            mylcd.lcd_display_string("Code Valid",1)
            mylcd.lcd_display_string("Opening the door",2)
            time.sleep(5)
        else:
            mylcd.lcd_display_string("Invalid Code",1)
            print("Invalid")

        time.sleep(5)
        mylcd.lcd_clear()

内容的提问来源于stack exchange,提问作者Al-

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.10 21:24:04