JSONField és SQL Server

Ez a cikk bemutatja, hogyan működik együtt a Django JSONField az SQL Serverrel a mssql-django backenddel, beleértve a támogatott lekérdezéseket és a korlátozásokat.

Prerequisites

  • 2016-os vagy újabb SQL Server (JSON-függvények szükségesek)
  • mssql-django 1.2 vagy újabb

A JSONField leképezése az SQL Serverre

A Django-beli JSONField leképezése az SQL Serverben nvarchar(max) típusra történik, JSON-ellenőrzési megszorítással. A háttérrendszer SQL Server beépített JSON-függvényeit (JSON_VALUE, JSON_QUERY, ISJSON) használja a keresések és lekérdezések megvalósításához.

Modell definiálása a JSONField használatával

Adja hozzá a következő modellt a következőhöz myapp/models.py: A cikkben szereplő példák egy Item modellt használnak, hogy ne ütközhessenek a ProductDjango rövid útmutatójában szereplő modellel.

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)

Hozza létre és alkalmazza a migrációt, hogy a mögöttes tábla létezzen az SQL Serverben:

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

JSON-adatok tárolása és lekérése

Indítsa el a Django parancsértelmezőjét a következő paranccsal: python manage.py shell. A >>> parancssori promptnál importálja a modellt:

from myapp.models import Item

Rekord létrehozása JSON-adatokkal:

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

A rekord lekérése és a JSON-értékek elérése:

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

Támogatott keresések

A mssql-django háttérrendszer a következő JSONField-kereséseket támogatja:

Kulcs-/indexkeresések

A Beágyazott JSON-értékek elérése Django dupla aláhúzásos szintaxisával:

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

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

tartalmaz

Note

A contains keresés nem támogatott a mssql-django háttérrendszeren. Alternatívaként használja a(z) has_key elemet kulcsútvonalas keresésekkel:

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

has_key

Ellenőrizze, hogy létezik-e egy adott kulcs:

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

has_keys

Ellenőrizze, hogy az összes megadott kulcs létezik-e:

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

has_any_keys

Ellenőrizze, hogy léteznek-e a megadott kulcsok:

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

isnull

A isnull keresés sajátos viselkedést mutat a SQL Server esetében:

# 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 A háttérrendszeren, ha egy kulcs létezik, de JSON-értékkel null rendelkezik, has_key egy üres QuerySetet ad vissza. Ez különbözik a PostgreSQL-től, ahol has_key az értéktől függetlenül ad vissza True . A isnull=True keresés olyan objektumokat ad vissza, ahol a kulcs nem létezik, és azokat az objektumokat, ahol az érték szerepel null.

pontos és Nincs

A exact keresés nem támogatja az None értékeket. A következő lekérdezés egy üres QuerySetet ad vissza:

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

A null értékek kereséséhez használja inkább a isnull keresést.

Limitations

  • Tömeges frissítések JSONFielddel: A bulk_update JSONField-értékekkel való használatakor előfordul néhány szélső eset, különösen a Django 5.2-es és újabb verzióiban. További információ: Az mssql-django korlátozásai és nem támogatott funkciói.
  • CASE WHEN expressions: A Django 5.2 és újabb verzióiban bizonyos JSONField-műveletek a CASE IF kifejezésen belül váratlan eredményeket eredményezhetnek.
  • egyezés a None értékkel: A null JSON-értékek szűréséhez exact helyett használja ezt: isnull.
  • has_key null értékekkel: a has_key üres QuerySetet ad vissza azokhoz a kulcsokhoz, amelyek léteznek, de null értékűek.
  • Literális idézőjelek JSON-sztringértékekben: A konstans " karaktereket (például metadata={"description": '"quoted"'}) tartalmazó JSON-sztringértékek egyenlőségi keresései nem feltétlenül egyeznek a tárolt sorokkal. Az idézőjeleket tartalmazó értékek helyesen tárolódnak, de a mezőkereséseken keresztül nem olvashatók le megbízhatóan.