SQL Server ile JSONField

Bu makalede, desteklenen aramalar ve sınırlamalar dahil olmak üzere Django'nun JSONField arka uç üzerinden mssql-django SQL Server ile nasıl çalıştığı açıklanmaktadır.

Prerequisites

  • SQL Server 2016 veya üzeri (JSON işlevleri gereklidir)
  • mssql-django 1.2 veya üzeri

JSONField’ın SQL Server ile eşlenmesi

Django'daki JSONField, SQL Server'da JSON denetim kısıtlamasına sahip nvarchar(max) ile eşlenir. Arka uç, aramalar ve sorgular uygulamak için SQL Server yerleşik JSON işlevlerini (JSON_VALUE, JSON_QUERY, ISJSON) kullanır.

JSONField ile model tanımlama

Aşağıdaki modeli öğesine myapp/models.pyekleyin. Bu makaledeki örnekler, ItemProduct modeliyle çakışmaması için bir model kullanır.

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)

Temeldeki tablonun SQL Server’da mevcut olması için geçişi oluşturun ve uygulayın:

python manage.py makemigrations myapp
python manage.py migrate myapp

JSON verilerini depolama ve alma

ile python manage.py shellDjango kabuğunu açın. >>> komut isteminde modeli içe aktarın:

from myapp.models import Item

JSON verileriyle kayıt oluşturma:

item = Item.objects.create(
    name="Widget",
    metadata={"color": "blue", "weight": 1.5, "dimensions": {"height": 10, "width": 5}},
    tags=["sale", "new"],
)

Kaydı alın ve JSON değerlerine erişin:

item = Item.objects.get(name="Widget")
print(item.metadata["color"])  # "blue"
print(item.tags)  # ["sale", "new"]

Desteklenen aramalar

mssql-django Arka uç aşağıdaki JSONField aramalarını destekler:

Anahtar/dizin aramaları

Django'nun çift alt çizgi söz dizimini kullanarak iç içe JSON değerlerine erişin:

# Filter by nested key value
Item.objects.filter(metadata__color="blue").values()

# Access nested objects
Item.objects.filter(metadata__dimensions__height=10).values()

contains

Note

contains arama işlemi, mssql-django arka ucunda desteklenmez. Alternatif olarak, has_key öğesini anahtar yolu aramalarıyla kullanın:

# Instead of: Item.objects.filter(metadata__contains={"color": "blue"})
# Use key-path lookup:
Item.objects.filter(metadata__color="blue").values()

has_key

Belirli bir anahtarın mevcut olup olmadığını denetleyin:

Item.objects.filter(metadata__has_key="color").values()

has_keys

Belirtilen tüm anahtarların mevcut olup olmadığını denetleyin:

Item.objects.filter(metadata__has_keys=["color", "weight"]).values()

has_any_keys

Belirtilen anahtarlardan herhangi birinin mevcut olup olmadığını denetleyin:

Item.objects.filter(metadata__has_any_keys=["color", "size"]).values()

isnull

isnull araması, SQL Server ile belirli bir davranış sergiler:

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

Note

mssql-django arka ucunda, bir anahtar varsa ancak JSON null değerine sahipse, has_key boş bir QuerySet döndürür. Bu, has_key öğesinin değerden bağımsız olarak True döndürdüğü PostgreSQL'den farklıdır. Arama, isnull=True anahtarın mevcut olmadığı nesneleri ve değerin nullolduğu nesneleri döndürür.

Hiçbiriyle tam olarak eşleşen

exact arama işlemi, None değerlerini desteklemez. Aşağıdaki sorgu boş bir QuerySet döndürür:

# Returns empty QuerySet - use isnull lookup instead
Item.objects.filter(metadata__color=None).values()

isnull Null değerleri bulmak için bunun yerine aramayı kullanın.

Limitations

  • JSONField ile toplu güncelleştirmeler: Özellikle Django 5.2 ve sonraki sürümlerde JSONField değerleriyle kullanıldığında bulk_update bazı uç durumlar vardır. Daha fazla bilgi için bkz. mssql-django'da sınırlamalar ve desteklenmeyen özellikler.
  • CASE WHEN ifadeleri: Django 5.2 ve sonraki sürümlerde CASE WHEN ifadeleri içindeki bazı JSONField işlemleri beklenmeyen sonuçlara neden olabilir.
  • None ile exact: null JSON değerlerini filtrelemek için exact yerine isnull kullanın.
  • null değerlerle has_key: has_key mevcut olup değeri null olan anahtarlar için boş bir QuerySet döndürür.
  • JSON dize değerlerinde gerçek tırnak karakterleri: Gerçek " karakterleri içeren JSON dize değerlerine yönelik eşitlik aramaları (örneğin, metadata={"description": '"quoted"'}) depolanan satırla eşleşmeyebilir. Tırnak karakterleri içeren değerler doğru şekilde depolanır, ancak alan aramaları aracılığıyla güvenilir biçimde alınamaz.