【问题标题】:Django query to Sum the lengths of ArrayFieldsDjango 查询求和 ArrayFields 的长度
【发布时间】:2017-12-24 03:32:25
【问题描述】:

我有这个模型:

class Interaction(models.Model):
    user = models.ForeignKey(User)
    codes = ArrayField(models.CharField(choices=CODE_CHOICES))

我正试图弄清楚如何在 Django 中执行与此 SQL 查询等效的操作:

select user_id, sum(cardinality(codes)) from interaction group by user_id;
  • 我试过extra(select={codes_len':'cardinality(codes)'}),但是你 不能在extra 字段上使用annotateaggregate
  • 我试过annotate(Sum("cardinality('codes')")),但是 cardinality('codes') 不是模型上的字段。
  • 我研究了编写一个自定义聚合字段,它结合了Sumcardinality,但看起来……很脆弱。
  • 我在文档中发现 __lenArrayField,但不在上下文中 annotate(Sum('codes__len'))
  • 我排除了原始 SQL,因为有很多 WHERE 语句(此处省略)使得该查询难以手动重构。

此时我想我别无选择,只能在模型中添加一个字段,即codes 字段的长度并与save() 混淆以保持同步。

真的没有别的办法了吗?我错过了什么吗?

【问题讨论】:

    标签: python django django-queryset django-aggregation django-annotate


    【解决方案1】:

    事实证明,自定义聚合函数是要走的路!

    以下内容:

    from django.db.models import Aggregate
    
    class SumCardinality(Aggregate):
        template = 'SUM(CARDINALITY(%(expressions)s))'
    

    查询很简单:

    Interaction.objects().filter(xxx).\
        values('user_id').annotate(codes_len=SumCardinality('codes'))
    

    【讨论】:

      猜你喜欢
      • 2018-07-30
      • 2016-03-23
      • 1970-01-01
      • 2014-06-14
      • 1970-01-01
      • 2012-05-28
      • 1970-01-01
      • 1970-01-01
      • 2014-04-30
      相关资源
      最近更新 更多