使用pyodbc的cursor.execute执行SQL后无法将结果转为DataFrame怎么办
报错原因
cursor.fetchall() 返回的是pyodbc专属的Row对象序列,不是原生Python元组,部分版本的pandas解析这类对象时会将每个Row整体识别为单个值,导致传入的数据被判定为47行1列,和你指定的3个列名维度不匹配,因此抛出形状错误。
解决方案
方法1:手动转换Row为原生元组
创建DataFrame前先将每个Row对象转为原生元组,适配pandas的解析规则:
# 原有代码不变,仅修改创建DataFrame的行 df = pd.DataFrame([tuple(row) for row in rows], columns=names)
方法2:直接使用pandas.read_sql传递参数(更推荐)
read_sql本身支持传入参数列表,不需要手动调用cursor执行,既简化代码也不会出现格式兼容问题:
import pyodbc import pandas as pd conn = pyodbc.connect("DSN=dsn") conn.setdecoding(pyodbc.SQL_CHAR, encoding='utf-8') conn.setencoding(encoding="utf-8") list_id = ["A1","A2","A3"] placeholders = ",".join("?" * len(list_id)) sql = "select * from table Where ID in (%s)" % placeholders # 直接传入参数列表给params参数即可 df = pd.read_sql(sql, conn, params=list_id) conn.close() df
方法3:使用from_records方法加载结构化数据
pandas的from_records方法专门适配数据库返回的结构化记录,对pyodbc的Row对象兼容性更好:
df = pd.DataFrame.from_records(rows, columns=names)
内容的提问来源于stack exchange,提问作者ponderwonder
相关产品推荐
相关产品推荐

