Nyers SQL-lekérdezések az mssql-django-ban

Ez a cikk bemutatja, hogyan hajthat végre nyers SQL-lekérdezéseket SQL Server Django-alkalmazásokból. A nyers SQL hasznos a Django ORM-en keresztül nem közzétett műveletekhez, például összetett Transact-SQL (T-SQL), térbeli lekérdezésekhez vagy teljesítménykritikus műveletekhez.

Használja a connection.cursor() függvényt

Közvetlenül a Django objektumán keresztül érheti el az adatbázis-kurzort connection :

from django.db import connection

def get_server_version():
    with connection.cursor() as cursor:
        cursor.execute("SELECT @@VERSION;")
        row = cursor.fetchone()
    return row[0]

Az with utasítás biztosítja, hogy a kurzor megfelelően legyen bezárva a használat után.

Paraméteres lekérdezések

Mindig használjon paraméteres lekérdezéseket az SQL-injektálás megakadályozásához. Paraméterek átadása listaként:

Note

Az alábbi példák a Django alapértelmezett táblaelnevezési konvencióját <app_label>_<model_name> használják (például myapp_product). Ha felülírja a(z) db_table elemet egy modell Meta elemében, helyettesítse ezt a nevet. A feloldott nevet futási időben is elolvashatja a(z) Product._meta.db_table használatával.

from django.db import connection

def get_products_by_price(min_price, max_price):
    with connection.cursor() as cursor:
        cursor.execute(
            "SELECT id, name, price FROM myapp_product WHERE price BETWEEN %s AND %s;",
            [min_price, max_price],
        )
        results = cursor.fetchall()
    return results

Important

Soha ne használjon sztringformázást vagy f-sztringeket az értékek SQL-lekérdezésekbe való beágyazásához. Az SQL-injektálás megakadályozása érdekében mindig használjon paraméteres lekérdezéseket (%s helyőrzőket paraméterlistával).

Eredmények beolvasása

Django kurzora számos módszert kínál az eredmények lekérésére:

from django.db import connection

def demonstrate_fetch_methods():
    with connection.cursor() as cursor:
        cursor.execute("SELECT id, name FROM myapp_product;")

        # Fetch one row
        row = cursor.fetchone()

        # Fetch the next 10 rows (continues from where fetchone stopped)
        rows = cursor.fetchmany(10)

        # Fetch all remaining rows (continues from where fetchmany stopped)
        all_rows = cursor.fetchall()

Az eredmények visszaadása szótárként

Sorok szótárakká alakítása a(z) cursor.description használatával:

from django.db import connection

def dictfetchall(cursor):
    columns = [col[0] for col in cursor.description]
    return [dict(zip(columns, row)) for row in cursor.fetchall()]

def get_all_products():
    with connection.cursor() as cursor:
        cursor.execute("SELECT id, name, price FROM myapp_product;")
        return dictfetchall(cursor)

Manager.raw() használata modelles lekérdezésekhez

Ha nyers SQL-t szeretne, de továbbra is Django-modellpéldányokat szeretne, használja a következőt Manager.raw():

from myapp.models import Product

products = Product.objects.raw(
    "SELECT id, name, price FROM myapp_product WHERE price > %s",
    [10.00],
)

for product in products:
    print(f"{product.name}: ${product.price}")

A lekérdezésnek a modell elsődleges kulcsában meghatározott összes mezőt vissza kell adnia. A további mezők igény szerint töltődnek be.

DDL-utasítások végrehajtása

Használjon nyers SQL-t olyan sémaműveletekhez, amelyeket a Django közvetlenül nem támogat:

from django.db import connection

def create_index():
    with connection.cursor() as cursor:
        cursor.execute(
            "CREATE INDEX IX_product_name ON myapp_product (name) "
            "INCLUDE (price);"
        )

Több adatbázis-kapcsolat

Ha több adatbázist használ, adja meg a használni kívánt kapcsolatot:

from django.db import connections

def query_reporting_db():
    with connections["reporting"].cursor() as cursor:
        cursor.execute("SELECT COUNT(*) FROM myapp_product;")
        return cursor.fetchone()[0]