2012-06-04 16 views
12

Para obtener un cursor en Django que hago:Usando dict_cursor en Django

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

¿Cómo puedo obtener un cursor dict en Django, el equivalente a -

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

¿Hay una manera de hacerlo esto en django? Cuando probé cursor = connection.cursor(MySQLdb.cursors.DictCursor) obtuve un Exception Value: cursor() takes exactly 1 argument (2 given). ¿O debo conectarme directamente con el controlador python-mysql?

Los documentos sugieren usar 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() 
    ] 

¿Existe una diferencia de rendimiento entre el uso de esto y crear un dict_cursor?

Respuesta

22

No existe tal soporte para DictCursor en django. Sin embargo, se puede escribir una pequeña función para eso para usted, vea este 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}] 
0

El siguiente código convierte el conjunto de resultados en un diccionario.

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

Si el conjunto de resultados tiene varias filas, iterar sobre el cursor en su lugar.

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

Sólo un lado interesante Nota. La expresión (x.name para x en cursor.description) produce un generador, no un objeto de lista. Tal generador se agotará después de la primera iteración del ciclo "para la fila en el cursor". Para que este ejemplo de código funcione en varias filas, debemos precargar las columnas cambiando los corchetes a corchetes: [x.name for x in cursor.description] –

1

hace fácilmente con Postgres al menos, estoy seguro de MySQL tiene similar (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') 

Obviamente no dude en utilizar DictCursor, RealDictCursor, etc LoggingCursor