1

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

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

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

然后我使用以下命令存储一个对象:

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

现在,我想要的查询是最基本的:查找所有文档 where data__nameis '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')

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

4

2 回答 2

2

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

可能有更复杂的查询,其中 ORM遇到问题,或者它可能 无法为您提供所需的确切 SQL 查询。在这些情况下,RawSQL 就派上用场了——尽管 ORM 在每次迭代中都变得更加完善,

  • 演员表(自 1.10 起),
  • 窗口函数(自 2.0 起),
  • 不断增长的数据库函数包装器数组
  • 使用Func 表达式(自 1.8 起)等为数据库函数定义自定义包装器的能力。
于 2019-03-17T19:58:24.370 回答
1

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

  • 更容易阅读
  • 将来,MariaDB 或 MySql 可以支持 JSON 字段,您的代码将能够在 PostgreSQL 和 MariaDB 上运行。
  • 不要将 RawSQL 用作一般规则。您可以在您的应用程序中创建安全漏洞。
于 2019-03-17T20:03:59.517 回答