2009-07-02 17 views

Respuesta

256

Consulte la documentación FAQ: "How can I see the raw SQL queries Django is running?"

django.db.connection.queries contiene una lista de las consultas SQL:

from django.db import connection 
print connection.queries 

QuerySets también tienen un query attribute que contiene la consulta para ser ejecutado:

print MyModel.objects.filter(name="my name").query 

Tenga en cuenta que el resultado de la consulta no es SQL válido, porque:

"Django nunca interpola los parámetros: envía la consulta y los parámetros por separado al adaptador de la base de datos, que realiza las operaciones apropiadas".

De Django error informe #17741.

Debido a eso, no debe enviar resultados de consultas directamente a una base de datos.

+10

Para una prueba futura de esta respuesta, más bien debe vincular la versión actual de la documentación de Django: http://docs.djangoproject.com/en/dev/faq/models/#how-can-i-see-the-raw- sql-queries-django-está-corriendo –

+18

¡o simplemente escribe la respuesta! Porque la gente me gusta en mi búsqueda de una solución ... – Jurudocs

+1

atributo de consulta? ¿Qué? ¿dónde está eso? He comprobado el enlace, pero es un gigante no alfabético (¿por qué alguien haría una lista que no es alfabético?) lista ... – bharal

16

Aunque puede hacerlo con el código proporcionado, creo que el uso de la barra de herramientas de depuración es una gran herramienta para mostrar consultas. Puede descargarlo desde github here.

Esto le da la opción de mostrar todas las consultas ejecutadas en una página determinada junto con el tiempo de consulta. También resume el número de consultas en una página junto con el tiempo total para una revisión rápida. Esta es una gran herramienta, cuando quieres ver lo que hace el Django ORM detrás de escena. También tiene muchas otras características agradables, que puede usar si lo desea.

+2

Me parece que esta es la mejor versión: https://github.com/django-debug-toolbar/django-debug-toolbar – philfreo

30

Eche un vistazo a debug_toolbar, es muy útil para la depuración.

La documentación y el código fuente están disponibles en http://django-debug-toolbar.readthedocs.io/.

Screenshot of debug toolbar

+1

debug_toolbar es especialmente útil cuando tiene una consulta que está fallando con un error de sintaxis SQL; mostrará la última consulta que intentó ejecutarse (y falló), lo que facilita la depuración. – scoopseven

9

Si se asegura de su archivo settings.py tiene:

  1. django.core.context_processors.debug enumeran en CONTEXT_PROCESSORS
  2. DEBUG=True
  3. su IP en el INTERNAL_IPS tupla

Entonces debería tener acceso a la variable sql_queries. Añado un pie de página para cada página que tiene este aspecto:

