JSONField mit SQL Server

In diesem Artikel wird erläutert, wie Djangos JSONField über das mssql-django Backend mit SQL Server zusammenarbeitet, einschließlich unterstützter Abfragen und Einschränkungen.

Voraussetzungen

  • SQL Server 2016 oder höher (JSON-Funktionen sind erforderlich)
  • mssql-django 1.2 oder höher

Zuordnung von JSONField zu SQL Server

Djangos JSONField wird in SQL Server nvarchar(max) mit einer JSON-Prüfbedingung zugeordnet. Das Back-End verwendet die integrierten JSON-Funktionen von SQL Server (JSON_VALUE, JSON_QUERY), ISJSONum Nachschlagevorgänge und Abfragen zu implementieren.

Definieren eines Modells mit JSONField

Fügen Sie das folgende Modell zu myapp/models.py. Die Beispiele in diesem Artikel verwenden ein Item Modell, damit sie nicht mit dem Product Modell aus der Django-Schnellstartanleitung in Konflikt stehen.

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)

Generieren sie die Migration, und wenden Sie sie an, sodass die zugrunde liegende Tabelle in SQL Server vorhanden ist:

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

Speichern und Abrufen von JSON-Daten

Öffnen Sie die Django-Shell mit python manage.py shell. Importieren Sie an der >>> Eingabeaufforderung das Modell:

from myapp.models import Item

Erstellen eines Datensatzes mit JSON-Daten:

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

Den Datensatz abrufen und auf JSON-Werte zugreifen:

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

Unterstützte Suchvorgänge

Das mssql-django Back-End unterstützt die folgenden JSONField-Nachschlagevorgänge:

Schlüssel-/Index-Nachschlagevorgänge

Greifen Sie auf geschachtelte JSON-Werte mithilfe der Syntax mit doppeltem Unterstrich von Django zu:

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

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

enthält

Note

Die contains Suche wird im mssql-django Back-End nicht unterstützt. Verwenden Sie has_key alternativ für Schlüsselpfadsuchen:

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

has_key

Überprüfen Sie, ob ein bestimmter Schlüssel vorhanden ist:

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

has_keys

Überprüfen Sie, ob alle angegebenen Schlüssel vorhanden sind:

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

has_any_keys

Überprüfen Sie, ob eine der angegebenen Schlüssel vorhanden ist:

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

isnull

Die isnull Suche weist ein bestimmtes Verhalten mit SQL Server auf:

# 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

Wenn im mssql-django Backend ein Schlüssel vorhanden ist, aber einen JSON-null-Wert hat, gibt has_key ein leeres QuerySet zurück. Dies unterscheidet sich von PostgreSQL, bei dem has_key unabhängig vom Wert True zurückgibt. Die isnull=True Suche gibt Objekte zurück, bei denen der Schlüssel nicht vorhanden ist, und Objekte, in denen sich der Wert befindet null.

genau mit „None“

Die exact Suche unterstützt keine None Werte. Die folgende Abfrage gibt ein leeres QuerySet zurück:

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

Verwenden Sie stattdessen die isnull Suche, um Nullwerte zu finden.

Einschränkungen

  • Massenaktualisierungen mit JSONField: Bei der Verwendung von bulk_update mit JSONField-Werten treten einige Randfälle auf, insbesondere in Django 5.2 und neueren Versionen. Weitere Informationen finden Sie unter Einschränkungen und nicht unterstützte Features in mssql-django.
  • CASE WHEN-Ausdrücke: Bei Django 5.2 und höheren Versionen können bestimmte JSONField-Vorgänge innerhalb von CASE WHEN-Ausdrücken zu unerwarteten Ergebnissen führen.
  • exact with None: Verwenden Sie isnull anstelle von exact, um nach JSON-Nullwerten zu filtern.
  • has_key mit NULL-Werten: has_key Gibt ein leeres QuerySet für Schlüssel zurück, die vorhanden sind, aber einen null Wert aufweisen.
  • Anführungszeichen als Literal in JSON-Zeichenfolgenwerten: Gleichheitsabfragen für JSON-Zeichenfolgenwerte, die das Zeichen " als Literal enthalten (z. B. metadata={"description": '"quoted"'}), stimmen möglicherweise nicht mit der gespeicherten Zeile überein. Werte, die Anführungszeichen enthalten, werden korrekt gespeichert, können aber nicht zuverlässig über Feldsuchvorgänge abgerufen werden.