मैं कैसे देख सकता हूँ कच्चे SQL क्वेरी Django चल रहा है?


307

क्या SQL को दिखाने का कोई तरीका है कि Django क्वेरी करते समय चल रहा है?

जवाबों:


372

डॉक्स FAQ देखें: " मैं कैसे देख सकता हूं कि कच्चे एसक्यूएल के सवाल Django चल रहे हैं? "

django.db.connection.queries SQL प्रश्नों की एक सूची है:

from django.db import connection
print(connection.queries)

क्वेरीज़ में एक queryविशेषता भी होती है जिसमें क्वेरी को निष्पादित किया जाता है:

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

ध्यान दें कि क्वेरी का आउटपुट मान्य SQL नहीं है, क्योंकि:

"Django वास्तव में मापदंडों को कभी भी प्रक्षेपित नहीं करता है: यह क्वेरी और मापदंडों को अलग-अलग डेटाबेस एडेप्टर को भेजता है, जो उचित संचालन करता है।"

Django बग रिपोर्ट # 17741 से

उसके कारण, आपको क्वेरी आउटपुट को सीधे डेटाबेस में नहीं भेजना चाहिए।


13
भविष्य के प्रमाण के लिए इस उत्तर को आपको Django के दस्तावेज़ के वर्तमान संस्करण से जोड़ना चाहिए: docs.djangoproject.com/en/dev/faq/models/…
आंद्रे मिलर

5
बहुत बढ़िया जवाब। हालांकि, यह निर्दिष्ट, निर्मित पायथोनियन str()फ़ंक्शन का उपयोग करने के लिए अनुशंसित है , जो आंतरिक __str__()विधि को लागू करता है। उदाहरण के लिए, str(MyModel.objects.filter(name="my name").query) मैं आपके प्रोजेक्ट के IPython और Django शेल का उपयोग करने की भी सिफारिश करूंगा। टैब पूरा होने पर वस्तु आत्मनिरीक्षण प्रदान करता है। जैसा कि Django अपनी मुखर नामकरण योजनाओं के लिए जाना जाता है, यह पद्धति बहुत उपयोगी है।
लोरेंज लो सॉर

7
ध्यान दें कि आउटपुट आउटपुट querySQL मान्य नहीं है, क्योंकि "Django कभी भी मापदंडों को इंटरपोल नहीं करता है: यह क्वेरी और पैरामीटर को अलग-अलग डेटाबेस एडेप्टर को भेजता है, जो उचित संचालन करता है।" स्रोत: code.djangoproject.com/ticket/17741
gregoltsov

3
@AndreMiller आपको Django के वर्तमान संस्करण से लिंक करने के लिए उपयोग करना चाहिए stable, नहीं dev, इस तरह: docs.djangoproject.com/en/stable/faq/models/…
Flim

3
django.db.connection.queries खाली सूची देता है
फंतासी

60

Django- एक्सटेंशन में एक पैरामीटर के साथ एक कमांड शेल_प्लस हैprint-sql

./manage.py shell_plus --print-sql

Django-shell में सभी निष्पादित प्रश्नों को मुद्रित किया जाएगा

पूर्व .:

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>

1
मैं इसे --print-sql या SHELL_PLUS_PRINT_SQL = True के साथ उपयोग कर रहा हूँ और यह मदद नहीं करता है - मैं अभी भी प्रश्नों को नहीं देख सकता। किसी भी विचार क्यों? django 1.8
डेजेल

1
आपको प्रश्न देखने के लिए DEBUG = True को अपनी सेटिंग में सेट करना होगा
Konstantin Voschanov

49

Debug_toolbar पर एक नज़र डालें , यह डीबगिंग के लिए बहुत उपयोगी है।

दस्तावेज़ और स्रोत http://django-debug-toolbar.readthedocs.io/ पर उपलब्ध है ।

डिबग टूलबार का स्क्रीनशॉट


1
debug_toolbar विशेष रूप से तब उपयोगी होता है जब आपके पास SQL ​​सिंटैक्स त्रुटि के साथ विफल होने वाली क्वेरी होती है; यह अंतिम क्वेरी को चलाने का प्रयास करेगा (और विफल), जिससे यह डीबग करना आसान हो जाएगा।
स्कूपसेवन

केवल एक चीज है जो आप ब्राउज़र पर SQL क्वेरी देखते हैं। यदि आप टर्मिनल से परीक्षण चलाते हैं और इसे वहां देखना चाहते हैं, तो यह एक व्यवहार्य समाधान नहीं है। अभी भी बहुत अच्छा, मैं इसे आज तक इस्तेमाल कर रहा हूं।
एरडिन एरे

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

print q.query

बहुत ही सरल उत्तर! नाइस
एस्पायर मुरहाबाज़ी

