将SQL查询导入Pandas只会导致1列

时间:2018-04-09 18:10:19

标签: python sql pandas pyodbc

我正在尝试将复杂SQL查询的结果导入到pandas数据帧中。我的查询要求我创建几个临时表,因为我想要的最终结果表包含一些聚合。 我的代码如下所示:

    cnxn = pyodbc.connect(r'DRIVER=foo;SERVER=bar;etc')
    cursor = cnxn.cursor()
    cursor.execute('SQL QUERY HERE')
    cursor.execute('SECONDARY SQL QUERY HERE')
    ...
    df = pd.DataFrame(cursor.fetchall(),columns = [desc[0] for desc in cursor.description])

我收到错误,告诉我形状不匹配:

    ValueError: Shape of passed values is (1,900000),indices imply (5,900000)

事实上,所有SQL查询的结果应该是一个包含5列而不是1的表。我使用Microsoft SQL Server Management Studio运行SQL查询,它可以正常工作并返回我想要的5列表。我试图不将任何列名称传递到数据框中并打印出数据框的头部,并发现pandas已将5列中的所有信息都放入1.每行中的值是由逗号分隔的5个值的列表,但是pandas将整个列表视为1列。为什么熊猫这样做?我也尝试过pd.read_sql路线,但我仍然得到同样的错误。

编辑:

我已经做了一些调试,将评论考虑在内。这个问题似乎并非源于我的查询是嵌套的。我尝试了一个简单的(一行)查询来返回一个3列表,我仍然得到相同的错误。打印出fetchall()如下所示:

    [(str1,str2,str3,datetime.date(stuff),datetime.date(stuff)), 
    (str1,str2,str3,datetime.date(stuff),datetime.date(stuff)),...]  

2 个答案:

答案 0 :(得分:4)

改为使用pd.DataFrame.from_records

df = pd.DataFrame.from_records(cursor.fetchall(),
                               columns = [desc[0] for desc in cursor.description])

答案 1 :(得分:1)

现在只需调整pd.DataFrame()调用cursor.fetchall()即可返回一个长度的元组列表。使用tuple()list将子元素映射到自己的列中:

df = pd.DataFrame([tuple(row) for row in cur.fetchall()],
                  columns = [desc[0] for desc in cursor.description])