Python中如何不通过循环获取cursor.fetchall()结果的next()迭代值
无循环获取查询结果迭代值的实现方案
原有代码运行异常的核心原因
- 调用
rows.next()失败的两个直接原因:cursor.fetchall()返回的是普通Python列表,不是迭代器,本身不存在绑定的.next()类方法- Python3 已经完全废弃了Python2中迭代器对象自带
.next()方法的写法,统一改为将迭代对象传入内置next()函数来获取下一个值
cursor.rowcount返回-1 是数据库驱动的正常合规行为:按照Python DB-API 2.0的规范,如果驱动在结果集完全拉取前无法提前计算SELECT语句的返回行数,就会返回-1,这和Python3的兼容性没有关系,你原本认为rowcount失效才改用fetchall的判断是不成立的。
可直接落地的实现方式
场景1:已经通过fetchall拿到了全部行结果
如果已经执行rows = cursor.fetchall()获取到长度为11的列表,需要无循环取下一行的值:
- 不需要靠循环遍历,先把列表转成真正的迭代器,再用内置
next()取值即可:cursor.execute(query) rows = cursor.fetchall() # 将普通列表转换为迭代器 row_iterator = iter(rows) # 直接取第一行,无循环 first_row = next(row_iterator) # 直接访问对应列的值 print(first_row[1]) # 后续需要取第二行、第三行,继续调用next(row_iterator)即可 second_row = next(row_iterator)
场景2:不想一次性拉取所有行到内存(不使用fetchall)
如果你的需求是逐行从结果集流里取值,不需要一次性把所有行加载到内存,根本不需要依赖cursor.rowcount的返回值:
- 游标本身就是符合迭代协议的对象,直接转成迭代器后用
next()取值即可,甚至比你原本打算用的fetchone()更灵活:cursor.execute(query) row_iterator = iter(cursor) try: # 直接取第一行 first_row = next(row_iterator) print(first_row[1]) except StopIteration: # 处理查询无返回结果的边界情况 print("当前查询未返回任何数据") - 补充说明:你原本计划使用的
cursor.fetchone()在Python3中是完全正常可用的,它的执行逻辑不依赖cursor.rowcount的返回值,在cursor.execute(query)之后直接调用就能获取第一行结果,哪怕此时rowcount返回-1也不受影响。
内容的提问来源于stack exchange,提问作者anjanesh
相关产品推荐
相关产品推荐

