如何用Django ORM获取与上一行至少间隔指定时长的所有数据行?
问题:筛选Django模型中时间间隔≥指定秒数的记录
我的Django模型定义如下:
class MyModel(Model): timestamp = models.DateTimeField(auto_now=True) ...
我需要从MyModel中筛选出与上一条记录时间间隔至少为指定秒数的数据行。数据通常每30秒新增一条,但我要保留间隔≥30秒的记录,同时还要限制记录在指定日期范围内(这部分功能已实现)。
我尝试了多种方案,以下是最接近目标的一种:
queryset = MyModel.objects.annotate( time_diff=F("timestamp") - Window( expression=Lag("timestamp"), order_by=(F("timestamp"),) ) )
这个方案不会直接报错,time_diff字段也能正常生成(比如queryset.last().time_diff会返回timedelta类型的值),但当我尝试对time_diff进行filter筛选时,会抛出错误:NotSupportError: Window is disallowed in the filter clause。
我还试过另外两种无效方案:
方案二:
start_date = datetime(...) end_date = datetime(...) time_interval = ... # 总秒数 time_diff_window = Window( expression=Lag('timestamp'), order_by=F('timestamp').asc(), ) queryset = MyModel.objects.filter( timestamp__range=(start_date, end_date), ).annotate( time_diff=Extract('timestamp', 'epoch') - Extract('lagged_timestamp', 'epoch'), lagged_timestamp=Lag('timestamp', default=start_date, over=time_diff_window), ).filter( time_diff__gte=time_interval, ).order_by('timestamp')
方案三:
window = Window(expression=Lag("timestamp"), order_by=F('timestamp').asc()) lagged_timestamp = Lag("timestamp", default=Value(timedelta(seconds=0), output_field=DurationField()), over=window,) # 计算当前行与上一行的时间差 time_diff = Coalesce(F("timestamp") - lagged_timestamp, Value(timedelta(seconds=0), output_field=DurationField())) # 筛选时间差大于指定间隔的记录 readings = MyModel.objects.annotate( time_diff=time_diff, ).filter( time_diff__gte=timedelta(seconds=time_interval), timestamp__range=(start_date, end_date), ).order_by("timestamp")
我知道可以用Python代码实现这个筛选逻辑,但更希望通过Django ORM完成,让数据库来承担计算压力。
内容的提问来源于stack exchange,提问作者Dakota Horstman
相关产品推荐
相关产品推荐

