JSONField pro SQL Server

Tento článek vysvětluje, jak v Django funguje JSONField se serverem SQL Server prostřednictvím backendu mssql-django, včetně podporovaných vyhledávacích výrazů a omezení.

Prerequisites

  • SQL Server 2016 nebo novější (vyžadují se funkce JSON)
  • mssql-django 1.2 nebo novější

Jak se JSONField mapuje na SQL Server

Django JSONField mapuje na nvarchar(max) s omezením kontroly JSON v SQL Server. Back-end používá k implementaci vyhledávání a dotazů integrované funkce JSON (JSON_VALUE, JSON_QUERY, ISJSON) SQL Server.

Definování modelu pomocí JSONFieldu

Přidejte do souboru myapp/models.pynásledující model . Příklady v tomto článku používají Item model, takže nejsou v konfliktu s modelem Product z rychlého startu Django.

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)

Vygenerujte a použijte migraci, aby v SQL Server existovala podkladová tabulka:

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

Ukládání a načítání dat JSON

Otevřete prostředí Django pomocí python manage.py shell. Na výzvě >>> importujte model:

from myapp.models import Item

Vytvoření záznamu s daty JSON:

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

Načtěte záznam a získejte přístup k hodnotám JSON:

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

Podporované vyhledávání

Back-end mssql-django podporuje následující vyhledávání JSONField:

Vyhledávání klíče nebo indexu

Přístup k vnořeným hodnotám JSON pomocí syntaxe dvojitého podtržítka Django:

# 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

Vyhledávání contains není na backendu mssql-django podporováno. Jako alternativu můžete použít has_key vyhledávání s klíčovou cestou:

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

has_key

Zkontrolujte, jestli existuje konkrétní klíč:

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

has_keys

Zkontrolujte, jestli existují všechny zadané klíče:

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

has_any_keys

Zkontrolujte, jestli existují některé ze zadaných klíčů:

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

isnull

Vyhledávání isnull má specifické chování s 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()

Note

Pokud v back-endu mssql-django existuje klíč, ale má hodnotu JSON null , has_key vrátí prázdnou sadu dotazů. To se liší od PostgreSQL, kde has_key se vrátí True bez ohledu na hodnotu. Vyhledávání isnull=True vrátí objekty, ve kterých klíč neexistuje, a objekty, kde je nullhodnota .

exact with None

Vyhledávání exact nepodporuje None hodnoty. Následující dotaz vrátí prázdnou sadu dotazů:

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

Použijte místo toho isnull k vyhledání hodnot null.

Limitations

  • Hromadné aktualizace s JSONField: Existují některé okrajové případy při použití bulk_update nad hodnotami JSONField, zejména v Django 5.2 a novějších verzích. Další informace naleznete v tématu Omezení a nepodporované funkce v mssql-django.
  • Výrazy CASE WHEN: V Django 5.2 a novějších verzích můžou určité operace JSONField uvnitř výrazů CASE WHEN způsobit neočekávané výsledky.
  • exact s None: K filtrování hodnot JSON null použijte isnull místo exact.
  • has_key s hodnotou null: has_key vrátí prázdný QuerySet pro klíče, které existují, ale mají hodnotu null.
  • Doslovné znaky uvozovek v řetězcových hodnotách JSON: Porovnání na rovnost u řetězcových hodnot JSON, které obsahují doslovné znaky " (například metadata={"description": '"quoted"'}), nemusí odpovídat uloženému záznamu. Hodnoty obsahující znaky uvozovek se ukládají správně, ale nedají se spolehlivě načíst prostřednictvím vyhledávání polí.