Python存储多条SQL查询结果 解决fetchall仅返回最后执行结果问题
代码错误点
- 存在多处拼写/语法错误:列表取值用了函数调用语法
query_list(i),正确写法是方括号索引query_list[i];游标变量名前后不一致,先定义cusror1,后续调用cursor1甚至未定义的cursor,根本没有正确获取当前循环的查询结果。 - 游标读取逻辑错误:数据库游标是单向迭代的,单次执行后调用
fetchall()会把所有结果拉取到本地,再次调用只会返回空值。你在循环里先调用一次cursor.fetchall()赋值给result,后续又调用cursor1.fetchall()做append,第二次读取时游标已经为空,拿不到任何数据。 - 变量类型覆盖错误:初始化
result_df为DataFrame类型,第一次循环直接将其赋值为fetchall()返回的元组列表,后续的append操作是针对列表而非DataFrame,且每次循环都重新给result_df赋值,没有做结果累积。 - 效率问题:循环内反复执行文件写入,IO开销大,且
DataFrame.append()方法已在新版Pandas中弃用,不建议使用。
正确实现方案
方案一:所有查询返回列结构一致,合并为单个DataFrame
直接用pd.read_sql()规避手动处理游标的各类问题,代码最简洁,出错概率最低:
import pandas as pd # 读取待执行SQL列表,自动过滤空值避免执行报错 query_df = pd.read_csv('input_query.csv') query_list = query_df['DB_QUERY'].dropna().tolist() result_container = [] for query_id, sql in enumerate(query_list): try: # 直接读取查询结果为DataFrame,自动处理游标、字段名映射 single_result = pd.read_sql(sql, conn) # 可选:新增字段标记查询ID,方便后续溯源结果对应哪条SQL single_result['source_query_id'] = query_id result_container.append(single_result) print(f"第{query_id+1}条SQL执行完成,返回{len(single_result)}行数据") except Exception as e: print(f"第{query_id+1}条SQL执行失败,错误信息:{str(e)},对应SQL:{sql[:100]}...") continue # 一次性合并所有结果,统一写入文件 final_result = pd.concat(result_container, ignore_index=True) final_result.to_csv('query_result.csv', index=False, encoding='utf-8-sig')
方案二:不同查询返回列结构不一致,存储为结果列表
如果各SELECT语句返回的字段、表结构不统一,不要强行合并为单个DataFrame,用列表存储每个查询的独立结果即可:
import pandas as pd query_df = pd.read_csv('input_query.csv') query_list = query_df['DB_QUERY'].dropna().tolist() # 每个元素为字典,存储对应SQL的元信息和查询结果 result_list = [] for query_id, sql in enumerate(query_list): try: single_result = pd.read_sql(sql, conn) result_list.append({ "query_id": query_id, "sql_content": sql, "data": single_result }) except Exception as e: print(f"第{query_id+1}条SQL执行失败:{str(e)}") continue # 调用示例:取第1条SQL的查询结果 # print(result_list[0]['data'])
原生游标实现参考
如果需要用原生cursor实现(比如特殊驱动不支持pandas直接读),注意统一变量名、单次读取游标、最后统一转换DataFrame:
import pandas as pd query = pd.read_csv('input_query.csv') query_list = query['DB_QUERY'].tolist() all_data = [] col_names = None for i in range(len(query_list)): sql = query_list[i] cursor = conn.cursor() cursor.execute(sql) # 仅调用一次fetchall获取全部结果 res = cursor.fetchall() # 首次执行时提取字段名 if col_names is None: col_names = [item[0] for item in cursor.description] all_data.extend(res) cursor.close() # 循环结束后统一转为DataFrame并写入文件 result_df = pd.DataFrame(all_data, columns=col_names) result_df.to_csv('query_result.csv', index=False, encoding='utf-8-sig')
内容的提问来源于stack exchange,提问作者Sakshi Soni
相关产品推荐
相关产品推荐

