জ্যাঙ্গো চলছে এমন কাঁচা এসকিউএল কোয়েরিগুলি আমি কীভাবে দেখতে পারি?


307

এসকিউএল দেখানোর কোনও উপায় আছে যে কোয়েরি করার সময় জাঙ্গো চলছে?

উত্তর:


371

দস্তাবেজগুলি এফএকিউ দেখুন: " আমি কীভাবে দেখতে পাচ্ছি যে কাঁচা এসকিউএল অনুসন্ধান জ্যাঙ্গো চলছে? "

django.db.connection.queries এসকিউএল প্রশ্নের একটি তালিকা রয়েছে:

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

ক্যোরিসেটে এক্সিকিউট করার জন্য ক্যোরিযুক্ত queryবৈশিষ্ট্যও রয়েছে:

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

নোট করুন যে ক্যোয়ারীর আউটপুটটি বৈধ এসকিউএল নয়, কারণ:

"জাজাঙ্গো আসলে প্যারামিটারগুলিকে কখনই বিভক্ত করে না: এটি কোয়েরি এবং পরামিতিগুলি পৃথকভাবে ডাটাবেস অ্যাডাপ্টারে প্রেরণ করে, যা উপযুক্ত ক্রিয়াকলাপ সম্পাদন করে।"

জাজানো বাগ রিপোর্ট # 17741 থেকে

তার কারণে আপনার কোয়েরি আউটপুট সরাসরি কোনও ডাটাবেসে প্রেরণ করা উচিত নয়।


13
ভবিষ্যতের প্রমাণের জন্য এই উত্তরটির পরিবর্তে আপনার জাজানো
আন্দ্রে মিলার

5
দুর্দান্ত উত্তর। তবে এটি নির্দিষ্ট, বিল্টিন পাইথোনিয়ান str()ফাংশনটি ব্যবহার করার পরামর্শ দেওয়া হয় যা অভ্যন্তরীণ __str__()পদ্ধতিতে আবেদন করে । উদাহরণস্বরূপ, str(MyModel.objects.filter(name="my name").query) আমি আইপিথন এবং আপনার প্রকল্পের জ্যাঙ্গো শেলটি ব্যবহার করার পরামর্শ দেব। ট্যাব সমাপ্তি তখন অবজেক্টের অন্তর্নির্মাণ সরবরাহ করে। যেহেতু জাজানো তার দৃser় নামকরণের স্কিমগুলির জন্য পরিচিত, তাই এই পদ্ধতিটি খুব কার্যকর হতে পারে।
লোরেঞ্জ লো Sauer

7
নোট করুন যে এর আউটপুটটি queryবৈধ এসকিউএল নয়, কারণ "জ্যাঙ্গো আসলে কখনই প্যারামিটারগুলিকে বিভক্ত করে না: এটি কোয়েরি এবং পরামিতিগুলি পৃথকভাবে ডাটাবেস অ্যাডাপ্টারে প্রেরণ করে, যা উপযুক্ত ক্রিয়াকলাপ সম্পাদন করে।" সূত্র: কোড. djangoproject.com/ticket/17741
গ্রেগলটসভ

3
@AndreMiller আপনি ব্যবহার করা উচিত stable, না dev: মত এই জ্যাঙ্গো এর বর্তমান সংস্করণ, এর লিঙ্ক, docs.djangoproject.com/en/stable/faq/models/...
Flimm

3
django.db.connection.queries খালি তালিকা ফিরিয়ে দেয়
কল্পিত

60

জ্যাঙ্গো-এক্সটেনশনের একটি পরামিতি সহ কমান্ড শেল_প্লাস রয়েছেprint-sql

./manage.py shell_plus --print-sql

জ্যাঙ্গো-শেল-এ সমস্ত কার্যকর করা প্রশ্নগুলি মুদ্রিত হবে

প্রাক্তন .:

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
আমি এটি --প্রিন্ট-এসকিউএল বা SHELL_PLUS_PRINT_SQL = সত্য দিয়ে ব্যবহার করছি এবং এটি সাহায্য করে না - আমি এখনও কোয়েরি দেখতে পাচ্ছি না। কোন ধারণা কেন?
জাজানো

