模型中的 Django 累积总和(sqlite)
Django cumulative sum in model (sqlite)
我的模型是:
class transaction(models.Model):
transactiondate = models.DateField()
category = models.ForeignKey(category, on_delete=models.PROTECT, default=0)
details = models.CharField(max_length=200, null=True)
amount = models.DecimalField(decimal_places=2, max_digits=10)
accountid = models.ForeignKey(account, on_delete=models.PROTECT)
并且我使用原始 SQL 查询获得了每个日期的累计总数:
def cumulativebalance():
query = """SELECT id, transactiondate,
SUM("amount")
OVER (ORDER BY transactiondate) AS "cumsum"
FROM "transactions_transaction"
GROUP BY transactiondate
ORDER BY transactiondate ASC, "cumsum" ASC
"""
return balance = transaction.objects.raw(query)
这 return 我正在寻找的输出。我的问题是 Django 中是否有一种方法可以将其合并到我的模型中而不是将其作为原始 SQL?
我试过的
我确实找到了一个以前的 并且我已经将答案修改为我自己的模型:
test = transaction.objects.annotate(
cumsum=Func(
Sum('amount'),
template='%(expressions)s OVER (ORDER BY %(order_by)s)',
order_by="transactiondate"
)
).values('transactiondate', 'cumsum').order_by('transactiondate', 'cumsum')
但这给了我一个错误:“OVER”附近的 /transactions/ 处的 OperationalError:语法错误。我不明白这是在告诉我什么。
生成的SQL显示在回溯中。我最好的猜测是 OVER 之后应该是 PARTITION BY 而不是 ORDER BY,但我不知道如何从我的 python 代码中更改它。
('SELECT "transactions_transaction"."transactiondate", '
'CAST(CAST(SUM("transactions_transaction"."amount") AS NUMERIC) OVER (ORDER '
'BY transactiondate) AS NUMERIC) AS "cumsum" FROM "transactions_transaction" '
'GROUP BY "transactions_transaction"."id", '
'"transactions_transaction"."transactiondate", '
'"transactions_transaction"."category_id", '
'"transactions_transaction"."details", "transactions_transaction"."amount", '
'"transactions_transaction"."accountid_id" ORDER BY '
'"transactions_transaction"."transactiondate" ASC, "cumsum" ASC')
自 django-2.0, it is possible to work with a Window
expressions [Django-doc]:
from django.db.models import F, Sum, <b>Window</b>
transaction.objects.annotate(
cumsum=<b>Window(</b>Sum('amount'), order_by=F('transactiondate').asc()<b>)</b>
).order_by('transactiondate', 'cumsum')
由此产生的transaction
对象会多出一个属性.cumsum
。
Note: Models in Django are written in PascalCase, not snake_case,
so you might want to rename the model from transaction
to Transaction
.
我的模型是:
class transaction(models.Model):
transactiondate = models.DateField()
category = models.ForeignKey(category, on_delete=models.PROTECT, default=0)
details = models.CharField(max_length=200, null=True)
amount = models.DecimalField(decimal_places=2, max_digits=10)
accountid = models.ForeignKey(account, on_delete=models.PROTECT)
并且我使用原始 SQL 查询获得了每个日期的累计总数:
def cumulativebalance():
query = """SELECT id, transactiondate,
SUM("amount")
OVER (ORDER BY transactiondate) AS "cumsum"
FROM "transactions_transaction"
GROUP BY transactiondate
ORDER BY transactiondate ASC, "cumsum" ASC
"""
return balance = transaction.objects.raw(query)
这 return 我正在寻找的输出。我的问题是 Django 中是否有一种方法可以将其合并到我的模型中而不是将其作为原始 SQL?
我试过的
我确实找到了一个以前的
test = transaction.objects.annotate(
cumsum=Func(
Sum('amount'),
template='%(expressions)s OVER (ORDER BY %(order_by)s)',
order_by="transactiondate"
)
).values('transactiondate', 'cumsum').order_by('transactiondate', 'cumsum')
但这给了我一个错误:“OVER”附近的 /transactions/ 处的 OperationalError:语法错误。我不明白这是在告诉我什么。
生成的SQL显示在回溯中。我最好的猜测是 OVER 之后应该是 PARTITION BY 而不是 ORDER BY,但我不知道如何从我的 python 代码中更改它。
('SELECT "transactions_transaction"."transactiondate", '
'CAST(CAST(SUM("transactions_transaction"."amount") AS NUMERIC) OVER (ORDER '
'BY transactiondate) AS NUMERIC) AS "cumsum" FROM "transactions_transaction" '
'GROUP BY "transactions_transaction"."id", '
'"transactions_transaction"."transactiondate", '
'"transactions_transaction"."category_id", '
'"transactions_transaction"."details", "transactions_transaction"."amount", '
'"transactions_transaction"."accountid_id" ORDER BY '
'"transactions_transaction"."transactiondate" ASC, "cumsum" ASC')
自 django-2.0, it is possible to work with a Window
expressions [Django-doc]:
from django.db.models import F, Sum, <b>Window</b>
transaction.objects.annotate(
cumsum=<b>Window(</b>Sum('amount'), order_by=F('transactiondate').asc()<b>)</b>
).order_by('transactiondate', 'cumsum')
由此产生的transaction
对象会多出一个属性.cumsum
。
Note: Models in Django are written in PascalCase, not snake_case, so you might want to rename the model from
totransaction
Transaction
.