在Django ORM中删除SQL查询中的额外GROUP BY

时间:2016-05-26 17:40:54

标签: django django-orm

我有以下型号:

class Statistics(models.Model):
    game_id = models.IntegerField(db_column='gameid', primary_key=True)
    time = models.DateTimeField()
    servers = models.IntegerField()
    users = models.IntegerField()

我有自定义数据库函数datediff_hours的传统postgre数据库。 要在django中使用此函数,我创建以下类:

from django.db.models import Func


class DateDiffHoursFunc(Func):
    function = 'datediff_hours'

现在我构建实际的查询:

from django.db.models import Sum, Value, F

query = Statistics.objects.values('time').filter(game_id=1).\
        annotate(users_sum=Sum('users', distinct=True)).\
        annotate(timestamp=DateDiffHoursFunc(Value(datetime(2016, 5, 26)), F('time'))).\
        values('users_sum', 'timestamp')

我得到的查询:

>>> print(query.query)

SELECT 
     SUM(`statistics`.`users`) AS `users_sum`, 
     datediff_hours(2013-04-01 00:00:00, `statistics`.`time`) AS `timestamp`
FROM `statistics` WHERE `statistics`.`gameid` = 12 
GROUP BY `statistics`.`time`, datediff_hours(2013-04-01 00:00:00, `statistics`.`time`) 
ORDER BY NULL

但是我需要仅通过time进行分组,如下所示:

SELECT 
     SUM(`statistics`.`users`) AS `users_sum`, 
     datediff_hours(2013-04-01 00:00:00, `statistics`.`time`) AS `timestamp`
FROM `statistics` WHERE `statistics`.`gameid` = 12 
GROUP BY `statistics`.`time`) 
ORDER BY NULL

如何仅限time限制分组?

2 个答案:

答案 0 :(得分:0)

您是否尝试过Raw SQL?

    query = Statistics.objects.values('time').filter(game_id=1).\
            annotate(users_sum=Sum('users', distinct=True)).\
            annotate(timestamp=DateDiffHoursFunc(Value(datetime(2016, 05, 26)), F('time'))).\
            values('users_sum', 'timestamp').query
    query.group_by = ['time']
    objs = QuerySet(query=query, models=Statistics)

它有点冒险,但试试吧。

答案 1 :(得分:0)

我的解决方案最终是切换到SqlAlchemy进行复杂查询。这个包很适合我 - Aldjemy