1
আপনার অনুসন্ধানগুলি দেখতে আপনার সেটিংসে DEBUG = সত্য সেট করা দরকার
py কোপিগুলি

49

ডিবাগ_টুলবার একবার দেখুন , এটি ডিবাগিংয়ের জন্য খুব দরকারী।

ডকুমেন্টেশন এবং উত্স http://django-debug-toolbar.readthedocs.io/ এ উপলব্ধ ।

ডিবাগ সরঞ্জামদণ্ডের স্ক্রিনশট


1
আপনার যখন একটি এসকিউএল সিন্ট্যাক্স ত্রুটির সাথে ব্যর্থ হয় এমন একটি কোয়েরি থাকে তখন ডিবাগ_টুলবারটি বিশেষত কার্যকর; এটি শেষ জিজ্ঞাসাটি প্রদর্শন করবে যা চালানোর চেষ্টা করেছিল (এবং ব্যর্থ হয়েছে), এটি ডিবাগ করা সহজ করে।
স্কুপসভেন

কেবলমাত্র আপনি ব্রাউজারে এসকিউএল অনুসন্ধানগুলি দেখতে পান। আপনি যদি টার্মিনাল থেকে পরীক্ষা চালান এবং এটি দেখতে চান তবে এটি একটি কার্যকর সমাধান নয়। তবুও দুর্দান্ত, আমি এটি আজ অবধি ব্যবহার করছি।
এরদিন ইরে

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

print q.query

খুব সহজ উত্তর! সুন্দর
এস্পোয়ার মুরাহবাজী

এই কার্যকারিতা সরানো হয়েছে? আমি m = MyModel.objects.get(...)অনুসরণ করার পরে এটি কাজ করে নাm.query
স্যাজ

এটি কারণ mএখন আর ক্যোয়ারসেট নয়। q = MyModel.objects.filter(...)তারপরে q.query, ব্যবহার করুন m = q.get()
ব্রাউয়ার

24

অন্য কোনও উত্তর এই পদ্ধতিটি কভার করে না, তাই:

আমি এখন পর্যন্ত সবচেয়ে দরকারী, সহজ এবং নির্ভরযোগ্য পদ্ধতিটি আপনার ডেটাবেসকে জিজ্ঞাসা করা। উদাহরণস্বরূপ লিনাক্সের জন্য পোস্টগ্রিসের জন্য আপনি যা করতে পারেন:

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

যদিও আপনি সরবরাহকৃত কোডটি দিয়ে এটি করতে পারেন তবে আমি দেখতে পেয়েছি যে ডিবাগ সরঞ্জামদণ্ড অ্যাপ্লিকেশনটি কোয়েরিগুলি দেখানোর জন্য একটি দুর্দান্ত সরঞ্জাম। আপনি এটি গিথব থেকে ডাউনলোড করতে পারেন এখানে

এটি আপনাকে জিজ্ঞাসা করার সময় সহ একটি নির্দিষ্ট পৃষ্ঠায় দৌড়ে সমস্ত প্রশ্নগুলি দেখানোর বিকল্প দেয়। এটি দ্রুত পর্যালোচনার জন্য মোট সময় সহ একটি পৃষ্ঠায় প্রশ্নের সংখ্যাও যোগ করে। এটি একটি দুর্দান্ত সরঞ্জাম, যখন আপনি দেখতে চান যে জ্যাঙ্গো ওআরএম পর্দার আড়ালে কী করে। এটিতে আরও অনেক দুর্দান্ত বৈশিষ্ট্য রয়েছে, যা আপনি চাইলে ব্যবহার করতে পারেন।


2
আমার কাছে এটি দেখতে সেরা সংস্করণ বলে মনে হচ্ছে: github.com/django-debug-toolbar/django-debug-toolbar
ফিলাফ্রেও

15

অন্য একটি বিকল্প, সেটিংসে লগিং বিকল্পগুলি দেখুন seeএই পোস্টের দ্বারা বর্ণিত py

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

ডিবাগ_টুলবার আপনার ডেভ সার্ভারে প্রতিটি পৃষ্ঠার লোডকে ধীর করে দেয়, লগিং তত দ্রুত হয় না। আউটপুটগুলি কনসোল বা ফাইলের জন্য ফেলে দেওয়া যেতে পারে, তাই ইউআই তেমন সুন্দর নয়। তবে প্রচুর এসকিউএল সহ দর্শনগুলির জন্য, প্রতিটি পৃষ্ঠার বোঝা এত ধীর হওয়ায় ডিবাগ_টুলবারের মাধ্যমে এসকিউএলগুলি ডিবাগ করতে এবং অনুকূল করতে অনেক সময় নিতে পারে।


