【问题标题】:What is the difference between annotations and regular lookups using Django's JSONField?使用 Django 的 JSONField 进行注释和常规查找有什么区别?
【发布时间】:2019-03-17 19:21:05
【问题描述】:

您可以通过直接查找或使用注释来查询 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')

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

【问题讨论】:

    标签: django django-postgresql django-jsonfield


    【解决方案1】:

    没有任何理由在可以使用 ORM 语法的查询中使用原始 SQL。对于精通 SQL 但对 Django 的 ORM 经验较少的人来说,RawSQL 可能比 ORM 提供更简单的路径,因为 ORM 有自己的学习曲线。

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

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

    【讨论】:

    • 这并不能回答问题,在很多情况下使用RawSQL 是绝对有理由的。
    • 我试图在第一句话中回答,如果我不清楚,很抱歉:没有任何理由在您的示例中使用 RawSQL。至于在更复杂的情况下使用 RawSQL 的必要性,我在第二段中确实承认了这一点。
    • 我想这很公平,但是我希望这两种查询方法之间存在一些较低级别的差异。
    • 您可以通过asking Django for the SQL of a querysetdisplaying the last executed SQL query 轻松检查“下层”。在您的示例中,两个查询之间只有很小的语法差异。
    【解决方案2】:

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

    • 更容易阅读
    • 未来,MariaDB 或 MySql 可以支持 JSON 字段,您的代码将能够在 PostgreSQL 和 MariaDB 上运行。
    • 一般规则不要使用 RawSQL。您可以在应用中制造安全漏洞。

    【讨论】:

      猜你喜欢
      • 2018-06-18
      • 2022-01-21
      • 2012-11-10
      • 2019-01-25
      • 1970-01-01
      • 2018-01-14
      • 2018-11-23
      • 2013-07-07
      • 2016-09-16
      相关资源
      最近更新 更多