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 2017 veya sonraki sürümler, Azure SQL Veritabanı veya Fabric'teki SQL veritabanı
  • mssql-django 1.2 veya üzeri

SQL veritabanı oluşturma

Aşağıdaki platformlardan birinde bir SQL veritabanı oluşturun veya bağlanın:

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 isnull yerine exact 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.