使用pyodbc和pandas读取SQL视图全量数据报错,求导出Excel方法
解决SQL多列查询转DataFrame的ValueError问题
问题说明
- 已通过Python+pyodbc连接SQL Server数据库,单列SELECT查询可正常返回数据
- 使用
SELECT *或多列查询时,转换为pandas DataFrame触发如下错误:ValueError: Shape of passed values is (128, 1), indices imply (128, 14)
- 目标:将SQL视图全量数据导出至Excel
问题原因
cursor.fetchall()返回的是元组的列表,每个元组对应一行数据。直接将该列表传入pd.DataFrame()时,元组未被正确展开,被识别为单元素列,导致列数(1列)与手动获取的列名数量(14列)不匹配,触发Shape错误。
另外注意:原SQL语句中[vewName}的右大括号是语法错误,需改为方括号]。
解决方案
方案1:修复现有代码
手动将每个元组转换为列表,确保每行数据被正确识别为多列:
import pyodbc import pandas as pd # 建立数据库连接 cnxn = pyodbc.connect(r'DRIVER={SQL Server};SERVER=serverName;DATABASE=myData;Trusted_Connection=yes;') cursor = cnxn.cursor() # 修正SQL语法错误(将}改为]) script = """ SELECT * FROM [dbName].[schema].[vewName] """ cursor.execute(script) # 获取列名 columns = [desc[0] for desc in cursor.description] # 获取数据并转换为列表的列表 data = cursor.fetchall() df = pd.DataFrame([list(row) for row in data], columns=columns) # 打印数据 print(df) # 导出至Excel(关闭索引列输出) df.to_excel(r'C:\Users\nnolting\py.xlsx', sheet_name='bar', index=False)
方案2:使用pandas内置的read_sql(推荐)
无需手动处理cursor,pandas会自动处理数据结构和列名,代码更简洁:
import pyodbc import pandas as pd # 建立数据库连接 cnxn = pyodbc.connect(r'DRIVER={SQL Server};SERVER=serverName;DATABASE=myData;Trusted_Connection=yes;') # 修正SQL语法错误 script = """ SELECT * FROM [dbName].[schema].[vewName] """ # 直接读取SQL结果为DataFrame df = pd.read_sql(script, cnxn) # 打印数据 print(df) # 导出至Excel df.to_excel(r'C:\Users\nnolting\py.xlsx', sheet_name='bar', index=False)
内容的提问来源于stack exchange,提问作者natureNate
相关产品推荐
相关产品推荐

