mssql-django'da ham SQL sorguları

Bu makalede, Django uygulamalarından SQL Server karşı ham SQL sorgularının nasıl yürütüleceğini açıklanmaktadır. Ham SQL, karmaşık Transact-SQL (T-SQL), uzamsal sorgular veya performans açısından kritik işlemler gibi Django ORM aracılığıyla kullanıma sunulmayan işlemler için kullanışlıdır.

connection.cursor() kullanın

Veritabanı imlecine doğrudan Django'nun nesnesi aracılığıyla erişin 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]

deyimi, with imlecin kullanımdan sonra düzgün bir şekilde kapatılmasını sağlar.

Parametreli sorgular

SQL eklemesini önlemek için her zaman parametreli sorgular kullanın. Parametreleri liste olarak geçirin:

Note

Aşağıdaki örneklerde Django'nun varsayılan tablo adlandırma kuralı <app_label>_<model_name> (örneğin, myapp_product) kullanılır. Bir modelin Meta öğesinde db_table değerini geçersiz kılarsanız, o adın yerine bunu kullanın. Çözümlenen adı, çalışma zamanında Product._meta.db_table ile de okuyabilirsiniz.

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

SQL sorgularına değer eklemek için hiçbir zaman dize biçimlendirmesini veya f dizelerini kullanmayın. SQL eklemesini önlemek için her zaman parametreli sorgular (%s parametre listesi içeren yer tutucular) kullanın.

Sonuçları getir

Django'nun imleci sonuçları almak için çeşitli yöntemler sağlar:

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

Sonuçları sözlük olarak döndürme

kullanarak cursor.descriptionsatırları sözlüklere dönüştürün:

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)

Model sorguları için Manager.raw() kullanma

Ham SQL istiyor ancak yine de Django model örneklerini istiyorsanız kullanın 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}")

Sorgu, modelin birincil anahtarında tanımlanan tüm alanları döndürmelidir. Ek alanlar gevşek olarak yüklenir.

DDL komutlarını yürütün

Django'nun doğrudan desteklemediği şema işlemleri için ham SQL kullanın:

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);"
        )

Birden çok veritabanı bağlantısı

Birden çok veritabanı kullanıyorsanız, hangi bağlantının kullanılacağını belirtin:

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]