【问题标题】:Querying jsonb fields in PostgreSQL using Django: IN vs. CONTAINS使用 Django 在 PostgreSQL 中查询 jsonb 字段:IN vs. CONTAINS
【发布时间】:2021-01-29 05:16:21
【问题描述】:

当 Django 的 ORM 使用 CONTAINS 将 JSONB 查询转换为 SQL 时,它使用 ->> 操作符,它工作正常。

例如:

"metadata__my_field_name__icontains": "1234"

运行方式:

...WHERE UPPER(("table"."metadata" ->> my_field_name)::text) LIKE UPPER(%1234%)...

效果很好。

但是,当我尝试使用 IN 运算符和值列表时:

"metadata__my_field_name__in": my_list

生成的 SQL 使用 JSON,而不是像这样的 JSONB 运算符:

..."table"."metadata" -> 'my_id') IN ('1234', '3456', ...

在运行时,它不会返回预期值(空集)。相反,如果我使用 JSONB 运算符 ->> 手动运行相同的查询,则会返回预期值。另请注意,ID 将转换为字符串。我正在运行 Django 2.2。

有没有办法强制 Django 使用 JSONB 运算符?

【问题讨论】:

    标签: python django postgresql jsonb


    【解决方案1】:

    好的,结果证明使用自定义查找是可行的。像这样:

    from django.contrib.postgres.fields.jsonb import (
        KeyTransform, KeyTransformTextLookupMixin
    )
    from django.db.models.lookups import In
    
    @KeyTransform.register_lookup
    class KeyTransformIdIn(KeyTransformTextLookupMixin, In):
        lookup_name = 'id_in'
        prepare_rhs = False
    
        def as_sql(self, compiler, connection):
            lhs_sql, lhs_params = self.process_lhs(compiler, connection)
            rhs_sql, rhs_params = self.process_rhs(compiler, connection)
            sql = "%s::int IN %s" % (lhs_sql, rhs_sql)
            params = [*lhs_params, *rhs_params]
            return sql, params
    

    来自 KeyTransformTextLookupMixin 源code comments

    """
    Mixin for combining with a lookup expecting a text lhs from a JSONField
    key lookup. Make use of the ->> operator instead of casting key values to
    text and performing the lookup on the resulting representation.
    """
    

    内置的 django.db.models.lookups.In 类提供了正确的右侧处理来将整数列表转换为正确的 PostgreSQL。

    ...WHERE ("table"."metadata" ->> 'my_id')::int IN (1234, 3456...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-25
      • 2017-06-27
      • 2015-04-13
      相关资源
      最近更新 更多