অসাধারণ! যদিও সরঞ্জামদণ্ডটি দুর্দান্ত দেখায়, আমি মনে করি এই উত্তরটি গ্রহণযোগ্য হওয়া উচিত। এটি আমার সমাধান চেয়েছিল কারণ এটি কনসোলটিতে "ম্যানেজ.পি রানসরভার" এসকিউএল লগ করতে দেয় এবং এটি "ম্যানেজ.পি মাইগ্রেশন" দিয়ে কাজ করে। দ্বিতীয়টি আমাকে দেখতে দিন যে আমার টেবিলগুলি তৈরি হওয়ার পরে "অনুলিপি ক্যাসকেড অন" অবশ্যই সেট করা হয়নি। এটি লক্ষণীয় যে এই উত্তরটি ডকস.ডজ্যাঙ্গোপ্রজেক্ট
এলএস

10

যদি আপনি নিশ্চিত হন যে আপনার সেটিংস.পি ফাইলটিতে রয়েছে:

  1. django.core.context_processors.debug তালিকাভুক্ত CONTEXT_PROCESSORS
  2. DEBUG=True
  3. আপনার IPমধ্যে INTERNAL_IPStuple

তারপরে আপনার 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 / context_processors.py এ ডিবাগ ফাংশনে।


1
আমি কেবল এটি চেষ্টা করেছি, এবং (স্ক্যুয়াল_টাইম_সাম অংশটি সরিয়ে দিয়ে) পেয়েছি: টেমপ্লেটে কোনও নাম্বার চক্র নেই। 'বিজোড়, এমনকি' সংজ্ঞায়িত করা হয় না - আমি কী মিস করছি?
জাহাজডুবি

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

আমি বিশ্বাস করি আপনি যদি পোস্টগ্রিজ এসকিউএল ব্যবহার করেন তবে এটির কাজ করা উচিত:

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

এটি পাইথন ২ তেও কাজ করেছিল print কেবলমাত্র মুদ্রণের মতো একটি রিফ্যাক্টর (কার্সার.মোগ্রিফাই (* কিউএস.কোয়ারি.এসকিএল_উইথ_প্যারামস ())) এর জন্য এটির প্রয়োজন।
আইচুকস

আইআইআরসি কার্সার.মোগ্রিফাই একটি স্ট্রিং প্রদান করে, তাই আমি অনুমান করি যে বিন্যাসের জন্য f স্ট্রিংয়ের ব্যবহার অতিরিক্ত
ব্যবহারযোগ্য

2

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)

প্যারামিটার ফাংশন হিসাবে লাগে (এসকিউএল ক্যোয়ারী ধারণ করে) পরিদর্শন করতে এবং আর্গুমেন্টগুলি, যে ফাংশনটি কল করার জন্য কোয়ার্গস প্রয়োজন। ফলস্বরূপ এটি কী ফাংশনটি দেয় এবং কোনও কনসোলে এসকিউএল কোয়েরিগুলি মুদ্রণ করে।


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

টেম্পলেটটির বাইরে এটি করা খুব ভাল কারণ যদি আপনার এপিআই ভিউ থাকে (সাধারণত জ্যাঙ্গো রেস্ট ফ্রেমওয়ার্ক) থাকে তবে এটি সেখানেও প্রযোজ্য।


1

জ্যাঙ্গো ২.২ এর জন্য:

যেহেতু বেশিরভাগ উত্তরগুলি ব্যবহার করার সময় আমাকে খুব বেশি সহায়তা করে নি ./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)

ক্যোরিসেট অবজেক্টে কাঁচা এসকিউএল কোয়েরি অ্যাক্সেস করুন

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

0

জ্যাঙ্গোতে কেবল যুক্ত করার জন্য, যদি আপনার কাছে এমন কোনও প্রশ্ন থাকে:

MyModel.objects.all()

একটি করুন:

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

SQL স্ট্রিং পেতে

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.