update transaction the raw queryset query primary must sql django

sql - transaction - select where django



¿Cómo puedo ver las consultas de SQL sin procesar que Django está ejecutando? (12)

¿Hay alguna manera de mostrar el SQL que Django está ejecutando al realizar una consulta?


Aunque puede hacerlo con el código suministrado, encuentro que usar la aplicación de la barra de herramientas de depuración es una gran herramienta para mostrar consultas. Puedes 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 que tomó la 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 quiere ver lo que el ORM de Django hace entre bastidores. También tiene muchas otras características interesantes que puede usar si lo desea.


Consulte las preguntas frecuentes de la documentación: " ¿Cómo puedo ver las consultas de SQL sin procesar que Django está ejecutando? "

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

from django.db import connection print connection.queries

Los conjuntos de consultas también tienen un atributo de query contiene la consulta que se ejecutará:

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

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

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

Del informe de error Django #17741 .

Debido a eso, no debe enviar el resultado de la consulta directamente a una base de datos.


Creo que esto debería funcionar si está utilizando PostgreSQL:

from django.db import connections from app_name import models from django.utils import timezone # Generate a queryset, use your favorite filter, QS objects, and whatnot. qs=models.ThisDataModel.objects.filter(user=''bob'',date__lte=timezone.now()) # Get a cursor tied to the default database cursor=connections[''default''].cursor() # Get the query SQL and parameters to be passed into psycopg2, then pass # those into mogrify to get the query that would have been sent to the backend # and print it out. Note F-strings require python 3.6 or later. print(f''{cursor.mogrify(*qs.query.sql_with_params())}'')


Desarrollé una extensión para este propósito, para que pueda poner fácilmente un decorador en su función de vista y ver cuántas consultas se ejecutan.

Instalar:

$ pip install django-print-sql

Para utilizar como gestor de contexto:

from django_print_sql import print_sql # set `count_only` to `True` will print the number of executed SQL statements only with print_sql(count_only=False): # write the code you want to analyze in here, # e.g. some complex foreign key lookup, # or analyzing a DRF serializer''s performance for user in User.objects.all()[:10]: user.groups.first()

Para utilizar como decorador:

from django_print_sql import print_sql_decorator @print_sql_decorator(count_only=False) # this works on class-based views as well def get(request): # your view code here

Github: https://github.com/rabbit-aaron/django-print-sql



He hecho un pequeño fragmento que puedes usar:

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 consultas de SQL) para inspeccionar y args, kwargs necesita llamar a esa función. Como resultado, devuelve qué función devuelve e imprime consultas SQL en una consola.


Lo siguiente devuelve la consulta como SQL válido, basado en #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 ''):]


Ninguna otra respuesta cubre este método, así que:

Considero que el método más útil, simple y confiable es, con mucho, consultar su base de datos. Por ejemplo, en Linux para Postgres puedes 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 procesar, sino también cualquier configuración de conexión o sobrecarga de transacción que django coloque en el sistema.


Otra opción, vea las opciones de registro en settings.py descritas en esta publicación

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

debug_toolbar ralentiza cada carga de página en su servidor dev, el registro no lo hace más rápido. Las salidas se pueden volcar a la consola o al archivo, por lo que la interfaz de usuario no es tan agradable. Pero para las 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.


Si te aseguras de que tu archivo settings.py tenga:

  1. django.core.context_processors.debug listado en CONTEXT_PROCESSORS
  2. DEBUG=True
  3. tu IP en la tupla de INTERNAL_IPS

Entonces deberías tener acceso a la variable sql_queries . Le agrego un pie de página a cada página que se ve así:

{%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 %}

sql_time_sum la variable sql_time_sum agregando 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.


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

./manage.py shell_plus --print-sql

En django-shell se imprimirán todas las consultas ejecutadas.

Ex.:

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>


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