首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django窗口函数

Django窗口函数
EN

Stack Overflow用户
提问于 2021-07-01 17:28:39
回答 1查看 734关注 0票数 2

问题

如何使用Django ORM计算数据库中两个连续行之间的列的增量?

背景

我有以下模式:

代码语言:javascript
复制
class Foobar(models.Model):
    foo = models.IntegerField()

我想为数据库中的每一行计算foo之间的增量。我找到了Django对窗口函数的支持函数。手里拿着这些,我试着做了这样的事情:

代码语言:javascript
复制
Foobar.objects.annotate(delta=Window(expression=F('foo') - Lag('foo')))

这将产生以下错误:

代码语言:javascript
复制
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.

因此,为了简化,我只是尝试用上一行的值对每一行进行注释:

代码语言:javascript
复制
fs = Foobar.objects.annotate(prev=Window(expression=Lag('foo'))
for f in fs:
    print(model_to_dict(f))

不过,我的print()语句中产生的dicts没有'prev'。我遗漏了什么?使用Lag()计算每一行之间的增量的正确方法是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-01 17:42:37

不过,我的print()语句中产生的dicts没有'prev'

这是因为您使用的是model_to_dict,它使用模型声明的字段返回字典,当然它不知道通过查询注释的数据。如果您实际检查该模型,该值确实会在其上得到注释:

代码语言:javascript
复制
fs = Foobar.objects.annotate(prev=Window(expression=Lag('foo'))

for f in fs:
    print(f.prev)

对于增量的计算,您当然可以这样做,只是F('foo')需要在Window表达式之外:

代码语言:javascript
复制
fs = Foobar.objects.annotate(delta=F('foo') - Window(expression=Lag('foo')))

for f in fs:
    print(f.delta)

注意事项:您似乎是出于某种原因使用model_to_dict,可能是为了序列化用于API的数据?这并不是一种很好的序列化模型的方法,相反,您应该考虑使用Django REST框架

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68214555

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档