В чем разница между аннотациями и обычным поиском с использованием JSONField Django?

Вы можете запросить 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')

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


person darkhorse    schedule 17.03.2019    source источник


Ответы (2)


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

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

  • Cast (начиная с версии 1.10),
  • Оконные функции (начиная с версии 2.0),
  • постоянно растущий набор оболочек для функций базы данных
  • возможность определять собственные оболочки для функций базы данных с Func-выражениями (начиная с 1.8) и т. д.
person Endre Both    schedule 17.03.2019
comment
Это не отвечает на вопрос, и во многих случаях есть абсолютно все основания использовать RawSQL. - person darkhorse; 17.03.2019
comment
Я попытался ответить в первом предложении, извините, если я выразился неясно: нет никакой причины использовать RawSQL в вашем примере. Что касается необходимости использования RawSQL в более сложных случаях, я признал это во втором абзаце. - person Endre Both; 17.03.2019
comment
Я думаю, достаточно справедливо, однако я надеялся на некоторые различия более низкого уровня между двумя методами запроса. - person darkhorse; 17.03.2019
comment
Вы можете легко проверить «нижний уровень» с помощью запросить у Django SQL для набора запросов или с помощью отображение последнего выполненного SQL-запроса. В вашем примере между двумя запросами есть лишь незначительные синтаксические различия. - person Endre Both; 17.03.2019

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

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