क्या यह कार्यक्षमता हटा दी गई है? जब मैं इसके m = MyModel.objects.get(...)बाद काम नहीं करता तो यह काम नहीं करताm.query
sg

ऐसा इसलिए mहै क्योंकि अब कोई क्वेरी नहीं है। का उपयोग करें q = MyModel.objects.filter(...), तब q.query, फिर m = q.get()
ब्रूवर

24

कोई अन्य उत्तर इस पद्धति को शामिल नहीं करता है, इसलिए:

मुझे अब तक का सबसे उपयोगी, सरल, और विश्वसनीय तरीका अपने डेटाबेस से पूछना है। उदाहरण के लिए लिनक्स पर Postgres के लिए आप कर सकते हैं:

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

प्रत्येक डेटाबेस में थोड़ी अलग प्रक्रिया होगी। डेटाबेस लॉग में आप न केवल कच्चे एसक्यूएल को देखेंगे, बल्कि सिस्टम पर कोई कनेक्शन सेटअप या ट्रांजेक्शन ओवरहेड डीजैंगो डाल रहा है।


8
स्थापित करने के लिए मत भूलना log_statement='all'में postgresql.confइस विधि के लिए।
रिक्की

2
आप postgresql.confदौड़ कर अपना पता लगा सकते हैंpsql -U postgres -c 'SHOW config_file'
kramer65

17

यद्यपि आप इसे आपूर्ति किए गए कोड के साथ कर सकते हैं, मुझे लगता है कि डिबग टूलबार ऐप का उपयोग करना प्रश्नों को दिखाने के लिए एक महान उपकरण है। आप इसे यहाँ जीथब से डाउनलोड कर सकते हैं

यह आपको किसी दिए गए पृष्ठ पर चलाए गए सभी प्रश्नों को क्वेरी करने के समय के साथ दिखाने का विकल्प देता है। यह त्वरित समीक्षा के लिए कुल समय के साथ एक पृष्ठ पर प्रश्नों की संख्या को भी बताता है। यह एक महान उपकरण है, जब आप यह देखना चाहते हैं कि Django ORM पर्दे के पीछे क्या करता है। इसमें कई अन्य अच्छे फीचर्स भी हैं, जिन्हें आप चाहें तो इस्तेमाल कर सकते हैं।


2
मुझे ऐसा लगता है कि यह सबसे अच्छा संस्करण है: github.com/django-debug-toolbar/django-debug-toolbar
philfreo

15

एक अन्य विकल्प, इस पोस्ट के द्वारा वर्णित settings.py में लॉगिंग विकल्प देखें

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

debug_toolbar आपके देव सर्वर पर प्रत्येक पृष्ठ लोड को धीमा कर देता है, लॉगिंग तेजी से नहीं होती है। आउटपुट को कंसोल या फ़ाइल में डंप किया जा सकता है, इसलिए यूआई उतना अच्छा नहीं है। लेकिन बहुत सारी एसक्यूएल वाले विचारों के लिए, डीबग करने में लंबा समय लग सकता है और डीबग_टूलबार के माध्यम से एसक्यूएल को ऑप्टिमाइज़ कर सकते हैं क्योंकि प्रत्येक पेज लोड इतना धीमा है।


अति उत्कृष्ट! जबकि टूलबार बहुत अच्छा लगता है, मुझे लगता है कि यह उत्तर स्वीकृत होना चाहिए। यह वह समाधान है जो मैं चाहता था क्योंकि यह कंसोल के लिए "मैनेज एरेन्डोवर रनवे" लॉग एसक्यूएल देता है और यह "मैनेजमेड माइग्रेट" के साथ काम करता है। उत्तरार्द्ध मुझे देखते हैं कि "जब मेरी टेबल बनाई जाती है तो निश्चित रूप से कैस्केड पर" सेट नहीं किया जाता था। यह ध्यान देने योग्य है कि यह उत्तर docs.djangoproject.com/en/1.9/topics/log//
LS

10

यदि आप यह सुनिश्चित करते हैं कि आपकी सेटिंग्स में फ़ाइल है:

  1. django.core.context_processors.debug में सूचीबद्ध CONTEXT_PROCESSORS
  2. DEBUG=True
  3. अपने IPमें INTERNAL_IPSटपल

तब आपके पास sql_queriesचर तक पहुंच होनी चाहिए । मैं प्रत्येक पृष्ठ पर एक पाद लेख संलग्न करता हूं जो इस तरह दिखता है:

