Подтвердить что ты не робот

Использование dict_cursor в django

Чтобы получить курсор в django, выполните следующие действия:

from django.db import connection
cursor = connection.cursor()

Как мне получить курсор dict в django, эквивалент -

import MySQLdb
connection = (establish connection)
dict_cursor = connection.cursor(MySQLdb.cursors.DictCursor)

Есть ли способ сделать это в 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()
    ]

Есть ли разница в производительности между этим и созданием dict_cursor?

4b9b3361

Ответ 1

Нет никакой поддержки для DictCursor в django. Но вы можете написать небольшую функцию для вас, посмотрите ticket:

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}] 

Ответ 2

Следующий код преобразует результирующий набор в словарь.

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))

Если в результирующем наборе есть несколько строк, вместо этого перебираем курсор.

columns = [x.name for x in cursor.description]
for row in cursor:
    row = dict(zip(columns, row))

Ответ 3

Легко сделать с 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')

Очевидно, не стесняйтесь использовать DictCursor, RealDictCursor, LoggingCursor и т.д.