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

cursor.fetchone()返回NoneType但有有效值,如何正确收集结果到列表?

问题:查询用户指定列数据时抛出NoneType下标异常

原代码尝试根据用户名查询指定列并收集结果到列表:

def get_user_data(username: str, columns: list):
    result = []
    for column in columns:
        query = f"SELECT {column} FROM ta_users WHERE username = '{username}'"
        cursor.execute(query)
        print('cursor.fetchone() from loop = ', cursor.fetchone(),
              'type= ', type(cursor.fetchone()))  # debug
        fetchone = cursor.fetchone()
        result.append(fetchone[0])

运行时抛出异常:

result.append(fetchone[0]) 

TypeError: 'NoneType' object is not subscriptable

调试打印结果:

cursor.fetchone() from loop = ('6005441021308034',) type= <class 'NoneType'>


问题原因

  1. 重复调用fetchone()消耗结果集:调试代码里连续两次调用cursor.fetchone(),第一次调用已经取走了唯一的结果,第二次调用返回None;后续赋值给fetchone的是无效结果,自然无法通过下标访问。
  2. 未处理空结果场景:当查询不到匹配数据时,fetchone()会返回None,直接访问下标必然触发异常。
  3. 存在SQL注入风险:用f-string拼接SQL语句,若用户名包含单引号等特殊字符,会破坏SQL结构,引发注入攻击。
  4. 查询效率低下:循环查询每一列会产生多次数据库交互,性能损耗大。

修复与优化方案

方案1:修复原逻辑(仅解决异常,仍存注入风险)

保留循环查询逻辑,修正None处理问题:

def get_user_data(username: str, columns: list):
    result = []
    for column in columns:
        query = f"SELECT {column} FROM ta_users WHERE username = '{username}'"
        cursor.execute(query)
        # 仅调用一次fetchone并保存结果
        fetchone = cursor.fetchone()
        print('cursor.fetchone() = ', fetchone, 'type= ', type(fetchone))
        # 先判断结果是否为空,再处理
        if fetchone is not None:
            result.append(fetchone[0])
        else:
            # 无数据时添加默认值,可根据需求改为空字符串等
            result.append(None)
    return result

方案2:推荐优化写法(解决注入+提升效率)

一次性查询所有指定列,使用参数化查询避免注入:

def get_user_data(username: str, columns: list):
    # 将列名拼接为字符串,需确保columns是可信输入(避免非法列名)
    columns_str = ", ".join(columns)
    # 用参数化占位符(%s适配MySQL,SQLite用?,需根据数据库类型调整)
    query = f"SELECT {columns_str} FROM ta_users WHERE username = %s"
    # 传入参数元组,彻底避免SQL注入
    cursor.execute(query, (username,))
    # 获取单条结果(假设用户名是唯一标识)
    row = cursor.fetchone()
    
    if row is not None:
        # 将查询结果行转为列表,顺序与columns参数一致
        return list(row)
    else:
        # 无匹配用户时,返回对应长度的默认值列表
        return [None] * len(columns)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 03:55:30