Django Window 函数
Django Window functions
问题
如何使用 Django ORM 计算数据库中连续两行之间列的增量?
背景
我有以下型号:
class Foobar(models.Model):
foo = models.IntegerField()
我想为数据库中的每一行计算 foo
之间的增量。我找到了Django's support for Window functions and the Lag()
function。有了这些,我尝试了这样的事情:
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()
语句中的结果字典没有 'prev'
。我错过了什么?使用 Lag()
计算每行之间的增量的正确方法是什么?
The resulting dicts in my print()
statement don't have 'prev'
,
though.
那是因为您正在使用 model_to_dict
,它使用模型声明的字段到 return 字典,当然它对您通过查询注释的数据一无所知。如果您实际检查模型,该值确实会在其上进行注释:
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)
Note: You seem to be using model_to_dict
for some reason, perhaps for serializing data to use for an API? This is not really a
great way to serialize models, instead you should look into using
Django REST framework.
问题
如何使用 Django ORM 计算数据库中连续两行之间列的增量?
背景
我有以下型号:
class Foobar(models.Model):
foo = models.IntegerField()
我想为数据库中的每一行计算 foo
之间的增量。我找到了Django's support for Window functions and the Lag()
function。有了这些,我尝试了这样的事情:
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()
语句中的结果字典没有 'prev'
。我错过了什么?使用 Lag()
计算每行之间的增量的正确方法是什么?
The resulting dicts in my
print()
statement don't have'prev'
, though.
那是因为您正在使用 model_to_dict
,它使用模型声明的字段到 return 字典,当然它对您通过查询注释的数据一无所知。如果您实际检查模型,该值确实会在其上进行注释:
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)
Note: You seem to be using
model_to_dict
for some reason, perhaps for serializing data to use for an API? This is not really a great way to serialize models, instead you should look into using Django REST framework.