이 문서에서는 Django의 JSONField가 mssql-django 백엔드를 통해 SQL Server와 함께 작동하는 방식과 지원되는 조회 기능 및 제한 사항을 설명합니다.
사전 요구 사항
- SQL Server 2016 이상(JSON 함수 필요)
-
mssql-django1.2 이상
JSONField가 SQL Server 매핑하는 방법
Django의 JSONField는 SQL Server에서 JSON CHECK 제약 조건이 있는 nvarchar(max)에 매핑됩니다. 백 엔드는 SQL Server 기본 제공 JSON 함수(JSON_VALUE, JSON_QUERY, ISJSON)를 사용하여 조회 및 쿼리를 구현합니다.
JSONField를 사용하여 모델 정의
에 다음 모델을 추가합니다 myapp/models.py. 이 문서의 예제에서는 Item의 모델과 Product 충돌하지 않도록 모델을 사용합니다.
from django.db import models
class Item(models.Model):
name = models.CharField(max_length=100)
metadata = models.JSONField(default=dict)
tags = models.JSONField(null=True, blank=True)
기본 테이블이 SQL Server 있도록 마이그레이션을 생성하고 적용합니다.
python manage.py makemigrations myapp
python manage.py migrate myapp
JSON 데이터 저장 및 검색
python manage.py shell로 Django 셸을 엽니다. 프롬프트에서 >>> 모델을 가져옵니다.
from myapp.models import Item
JSON 데이터를 사용하여 레코드를 만듭니다.
item = Item.objects.create(
name="Widget",
metadata={"color": "blue", "weight": 1.5, "dimensions": {"height": 10, "width": 5}},
tags=["sale", "new"],
)
레코드를 검색하고 JSON 값에 액세스합니다.
item = Item.objects.get(name="Widget")
print(item.metadata["color"]) # "blue"
print(item.tags) # ["sale", "new"]
지원되는 조회 기능
백 엔드는 mssql-django 다음 JSONField 조회를 지원합니다.
키/인덱스 조회
Django의 이중 밑줄 구문을 사용하여 중첩된 JSON 값에 액세스합니다.
# Filter by nested key value
Item.objects.filter(metadata__color="blue").values()
# Access nested objects
Item.objects.filter(metadata__dimensions__height=10).values()
contains
메모
contains 조회는 mssql-django 백엔드에서 지원되지 않습니다. 대안으로 has_key를 키 경로 조회와 함께 사용하세요.
# Instead of: Item.objects.filter(metadata__contains={"color": "blue"})
# Use key-path lookup:
Item.objects.filter(metadata__color="blue").values()
has_key
특정 키가 있는지 확인합니다.
Item.objects.filter(metadata__has_key="color").values()
has_keys
지정된 모든 키가 있는지 확인합니다.
Item.objects.filter(metadata__has_keys=["color", "weight"]).values()
has_any_keys
지정된 키가 있는지 확인합니다.
Item.objects.filter(metadata__has_any_keys=["color", "size"]).values()
isnull
isnull 조회는 SQL Server에서 특정 동작이 있습니다:
# Returns objects where the key doesn't exist AND keys with None value
Item.objects.filter(metadata__color__isnull=True).values()
# Returns objects where the key exists and has a non-null value
Item.objects.filter(metadata__color__isnull=False).values()
메모
mssql-django 백엔드에서는 키가 존재하지만 그 값이 JSON null인 경우 has_key는 빈 QuerySet을 반환합니다. 이는 PostgreSQL과는 다릅니다. PostgreSQL에서는 값에 관계없이 has_key가 True를 반환합니다. 조회는 isnull=True 키가 없는 개체와 값 null이 있는 개체를 반환합니다.
값이 '없음'일 때 정확히 일치
exact 조회는 None 값을 지원하지 않습니다. 다음 쿼리는 빈 QuerySet을 반환합니다.
# Returns empty QuerySet - use isnull lookup instead
Item.objects.filter(metadata__color=None).values()
대신 isnull 조회를 사용하여 null 값을 찾으세요.
Limitations
-
JSONField를 사용한 대량 업데이트: JSONField 값과 함께
bulk_update를 사용할 때, 특히 Django 5.2 이상 버전에서는 몇 가지 예외적인 경우가 있습니다. 자세한 내용은 mssql-django의 제한 사항 및 지원되지 않는 기능을 참조하세요. - CASE WHEN 식: Django 5.2 이상 버전에서는 CASE WHEN 식 내의 특정 JSONField 작업이 예기치 않은 결과를 생성할 수 있습니다.
-
exact with None: null JSON 값을 필터링하려면
exact대신isnull를 사용하세요. -
null 값인 경우의 has_key:
has_key키는 존재하지만 그 값이null인 경우 빈 QuerySet을 반환합니다. -
JSON 문자열 값의 리터럴 따옴표 문자: 리터럴
"문자가 포함된 JSON 문자열 값에 대한 동등성 조회는 저장된 행과 일치하지 않을 수 있습니다(예:metadata={"description": '"quoted"'}). 따옴표 문자가 포함된 값은 올바르게 저장되지만 필드 조회를 통해 안정적으로 검색할 수 없습니다.