输出pyodbc游标结果为python字典

Foo*_*ack 56 python dictionary cursor pyodbc pypyodbc

如何序列pyodbc光标输出(从.fetchone,.fetchmany.fetchall)Python字典?

我正在使用bottlepy并需要返回dict,因此它可以将其作为JSON返回.

Bry*_*yan 113

如果您不提前知道列,请使用cursor.description构建列名列表并使用每行压缩以生成字典列表.示例假定建立了连接和查询:

>>> cursor = connection.cursor().execute(sql)
>>> columns = [column[0] for column in cursor.description]
>>> print(columns)
['name', 'create_date']
>>> results = []
>>> for row in cursor.fetchall():
...     results.append(dict(zip(columns, row)))
...
>>> print(results)
[{'create_date': datetime.datetime(2003, 4, 8, 9, 13, 36, 390000), 'name': u'master'},   
 {'create_date': datetime.datetime(2013, 1, 30, 12, 31, 40, 340000), 'name': u'tempdb'},
 {'create_date': datetime.datetime(2003, 4, 8, 9, 13, 36, 390000), 'name': u'model'},     
 {'create_date': datetime.datetime(2010, 4, 2, 17, 35, 8, 970000), 'name': u'msdb'}]
Run Code Online (Sandbox Code Playgroud)

  • 不知道`cursor.description`。这只是为我节省了大量时间。 (4认同)
  • @LJT仅在python3中...但是由于print()函数在python2中有效,因此使用它是一个好习惯。 (2认同)

Kev*_*ell 9

对于游标不可用的情况 - 例如,当某些函数调用或内部方法返回行时,您仍然可以使用 row.cursor_description 创建字典表示

def row_to_dict(row):
    return dict(zip([t[0] for t in row.cursor_description], row))
Run Code Online (Sandbox Code Playgroud)


Foo*_*ack 7

使用@ Beargle的结果和bottlepy,我能够创建这个非常简洁的查询暴露端点:

@route('/api/query/<query_str>')
def query(query_str):
    cursor.execute(query_str)
    return {'results':
            [dict(zip([column[0] for column in cursor.description], row))
             for row in cursor.fetchall()]}
Run Code Online (Sandbox Code Playgroud)

  • 这会遭受SQL注入攻击吗? (2认同)

Tom*_*and 5

这是您可能可以使用的简短版本

>>> cursor.select("<your SQL here>")
>>> single_row = dict(zip(zip(*cursor.description)[0], cursor.fetchone()))
>>> multiple_rows = [dict(zip(zip(*cursor.description)[0], row)) for row in cursor.fetchall()]
Run Code Online (Sandbox Code Playgroud)

您可能会知道,当在列表中添加*时,您基本上会删除列表,而将各个列表条目保留为所调用函数的参数。通过使用zip拉链,我们选择了第1到n项,并将它们拉链在一起,就像裤子中的拉链一样。

所以用

zip(*[(a,1,2),(b,1,2)])
# interpreted by python as zip((a,1,2),(b,1,2))
Run Code Online (Sandbox Code Playgroud)

你得到

[('a', 'b'), (1, 1), (2, 2)]
Run Code Online (Sandbox Code Playgroud)

由于description是带有元组的元组,其中每个元组都描述了每一列的标题和数据类型,因此您可以使用以下命令提取每个元组的第一个

>>> columns = zip(*cursor.description)[0]
Run Code Online (Sandbox Code Playgroud)

相当于

>>> columns = [column[0] for column in cursor.description]
Run Code Online (Sandbox Code Playgroud)