mariadb 如何在django queryset中标注median value

8wtpewkr  于 7个月前  发布在  Go
关注(0)|答案(3)|浏览(76)

我有2个模型拼图和玩。我对每一部剧都有评分我想注解一个谜题查询集的中位数评分值为所有相应的发挥。

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?)。
但几个小时后,我必须承认我在这里超出了我的能力范围。
有人能帮我把这些点连起来吗?

lbsnaicq

lbsnaicq1#

Django中没有Median实现,因为它没有在PostgreSQL中实现。
您可以在MariaDB 10.3.3+上运行median作为原始查询,或者在Django中编写一个聚合函数以满足您的自定义需求,然后使用ORM将其转换为相同的查询
你应该在生产和开发环境中使用相同的数据库类型,以尽量减少由于不同环境而导致的错误(建议使用docker等工具)

sycxhyv7

sycxhyv72#

关于使用PostgreSQL时如何做到这一点,请参考我在Django & Postgres上的回答-百分位数(中位数)和分组。
可以创建AggregateMedian子类,它的行为与其他聚合函数类似。

dced5bon

dced5bon3#

好吧,我发现了一个强大的多数据库实现的Django中位数和百分位数的包:https://github.com/ankane/tailslide/
它使用户能够执行以下操作:

from tailslide import Median, Percentile

Item.objects.aggregate(Median('price'))
Request.objects.aggregate(Percentile('response_time', .95))

相关问题