问题
如何使用Django ORM计算数据库中两个连续行之间的列的增量?
背景
我有以下模式:
class Foobar(models.Model):
foo = models.IntegerField()我想为数据库中的每一行计算foo之间的增量。我找到了Django对窗口函数的支持和函数。手里拿着这些,我试着做了这样的事情:
Foobar.objects.annotate(delta=Window(expression=F('foo') - Lag('foo')))这将产生以下错误:
Traceback (most recent call last):
File "/usr/lib/python3.8/code.py", line 90, in runcode
exec(code, self.locals)
File "<input>", line 1, in <module>
File "/home/user/.cache/pypoetry/virtualenvs/scraper-2Ye6bxs0-py3.8/lib/python3.8/site-packages/django/db/models/expressions.py", line 1275, in __init__
raise ValueError(
ValueError: Expression 'CombinedExpression' isn't compatible with OVER clauses.因此,为了简化,我只是尝试用上一行的值对每一行进行注释:
fs = Foobar.objects.annotate(prev=Window(expression=Lag('foo'))
for f in fs:
print(model_to_dict(f))不过,我的print()语句中产生的dicts没有'prev'。我遗漏了什么?使用Lag()计算每一行之间的增量的正确方法是什么?
发布于 2021-07-01 17:42:37
不过,我的
print()语句中产生的dicts没有'prev'。
这是因为您使用的是model_to_dict,它使用模型声明的字段返回字典,当然它不知道通过查询注释的数据。如果您实际检查该模型,该值确实会在其上得到注释:
fs = Foobar.objects.annotate(prev=Window(expression=Lag('foo'))
for f in fs:
print(f.prev)对于增量的计算,您当然可以这样做,只是F('foo')需要在Window表达式之外:
fs = Foobar.objects.annotate(delta=F('foo') - Window(expression=Lag('foo')))
for f in fs:
print(f.delta)注意事项:您似乎是出于某种原因使用
model_to_dict,可能是为了序列化用于API的数据?这并不是一种很好的序列化模型的方法,相反,您应该考虑使用Django REST框架。
https://stackoverflow.com/questions/68214555
复制相似问题