【问题标题】:How to annotate median value to django queryset如何将中值注释到 django 查询集
【发布时间】:2020-04-29 15:45:16
【问题描述】:

我有 2 个模型 Puzzle and Play。对于每场比赛,我都有一个评分。 我想在拼图查询集中注释所有相应播放的中值评分。

class Puzzle(models.Model):
    name = models.CharField(max_length=255)

class Play(models.Model):
    puzzle = models.ForeignKey(Puzzle, on_delete=models.CASCADE,related_name='plays')
    rating = models.IntegerField(default=-1)
    puzzle_completed = models.BooleanField(default=None, blank=False, null=False)

我会数数:

Puzzle.objects.annotate(nb_sucesses=Count('plays', filter = Q(plays__puzzle_completed=True), distinct = True),)

我希望以类似的方式获得中位数:

Puzzle.objects.annotate(rating_median=Median('plays__rating', filter = Q(plays__puzzle_completed=True), distinct = True),)

但是,显然由于我的 Django 开发环境数据库 (sqlite),我无法做到这一点。

根据我从以下信息https://mariadb.com/kb/en/median/ 推断,在我的生产环境(MariaDB)中,这种方法应该可以工作(但我还没有测试过)

我目前的理解(基于不同的互联网搜索)是我应该能够使用 Django Func() 函数来使用自定义 Median 函数 (following that model ?),如果在生产中调用 Median,或者更复杂sql 原始查询是否处于开发阶段(基于 on this one ?on this one?)。

但几个小时后,我必须承认我在这里超出了我的深度。

谁能帮我把这些点联系起来?

【问题讨论】:

标签: sql django sqlite mariadb django-annotate


【解决方案1】:

Django 中没有 Median 实现,因为它没有在 PostgreSQL 中实现。

您可以在 MariaDB 10.3.3+ 上运行 median 作为原始查询,或者在 Django 中为您的自定义需求编写一个 aggregate 函数,然后使用 ORM 转换为相同的查询

您绝对应该在生产和开发环境中使用相同的数据库类型,以尽量减少由于不同环境导致的错误(建议也使用像 docker 这样的工具)

【讨论】:

    【解决方案2】:

    关于在使用 PostgreSQL 时如何做到这一点,请参阅 我在Django & Postgres - percentile (median) and group by 的回答。

    可以创建AggregateMedian 子类,然后其行为类似于其他聚合函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 2018-02-06
      • 2016-08-17
      • 2020-05-14
      相关资源
      最近更新 更多