В чем разница между аннотациями и обычными поисками с использованием JSONField от Django? - PullRequest
1 голос
/ 17 марта 2019

Вы можете запросить JSONField в Django, либо с помощью прямого поиска, либо с помощью аннотаций.Теперь я понимаю, что если вы аннотируете поле, вы можете выполнять всевозможные сложные запросы, но для самого базового запроса, какой из них на самом деле является предпочтительным методом?

Пример: допустим, у меня есть модель, подобная

class Document(models.Model):
    data = JSONField()

И затем я сохраняю объект, используя следующую команду:

>>> Document.objects.create(data={'name': 'Foo', 'age': 24})

Теперь запрос, который я хочу, является самым основным: Найти все документы, где data__name равно 'Foo'.Я могу сделать это двумя способами, один с использованием аннотации, а другой без, вот так:

>>> from django.db.models.expressions import RawSQL
>>> Document.objects.filter(data__name='Foo')
>>> Document.objects.annotate(name = RawSQL("(data->>'name')::text", [])).filter(name='Foo')

Так в чем же разница?И если я могу делать базовые запросы, зачем мне аннотировать?При условии, конечно, я не собираюсь делать сложные запросы.

Ответы [ 2 ]

1 голос
/ 17 марта 2019

Нет никакой причины использовать необработанный SQL для запросов, где вы можете использовать синтаксис ORM. Для тех, кто знаком с SQL, но менее знаком с ORM в Django, RawSQL может обеспечить более простой путь к определенному результату, чем ORM, который имеет свою собственную кривую обучения.

Могут быть более сложные запросы, когда ORM сталкивается с проблемами или когда может , а не , дать вам точный запрос SQL, который вам нужен. Именно в этих случаях пригодится RawSQL - хотя ORM становится все более полным с каждой итерацией, с

  • В ролях (с 1.10),
  • Окно Функции (начиная с 2.0),
  • постоянно растущий массив упаковщиков для функций базы данных
  • возможность определять пользовательские оболочки для функций базы данных с выражениями Func (начиная с 1.8) и т. Д.
0 голосов
/ 17 марта 2019

Они взаимозаменяемы, так что дело вкуса. Я думаю Document.objects.filter(data__name='Foo') лучше, потому что:

  • Проще читать
  • В будущем MariaDB или MySql могут поддерживать поля JSON, и ваш код сможет работать как на PostgreSQL, так и на MariaDB.
  • Не используйте RawSQL как общее правило. Вы можете создать дыры в безопасности в своем приложении.
...