在django中使用dict_cursor

Dav*_*542 18 python django

要在django中获取光标我做:

from django.db import connection
cursor = connection.cursor()
Run Code Online (Sandbox Code Playgroud)

我如何在django中获得一个dict游标,相当于 -

import MySQLdb
connection = (establish connection)
dict_cursor = connection.cursor(MySQLdb.cursors.DictCursor)
Run Code Online (Sandbox Code Playgroud)

在django有办法做到这一点吗?当我尝试时,cursor = connection.cursor(MySQLdb.cursors.DictCursor)我得到了一个Exception Value: cursor() takes exactly 1 argument (2 given).或者我需要直接连接python-mysql驱动程序?

django文档建议使用dictfetchall:

def dictfetchall(cursor):
    "Returns all rows from a cursor as a dict"
    desc = cursor.description
    return [
        dict(zip([col[0] for col in desc], row))
        for row in cursor.fetchall()
    ]
Run Code Online (Sandbox Code Playgroud)

使用它和创建dict_cursor有性能差异吗?

Aam*_*nan 31

DictCursordjango 没有这样的支持.但是你可以为你编写一个小函数,请参阅docs:直接执行自定义SQL:

def dictfetchall(cursor): 
    "Returns all rows from a cursor as a dict" 
    desc = cursor.description 
    return [
            dict(zip([col[0] for col in desc], row)) 
            for row in cursor.fetchall() 
    ]

>>> cursor.execute("SELECT id, parent_id from test LIMIT 2");
>>> dictfetchall(cursor)
[{'parent_id': None, 'id': 54360982L}, {'parent_id': None, 'id': 54360880L}] 
Run Code Online (Sandbox Code Playgroud)

  • 我想这个答案对很多来到这里的人都有帮助。但是,如果您阅读原始问题,则答案不匹配:使用 dictfetchall() 和创建 dict_cursor 之间是否存在性能差异? (3认同)

ker*_*ert 7

至少可以轻松地用Postgres完成,我确定mysql具有类似的功能(Django 1.11)

from django.db import connections
from psycopg2.extras import NamedTupleCursor


def scan_tables(app):
    conn = connections['default']
    conn.ensure_connection()
    with conn.connection.cursor(cursor_factory=NamedTupleCursor) as cursor:
        cursor.execute("SELECT table_name, column_name "
                       "FROM information_schema.columns AS c "
                       "WHERE table_name LIKE '{}_%'".format(app))
        columns = cursor.fetchall()
        for column in columns:
            print(column.table_name, column.column_name)


scan_tables('django')
Run Code Online (Sandbox Code Playgroud)

显然可以随意使用DictCursor,RealDictCursor,LoggingCursor等

  • 给我 TypeError:cursor() 在 Django 2.x 中得到了意外的关键字参数 'cursor_factory' 。 (2认同)

San*_*eep 5

以下代码将结果集转换为字典。

from django.db import connections
cursor = connections['default'].cursor()

columns = (x.name for x in cursor.description)
result = cursor.fetchone()
result = dict(zip(columns, result))
Run Code Online (Sandbox Code Playgroud)

如果结果集有多行,则改为迭代游标。

columns = [x.name for x in cursor.description]
for row in cursor:
    row = dict(zip(columns, row))
Run Code Online (Sandbox Code Playgroud)

  • 只是一个有趣的旁注。表达式 (x.name for x incursor.description) 生成生成器而不是列表对象。在“for row incursor”循环的第一次迭代之后,这样的生成器将被耗尽。为了使此代码示例适用于多行,我们需要通过将圆括号更改为方括号来预取列:[x.name for x incursor.description] (5认同)