{%if sql_queries %} 
    <div class="footNav"> 
    <h2>Queries</h2> 
    <p> 
     {{ sql_queries|length }} Quer{{ sql_queries|pluralize:"y,ies" }}, {{sql_time_sum}} Time 
    {% ifnotequal sql_queries|length 0 %} 
     (<span style="cursor: pointer;" onclick="var s=document.getElementById('debugQueryTable').style;s.disp\ 
lay=s.display=='none'?'':'none';this.innerHTML=this.innerHTML=='Show'?'Hide':'Show';">Show</span>) 
    {% endifnotequal %} 
    </p> 
    <table id="debugQueryTable" style="display: none;"> 
     <col width="1"></col> 
     <col></col> 
     <col width="1"></col> 
     <thead> 
     <tr> 
      <th scope="col">#</th> 
      <th scope="col">SQL</th> 
      <th scope="col">Time</th> 
     </tr> 
     </thead> 
     <tbody> 
     {% for query in sql_queries %} 
      <tr class="{% cycle odd,even %}"> 
      <td>{{ forloop.counter }}</td> 
      <td>{{ query.sql|escape }}</td> 
      <td>{{ query.time }}</td> 
      </tr> 
     {% endfor %} 
     </tbody> 
    </table> 
    </div> 
{% endif %} 

que tiene la variable sql_time_sum añadiendo la línea

context_extras['sql_time_sum'] = sum([float(q['time']) for q in connection.queries]) 

a la función de depuración en django_src/django/core/context_processors.py.

+0

Acabo de probar esto, y (habiendo eliminado la parte sql_time_sum), obtuve: No named cycles en la plantilla. 'impar, incluso' no está definido, ¿qué me estoy perdiendo? – castaway

14
q = Query.objects.values('val1','val2','val_etc') 

print q.query 
+2

o 'str (q.query)' –

7

Otra opción, consulte las opciones de registro en settings.py descritas por este post

http://dabapps.com/blog/logging-sql-queries-django-13/

debug_toolbar ralentiza cada carga de la página en el servidor dev, la tala no por lo que es más rápido. Las salidas se pueden descargar a la consola o archivo, por lo que la interfaz de usuario no es tan agradable. Pero para vistas con muchos SQL, puede llevar mucho tiempo depurar y optimizar los SQL a través de debug_toolbar, ya que cada carga de página es muy lenta.

+0

¡Excelente! Si bien la barra de herramientas se ve genial, creo que esta respuesta debería ser la aceptada. Esta es la solución que quería porque permite que "manage.py runserver" registre SQL en la consola y funcione con "manage.py migrate". Este último me permitió ver que "on delete cascade" definitivamente no se estaba configurando cuando se crearon mis tablas. Vale la pena señalar que esta respuesta se basa en https://docs.djangoproject.com/en/1.9/topics/logging/#django-db-backends –

13

otra respuesta cubre este método, por lo que:

encuentro, con mucho, el método más útil, sencillo y fiable es preguntarle a su base de datos. Por ejemplo, en Linux para Postgres, puede hacer:

sudo su postgres 
tail -f /var/log/postgresql/postgresql-8.4-main.log 

Cada base de datos tendrá un procedimiento ligeramente diferente. En los registros de la base de datos, verá no solo el SQL sin formato, sino también cualquier configuración de conexión o sobrecarga de transacción que django esté colocando en el sistema.

+3

, no olvides establecer 'log_statement = 'all'' en' postgresql .conf' para este método. – RickyA

22

Django-extensions tienen un comando shell_plus con un parámetro print-sql

./manage.py shell_plus --print-sql 

En django-shell todas las consultas ejecutadas serán impresos

Ej .:

User.objects.get(pk=1) 
SELECT "auth_user"."id", 
     "auth_user"."password", 
     "auth_user"."last_login", 
     "auth_user"."is_superuser", 
     "auth_user"."username", 
     "auth_user"."first_name", 
     "auth_user"."last_name", 
     "auth_user"."email", 
     "auth_user"."is_staff", 
     "auth_user"."is_active", 
     "auth_user"."date_joined" 
FROM "auth_user" 
WHERE "auth_user"."id" = 1 

Execution time: 0.002466s [Database: default] 

<User: username> 
+0

Lo estoy usando con --print-sql o con SHELL_PLUS_PRINT_SQL = True y no ayuda - Todavía no puedo ver las consultas. alguna idea por que? django 1.8 – Dejell

1

Las siguientes declaraciones de la consulta como SQL válido, basado en https://code.djangoproject.com/ticket/17741:

def str_query(qs): 
    """ 
    qs.query returns something that isn't valid SQL, this returns the actual 
    valid SQL that's executed: https://code.djangoproject.com/ticket/17741 
    """ 
    cursor = connections[qs.db].cursor() 
    query, params = qs.query.sql_with_params() 
    cursor.execute('EXPLAIN ' + query, params) 
    res = str(cursor.db.ops.last_executed_query(cursor, query, params)) 
    assert res.startswith('EXPLAIN ') 
    return res[len('EXPLAIN '):] 
0

He hecho un pequeño fragmento que puede utilizar:

from django.conf import settings 
from django.db import connection 


def sql_echo(method, *args, **kwargs): 
    settings.DEBUG = True 
    result = method(*args, **kwargs) 
    for query in connection.queries: 
     print(query) 
    return result 


# HOW TO USE EXAMPLE: 
# 
# result = sql_echo(my_method, 'whatever', show=True) 

Toma como función de parámetros (contiene queryies SQL) para inspeccionar y args, kwargs necesarios para llamar a esa función. Como resultado, devuelve la función que devuelve e imprime las consultas SQL en una consola.

Cuestiones relacionadas