Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье объясняется, как JSONField Django работает с SQL Server через модуль mssql-django, включая поддерживаемые операции поиска и ограничения.
Необходимые условия
- SQL Server 2016 или более поздней версии (необходимы функции JSON)
-
mssql-django1.2 или более поздней версии
Сопоставление JSONField с SQL Server
В Django JSONField соответствует nvarchar(max) с ограничением проверки JSON в SQL Server. Серверная часть использует встроенные JSON-функции SQL Server (JSON_VALUE, JSON_QUERY, ISJSON) для реализации поиска и запросов.
Определение модели с помощью JSONField
Добавьте следующую модель в myapp/models.py. В примерах в этой статье используется Item модель, поэтому они не конфликтуют с моделью Product из краткого руководства по 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)
Создайте и примените миграцию, чтобы базовая таблица существовала в SQL Server:
python manage.py makemigrations myapp
python manage.py migrate myapp
Хранение и получение данных JSON
Откройте оболочку Django с помощью команды python manage.py shell. В командной строке >>> импортируйте модель:
from myapp.models import Item
Создайте запись с данными JSON:
item = Item.objects.create(
name="Widget",
metadata={"color": "blue", "weight": 1.5, "dimensions": {"height": 10, "width": 5}},
tags=["sale", "new"],
)
Получение записей и доступ к значениям JSON:
item = Item.objects.get(name="Widget")
print(item.metadata["color"]) # "blue"
print(item.tags) # ["sale", "new"]
Поддерживаемые запросы поиска
mssql-django бэкенд поддерживает следующие операции поиска для JSONField:
Поиск ключей и индексов
Доступ к вложенным значениям JSON с помощью синтаксиса двойного подчеркивания Django:
# Filter by nested key value
Item.objects.filter(metadata__color="blue").values()
# Access nested objects
Item.objects.filter(metadata__dimensions__height=10).values()
содержит
Note
Поиск contains не поддерживается в серверной части mssql-django. Используйте has_key с поиском по пути ключа в качестве альтернативы:
# Instead of: Item.objects.filter(metadata__contains={"color": "blue"})
# Use key-path lookup:
Item.objects.filter(metadata__color="blue").values()
has_key
Проверьте, существует ли определенный ключ:
Item.objects.filter(metadata__has_key="color").values()
has_keys
Проверьте, существуют ли все указанные ключи:
Item.objects.filter(metadata__has_keys=["color", "weight"]).values()
has_any_keys
Проверьте, существуют ли какие-либо из указанных ключей:
Item.objects.filter(metadata__has_any_keys=["color", "size"]).values()
Isnull
Операция isnullпоиска имеет особенности при работе с 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
На стороне mssql-django, если ключ существует, но имеет значение JSON null, has_key возвращает пустой QuerySet. Это отличается от PostgreSQL, где has_key возвращается True независимо от значения. Оператор поиска isnull=True возвращает объекты, в которых ключ отсутствует, и объекты, в которых значение равно null.
точное соответствие с None
Поиск exact не поддерживает значения None. Следующий запрос возвращает пустой набор запросов:
# Returns empty QuerySet - use isnull lookup instead
Item.objects.filter(metadata__color=None).values()
Вместо этого используйте isnull для поиска значений NULL.
Limitations
-
Массовые обновления с помощью JSONField: некоторые пограничные случаи существуют при использовании
bulk_updateсо значениями JSONField, особенно в Django 5.2 и более поздних версиях. Дополнительные сведения см. в разделе "Ограничения" и неподдерживаемые функции в mssql-django. - ВЫРАЖЕНИЯ CASE WHEN: В Django 5.2 и более поздних версиях некоторые операции JSONField внутри выражений CASE WHEN могут привести к непредвиденным результатам.
-
exact с None: используйте
isnullвместоexact, чтобы фильтровать значения JSON со значением null. -
has_key со значениями NULL:
has_keyвозвращает пустой QuerySet для ключей, которые существуют, но имеют значениеnull. -
Символы литеральных кавычек в строковых значениях JSON: подстановки равенства в строковых значениях JSON, содержащих литеральные
"символы (например,metadata={"description": '"quoted"'}), могут не соответствовать сохраненной строке. Значения, содержащие символы кавычек, сохраняются правильно, но их не всегда удаётся надёжно получить при поиске по полям.