Estoy tratando de optimizar las llamadas a la base de datos provenientes de una aplicación Django bastante pequeña. Actualmente tengo un par de modelos, Inquiry y InquiryStatus. Al seleccionar todos los registros de MySQL, obtengo una buena declaración JOIN en las dos tablas, seguida de muchas solicitudes a la tabla InquiryStatus. ¿Por qué Django sigue haciendo solicitudes individuales si ya hice un select_related()?

Las modelos se ven así:

class InquiryStatus(models.Model):
    status = models.CharField(max_length=25) 
    status_short = models.CharField(max_length=5)
    class Meta:
        ordering = ["-default_status", "status", "status_short"]

class Inquiry(models.Model):
    ts = models.DateTimeField(auto_now_add=True)
    type = models.CharField(max_length=50) 
    status = models.ForeignKey(InquiryStatus)
    class Meta:
        ordering = ["-ts"]

La vista que reuní para depurar se ve así:

def inquiries_list(request, template_name="inquiries/list_inquiries.js"):
    ## Notice the "print" on the following line.  Forces evaluation.
    print models.Inquiry.objects.select_related('status').all()
    return HttpResponse("CRAPSTICKS")

He intentado usar select_related(depth=1), sin cambios. Cada una de las solicitudes extrañas a la base de datos está seleccionando un id específico en la cláusula WHERE.

Actualizar:

Así que hubo un código muy importante que debería haberse incluido con los modelos:

from fullhistory import register_model
register_model(Inquiry)
register_model(InquiryStatus)

Como resultado, fullhistory estaba (por razones que no puedo entender) sacando cada resultado individual y analizándolo.

1
Jack M. 28 ago. 2009 a las 02:10

3 respuestas

La mejor respuesta

Parece que fullhistory termina serializando el objeto, que evalúa cada campo en la instancia para dar Es una base para comparar.

Eche un vistazo a la función get_all_data:

http://code.google.com/p/fullhistory/source/browse/trunk/fullhistory/fullhistory.py

Si alguien quiere escribir una razón detallada de por qué sucede esto, con gusto marcaré esa respuesta como correcta.

0
Jack M. 28 ago. 2009 a las 14:43

El código que ha mostrado en realidad no debería generar ninguna consulta: los conjuntos de consultas solo se evalúan cuando es necesario, no cuando están definidos, y no utiliza el valor en ningún lugar, por lo que la ejecución no se realizará.

Muéstrenos una plantilla o algún otro código que realmente evalúe los qs: los corta, itera, imprime o lo que sea.

0
Daniel Roseman 28 ago. 2009 a las 06:36

Creo que esto tiene que ver con una evaluación perezosa. Django solo llega a la base de datos si es necesario y cuando es necesario, no cuando invocas modelos.Inquiry.objects.select_related ('status'). All ()

http://docs.djangoproject.com/en/dev/topics/db/queries/#id3

0
Gabriel Ross 28 ago. 2009 a las 00:20