如何将SQL查询结果转换为Python字典

22

我在将查询结果转换为Python字典时遇到了困难。每个字典都应代表一个学生,键是列名,值是查询结果中相应的值。目前为止,这是我想出来的:

def all_students():
    qu= 'select * from students'
    crs.execute(qu)
    for row in crs:
        student= {"StudentNum":row[0], "StudentLastName":row[2], "StudentFirst Name":row[3}
    return student
但是当我打印它时,它返回不正确的信息,而且一切都混乱了,它只显示一条记录:

但是当我打印它时,它返回不正确的信息,而且一切都混乱了,它只显示一条记录:

{'StudentLastName': Jane, StudentNum: 'Smith  ', StudentFirst Name: '1612'}
9个回答

28
你可以使用cursor.description来获取列名,并将列名与每个返回的行进行"压缩",从而产生一个字典列表作为结果。
desc = cursor.description
column_names = [col[0] for col in desc]
data = [dict(zip(column_names, row))  
        for row in cursor.fetchall()]

注意:在Python2中,使用itertools.izip代替zip()

3
对于最后一行,您可以使用for row in cursor代替cursor.fetchall()并获得相同的结果。 - Max Heiber
4
似乎itertools.izip在Python 3中不可用,但是普通的zip函数仍然可以使用。 - BanzaiTokyo
模块 'itertools' 没有 'zip' 成员。 - Ri1a
1
@RickLan 确定,已添加Python3的注释。 - alecxe
我使用的代码如下:desc = cur.description cols = [col[0] for col in desc] data = [dict(itertools.zip(cols, row)) for row in cur.fetchall()]但是我仍然收到以下错误:AttributeError: module 'itertools' has no attribute 'zip'我想这就是Ri1a试图指出的问题。 - techele
显示剩余3条评论

11

是的,但那是“慢慢来 - 全部的Python”连接器。 - undefined

5

4

我希望这能有所帮助...

def all_students():
    qu= "select * from students"
    students = crs.execute(qu)
    students_data = []
    for row in students:
        student= {"StudentNum":row[0], "StudentLastName":row[2], "StudentFirst Name":row[3}
         students_data.append(student)

    final_data["students_info"] = students_data
    return final_data

1
为了回答原问题,您可以尝试以下方法(无需遍历crs,只要给定表内容适合内存,就可以直接使用crs.fetchall()): result_list_of_dict = [{'StudentNum': col1, 'StudentLastName': col2, 'StudentFirst Name': col3} for (col1, col2, col3) in crs.fetchall()] 结果的result_list_of_dict是一个字典列表,每个元素(字典)将具有您指定的3个键(“StudentNum”,“StudentLastName”和“StudentFirstName”),并提取自SQL表的相关值。 扩展: 基本上,cursor.fetchall()返回一个元组列表,只要列出所有可能返回的值,您就可以随意修改前半部分。例如,以下代码可用于包含5列的表,您只想提取前3列的情况: result_dict = {col1:(col2, col3) for (col1, col2, col3, col4, col5) in cursor.fetchall()} 在这种情况下,生成的result_dict将是一个字典。

1
你能解释一下为什么这个可行吗?这段代码在做什么,它是如何回答这个问题的? - Jake Luby
1
我进行了更改,以使原始问题更具相关性。 - Lien Chu
只有这个答案返回一个字典;其他的返回多个字典列表! - ARZ

1

得票最高的答案是针对Python2的,这里是针对Python3的答案:

import itertools

desc = cursor.description
column_names = [col[0] for col in desc]
data = [dict(zip(column_names, row))  
        for row in cursor.fetchall()]

0
如果您期望查询返回单个结果,并且希望将所有值按其列名存储在字典中,则可以使用以下代码:

def querySingle(sql, args):
    try:
        cursor = cnx.cursor()
        cursor.execute(sql, args)
        for row in cursor:
            return dict((column[0],row[index]) for index, column in enumerate(cursor.description))
        return {}
    finally:
        cursor.close()

例如,querySingle("SELECT * FROM animals WHERE id=%s", [1]) 可能会返回:
{
    "id": 1,
    "name": "Bob",
    "type": "Alligator"
}

工作原理

cursor.description 返回一个包含所有列的数组,其中每个条目都是一个数组,其第一个值是列的名称。在此基础上使用 enumerate 可以得到每个列及其索引。然后只需要使用来自 column[0] 的名称和来自 row[index] 的数据创建字典即可。在 for 循环中返回可以确保仅处理第一行。


0
result = db_pool.execute(query, return_dict=True)

-2
如果您是来自哈佛大学的cs50课程,SELECT查询返回一个列表,其中每一行由Python dict表示,键对应列名,值来自表格。

您无需进行转换。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接