如何检索与 Django 的 ORM 至少相隔“间隔”的每一行?

问题描述 投票:0回答:0

假设我有以下模型:

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 使其工作并让数据库完成繁重的工作。

python django django-orm
© www.soinside.com 2019 - 2024. All rights reserved.