Django에서 저장 프로시저 호출

이 문서에서는 백 엔드를 사용하여 mssql-django Django 애플리케이션에서 SQL Server 저장 프로시저를 만들고 호출하는 방법을 설명합니다.

마이그레이션에서 저장 프로시저 만들기

Django 마이그레이션 워크플로의 일부로 저장 프로시저를 만드는 데 사용합니다 migrations.RunSQL .

from django.db import migrations

class Migration(migrations.Migration):

    dependencies = [
        ("myapp", "0001_initial"),
    ]

    operations = [
        migrations.RunSQL(
            sql="""
                CREATE PROCEDURE GetProductsByCategory
                    @CategoryName NVARCHAR(100)
                AS
                BEGIN
                    SET NOCOUNT ON;
                    SELECT id, name, price
                    FROM myapp_product
                    WHERE category = @CategoryName;
                END;
            """,
            reverse_sql="DROP PROCEDURE IF EXISTS GetProductsByCategory;",
        ),
    ]

마이그레이션을 적용합니다.

python manage.py migrate

저장 프로시저 호출

Django를 connection.cursor() 사용하여 원시 SQL을 사용하여 저장 프로시저를 호출합니다.

from django.db import connection

def get_products_by_category(category_name):
    with connection.cursor() as cursor:
        cursor.execute("EXECUTE GetProductsByCategory @CategoryName = %s;", [category_name])
        results = cursor.fetchall()
    return results

여러 매개 변수를 사용하여 저장 프로시저 호출

여러 매개 변수를 목록으로 전달합니다.

from django.db import connection

def search_products(category_name, min_price):
    with connection.cursor() as cursor:
        cursor.execute(
            "EXECUTE SearchProducts @CategoryName = %s, @MinPrice = %s;",
            [category_name, min_price],
        )
        results = cursor.fetchall()
    return results

결과에서 열 이름 읽기

cursor.description에서 열 이름에 액세스:

from django.db import connection

def get_products_as_dicts(category_name):
    with connection.cursor() as cursor:
        cursor.execute("EXECUTE GetProductsByCategory @CategoryName = %s;", [category_name])
        columns = [col[0] for col in cursor.description]
        results = [dict(zip(columns, row)) for row in cursor.fetchall()]
    return results

여러 결과 집합 처리

일부 저장 프로시저는 여러 결과 집합을 반환합니다. 둘 사이를 이동하려면 cursor.nextset()를 사용하세요:

from django.db import connection

def get_dashboard_data():
    with connection.cursor() as cursor:
        cursor.execute("EXECUTE GetDashboardData;")

        # First result set
        products = cursor.fetchall()

        # Move to second result set
        cursor.nextset()
        categories = cursor.fetchall()

    return products, categories

Django 매니저로 감싸기

더 깨끗한 코드를 위해 사용자 지정 관리자에 저장 프로시저 호출을 캡슐화합니다.

from django.db import connection, models

class ProductManager(models.Manager):
    def by_category(self, category_name):
        with connection.cursor() as cursor:
            cursor.execute(
                "EXECUTE GetProductsByCategory @CategoryName = %s;",
                [category_name],
            )
            columns = [col[0] for col in cursor.description]
            return [dict(zip(columns, row)) for row in cursor.fetchall()]

class Product(models.Model):
    name = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    category = models.CharField(max_length=100)

    objects = ProductManager()

사용법:

products = Product.objects.by_category("Electronics")