使用 Django 的 JSONField 进行注解和常规查找有什么区别?

What is the difference between annotations and regular lookups using Django's JSONField?

您可以查询Django 的JSONField,可以直接查找,也​​可以使用注解。现在我意识到如果你注释一个字段,你可以进行各种复杂的查询,但是对于非常基本的查询,哪种方法实际上是首选方法?

示例:假设我有这样的模型

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')

那么到底有什么区别呢?如果我可以进行基本查询,为什么还需要注释?当然,前提是我不打算进行复杂的查询。

对于可以使用 ORM 语法的查询,没有任何理由使用原始 SQL。对于熟悉 SQL 但对 Django 的 ORM 经验较少的人来说,RawSQL 可能比 ORM 提供更容易获得特定结果的途径,它有自己的学习曲线。

可能会有更复杂的查询,其中 ORM or where it not 会为您提供所需的确切 SQL 查询。正是在这些情况下,RawSQL 派上了用场——尽管 ORM 在每次迭代中都变得更加完整,

  • Cast(自 1.10 起),
  • Window 函数(自 2.0 起),
  • 不断增长的数据库函数包装器
  • 使用 Func expressions(自 1.8 起)等为数据库函数定义自定义包装器的能力

它们是可以互换的,所以这是品味问题。我认为 Document.objects.filter(data__name='Foo') 更好,因为:

  • 更容易阅读
  • 将来,MariaDB 或 MySql 可以支持 JSON 个字段,您的代码将能够 运行 在 PostgreSQL 和 MariaDB 上。
  • 一般情况下不要使用 RawSQL。您可以在您的应用程序中创建安全漏洞。