Django Select Query Time Diff

风流意气都作罢 提交于 2020-01-24 15:14:45

问题


I am trying to query a database table in django with, among others, the following columns:

id | start_time | end_time

Rather than getting the separate values for the two, can I just get the difference directly in a query? Something to this effect:

SELECT id, Diff(start_time, end_time) FROM myTable

回答1:


QuerySet.extra() will allow you to specify arbitrary expressions for a column. Note that the result will be DB-dependent.




回答2:


This can be done entirely through the ORM in Django 1.10 and above. With a model like so:

class Timer(models.Model)

    start_time = models.DateTimeField()
    end_time = models.DateTimeField()

You can annotate the objects with the duration like so:

from django.db.models import DurationField, ExpressionWrapper, F

Timer.objects.annotate(duration=ExpressionWrapper(F('end_time') - F('start_time'),
                                                  output_field=DurationField()))



回答3:


It seems to me that the easiest way is to add a third column with the difference and update it every time the object is modified like this:

class Timer(models.Model)

    start_time = models.DateTimeField()
    end_time = models.DateTimeField()
    diff_time = models.DateTimeField()

    def __init__(self, *args, **kwargs):
        super(Timer, self).__init__(*args, **kwargs)
        self.diff_time = self.end_time - self.start_time

    def save(self, *args, **kwargs):
        self.diff_time = self.end_time - self.start_time
        super(Timer, self).save(*args, **kwargs)

I tried to look for a solution with annotate, but there is no support for aggregate functions in either mysql nor postgres. Even if there where, seem like nice trade off an extra column for not having to calculate the diff for each row on each query!

Oh, and you can just retrieve what you want like this:

 Timer.objects.values('id', 'diff_time')



回答4:


As of Django 1.8, extra is discouraged in favor of annotate+RawSQL. The following works for MySQL:

res = MyTable.objects.annotate(duration=RawSQL('datediff(endtime, starttime)', ()))
# examine the results
print res.values_list('duration', 'starttime', 'endtime')


来源:https://stackoverflow.com/questions/5698486/django-select-query-time-diff

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!