{%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लाइन जोड़कर वेरिएबल मिला

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

django_src / django / core / संदर्भ_processors.py में डीबग फ़ंक्शन के लिए।


1
मैंने सिर्फ यह कोशिश की, और (sql_time_sum भाग को हटा दिया), मिला: टेम्पलेट में कोई नाम चक्र नहीं। 'विषम, यहां तक ​​कि' परिभाषित नहीं है - मैं क्या याद कर रहा हूं?
कास्टअवे

8

मैंने इस उद्देश्य के लिए एक एक्सटेंशन विकसित किया है, जिससे आप आसानी से अपने व्यू फंक्शन पर डेकोरेटर लगा सकते हैं और देख सकते हैं कि कितने प्रश्नों का निष्पादन होता है।

स्थापित करने के लिए:

$ pip install django-print-sql

संदर्भ प्रबंधक के रूप में उपयोग करने के लिए:

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

डेकोरेटर के रूप में उपयोग करने के लिए:

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

गिथब: https://github.com/rabbit-aaron/django-print-sql


3

मेरा मानना ​​है कि यदि आप 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())}')

यह पाइथन में भी काम करता है 2. केवल एक रिफलेक्टर जैसे प्रिंट (कर्सर.मोग्रिफ़ (* qs.query.sql_with_params ()) यह सब इसकी आवश्यकता है।
IChux

IIRC Cursor.mogrify एक स्ट्रिंग लौटाता है, इसलिए मुझे लगता है कि स्वरूपण के लिए f स्ट्रिंग का उपयोग बहुत ही शानदार है ..
chander

2

निम्न क्वेरी मान्य SQL के रूप में, 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 '):]

2

मैंने एक छोटा सा स्निपेट बनाया है जिसका आप उपयोग कर सकते हैं:

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)

यह निरीक्षण करने और आर्ग करने के लिए पैरामीटर फंक्शन (sql क्वेरी शामिल होती है) के रूप में लेता है, kwargs को उस फ़ंक्शन को कॉल करने की आवश्यकता होती है। परिणाम के रूप में यह देता है जो फ़ंक्शन देता है और SQL क्वेरी कंसोल में प्रिंट करता है।


1

मैंने इस फ़ंक्शन को अपनी परियोजना के एक ऐप में उपयोग फ़ाइल में रखा:

import logging
import re

from django.db import connection

logger = logging.getLogger(__name__)

def sql_logger():
    logger.debug('TOTAL QUERIES: ' + str(len(connection.queries)))
    logger.debug('TOTAL TIME: ' + str(sum([float(q['time']) for q in connection.queries])))

    logger.debug('INDIVIDUAL QUERIES:')
    for i, query in enumerate(connection.queries):
        sql = re.split(r'(SELECT|FROM|WHERE|GROUP BY|ORDER BY|INNER JOIN|LIMIT)', query['sql'])
        if not sql[0]: sql = sql[1:]
        sql = [(' ' if i % 2 else '') + x for i, x in enumerate(sql)]
        logger.debug('\n### {} ({} seconds)\n\n{};\n'.format(i, query['time'], '\n'.join(sql)))

फिर, जब जरूरत होती है, मैं बस इसे आयात करता हूं और इसे जो भी संदर्भ (आमतौर पर एक दृश्य) से कॉल करना आवश्यक है, जैसे:

# ... other imports
from .utils import sql_logger

class IngredientListApiView(generics.ListAPIView):
    # ... class variables and such

    # Main function that gets called when view is accessed
    def list(self, request, *args, **kwargs):
        response = super(IngredientListApiView, self).list(request, *args, **kwargs)

        # Call our function
        sql_logger()

        return response

टेम्पलेट के बाहर ऐसा करना अच्छा है क्योंकि तब यदि आपके पास एपीआई विचार (आमतौर पर Django रेस्ट फ्रेमवर्क) है, तो यह वहां भी लागू होता है।


1

Django 2.2 के लिए:

उपयोग करते समय अधिकांश उत्तरों ने मेरी बहुत मदद नहीं की ./manage.py shell । अंत में मुझे जवाब मिल गया। आशा है कि यह किसी को मदद करता है।

सभी प्रश्नों को देखने के लिए:

from django.db import connection
connection.queries

किसी एकल क्वेरी के लिए क्वेरी देखने के लिए:

q=Query.objects.all()
q.query.__str__()

q.queryसिर्फ मेरे लिए वस्तु प्रदर्शित करना। __str__()(स्ट्रिंग प्रतिनिधित्व) का उपयोग करके पूरी क्वेरी प्रदर्शित की गई।


0

Django.db.connection.queries का उपयोग करके क्वेरी देखें

from django.db import connection
print(connection.queries)

QuerySet ऑब्जेक्ट पर कच्चे SQL क्वेरी तक पहुँचें

 qs = MyModel.objects.all()
 print(qs.query)

0

बस जोड़ने के लिए, django में, यदि आपके पास कोई क्वेरी है जैसे:

MyModel.objects.all()

करना:

MyModel.objects.all().query.sql_with_params()

sql स्ट्रिंग प्राप्त करने के लिए

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.