Python数据库cursor的fetchall()遗漏fetchone()读取行问题排查
问题原因
数据库游标是单向顺序遍历的设计,每次调用fetchone()/fetchall()等读取方法时,都会从当前游标所在位置向后取数据,读取完成后游标会自动移动到已读取数据的末尾,不会自动重置到结果集起始位置。
代码逻辑里先调用了一次fetchone()做存在性判断,这一步已经把结果集的第一行读取出来,游标直接移动到了第二行的起始位置;后续进入else分支调用fetchall()时,只会读取当前游标位置之后的所有剩余行,最开始被fetchone()取走的第一行自然不会出现在fetchall()的返回结果里,就出现了少一行数据的问题。
另外贴出的测试代码还存在基础语法错误:execute()方法内的SQL字符串没有闭合双引号,括号也不匹配,运行时会直接抛语法异常,需要一并修正。
修复方法
方案1:一次性读取全量结果再判断(推荐,适合结果集不大的场景)
直接先调用fetchall()拿到所有匹配行,再通过判断结果列表是否为空来决定输出内容,完全避免游标提前偏移的问题:
cursor = conn.cursor() # 修正SQL语法问题 cursor.execute("SELECT * from Documents where documentID like '1167%'") all_rows = cursor.fetchall() if not all_rows: print('Record is not there') else: print(all_rows)
方案2:保留逐行读取逻辑,合并提前读取的首行(适合超大结果集场景)
如果匹配结果量级很大,不想一次性把所有数据加载到内存,可以保留fetchone()的存在性判断,但要把第一次读到的首行和后续fetchall()拿到的剩余行合并为完整结果:
cursor = conn.cursor() cursor.execute("SELECT * from Documents where documentID like '1167%'") first_row = cursor.fetchone() if first_row is None: print('Record is not there') else: # 拼接首行和剩余行得到完整结果集 all_rows = [first_row] + cursor.fetchall() print(all_rows)
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

