466 Stimmen

Wie kann ich die rohen SQL-Abfragen sehen, die Django ausführt?

Gibt es eine Möglichkeit, die SQL, die Django ausgeführt wird, während der Durchführung einer Abfrage zu zeigen?

3voto

Dave Vogt Punkte 16300

Es gibt noch eine andere Möglichkeit, die sehr nützlich ist, wenn Sie die Abfrage für ein benutzerdefiniertes SQL wiederverwenden müssen. Ich habe dies in einer Analyse-App verwendet, die weit über das hinausgeht, was Djangos ORM bequem tun kann, also schließe ich ORM-generiertes SQL als Unterabfragen ein.

from django.db import connection
from myapp.models import SomeModel

queryset = SomeModel.objects.filter(foo='bar')

sql_query, params = queryset.query.as_sql(None, connection)

Dadurch erhalten Sie das SQL mit Platzhaltern sowie ein Tupel mit den zu verwendenden Abfrageparametern. Dieses können Sie direkt an die DB weitergeben:

with connection.connection.cursor(cursor_factory=DictCursor) as cursor:
    cursor.execute(sql_query, params)
    data = cursor.fetchall()

2voto

turkus Punkte 4097

Ich habe ein kleines Snippet erstellt, das Sie verwenden können:

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)

Sie nimmt als Parameter die Funktion (enthält SQL-Abfragen), die überprüft werden soll, und die für den Aufruf dieser Funktion erforderlichen Args und Wargs. Als Ergebnis gibt es zurück, was die Funktion zurückgibt und druckt SQL-Abfragen in einer Konsole.

2voto

megajoe Punkte 525

Um die Ergebnisabfrage von django an die Datenbank (mit korrekter Parametersubstitution) können Sie diese Funktion verwenden:

from django.db import connection

def print_database_query_formatted(query):
    sql, params = query.sql_with_params()
    cursor = connection.cursor()
    cursor.execute('EXPLAIN ' + sql, params)
    db_query = cursor.db.ops.last_executed_query(cursor, sql, params).replace('EXPLAIN ', '')

    parts = '{}'.format(db_query).split('FROM')
    print(parts[0])
    if len(parts) > 1:
        parts = parts[1].split('WHERE')
        print('FROM{}'.format(parts[0]))
        if len(parts) > 1:
            parts = parts[1].split('ORDER BY')
            print('WHERE{}'.format(parts[0]))
            if len(parts) > 1:
                print('ORDER BY{}'.format(parts[1]))

# USAGE
users = User.objects.filter(email='admin@admin.com').order_by('-id')
print_database_query_formatted(users.query)

Beispiel für die Ausgabe

SELECT "users_user"."password", "users_user"."last_login", "users_user"."is_superuser", "users_user"."deleted", "users_user"."id", "users_user"."phone", "users_user"."username", "users_user"."userlastname", "users_user"."email", "users_user"."is_staff", "users_user"."is_active", "users_user"."date_joined", "users_user"."latitude", "users_user"."longitude", "users_user"."point"::bytea, "users_user"."default_search_radius", "users_user"."notifications", "users_user"."admin_theme", "users_user"."address", "users_user"."is_notify_when_buildings_in_radius", "users_user"."active_campaign_id", "users_user"."is_unsubscribed", "users_user"."sf_contact_id", "users_user"."is_agree_terms_of_service", "users_user"."is_facebook_signup", "users_user"."type_signup" 
FROM "users_user" 
WHERE "users_user"."email" = 'admin@admin.com' 
ORDER BY "users_user"."id" DESC

Sie basiert auf diesem Ticket-Kommentar: https://code.djangoproject.com/ticket/17741#comment:4

2voto

pymen Punkte 4445

An SQL generieren para CREATE / UPDATE Befehle, die sofort in Django [getestet auf 1.8]

def generate_update_sql(queryset, update_kwargs):
    """Converts queryset with update_kwargs
    like if was: queryset.update(**update_kwargs)

    qs = Event.objects.exclude(app='some')
    update_kwargs = dict(description='test', action='action')
    generate_update_sql(qs, update_kwargs) will return
    UPDATE `api_event` SET `description` = test, `action` = action WHERE NOT (`api_event`.`app` = some)
    """
    from django.db.models import sql

    query = queryset.query.clone(sql.UpdateQuery)
    query.add_update_values(update_kwargs)
    compiler = query.get_compiler(queryset.db)
    sql, params = compiler.as_sql()
    return sql % params

def generate_create_sql(model, model_data):
    """Converts queryset with create_kwargs
    like if was: queryset.create(**create_kwargs)

    generate_create_sql(Event, dict(slug='a', app='b', model='c', action='e')) will return
    "INSERT INTO `api_event` (`slug`, `app`, `model`, `action`, `action_type`) VALUES (a, b, c, e, )"

    """
    from django.db.models import sql

    not_saved_instance = model(**model_data)
    not_saved_instance._for_write = True

    query = sql.InsertQuery(model)

    fields = [f for f in model._meta.local_concrete_fields if not isinstance(f, AutoField)]
    query.insert_values(fields, [not_saved_instance], raw=False)

    compiler = query.get_compiler(model.objects.db)
    sql, params = compiler.as_sql()[0]
    return sql % params

Tests und Verwendung

    def test_generate_update_sql_with_F(self):
        qs = Event.objects.all()
        update_kwargs = dict(description=F('slug'))
        result = generate_update_sql(qs, update_kwargs)
        sql = "UPDATE `api_event` SET `description` = `api_event`.`slug`"
        self.assertEqual(sql, result)

    def test_generate_create_sql(self):
        result = generate_create_sql(Event, dict(slug='a', app='b', model='c', action='e'))
        sql = "INSERT INTO `api_event` (`slug`, `app`, `model`, `action`, `action_type`, `description`) VALUES (a, b, c, e, , )"
        self.assertEqual(sql, result)

-1voto

Abfragen anzeigen Verwendung von django.db.connection.queries

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

Zugriff auf Roh-SQL-Abfrage auf QuerySet-Objekt

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X