假设我有以下模型:
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
)。但是,当我在 .filter
上尝试 time_diff
时,我收到类似 NotSupportError: Window is disallowed in the filter clause
的错误。
我尝试过的其他一些无效的尝试如下(请注意,我也试图将记录限制在特定的日期范围内,但效果很好):
start_date = datetime(...)
end_date = datetime(...)
time_interval = ... # total seconds
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,)
# Compute the time difference between the current row and the previous
time_diff = Coalesce(F("timestamp") - lagged_timestamp, Value(timedelta(seconds=0), output_field=DurationField()))
# Filter the rows where the time differences is greater than the requested interval
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 中执行此操作,但我真的很想尝试通过 ORM 使其工作并让数据库完成繁重的工作。