Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 计算字段的Django查询表达式,带聚合,不带分组_Python_Django_Django Orm - Fatal编程技术网

Python 计算字段的Django查询表达式,带聚合,不带分组

Python 计算字段的Django查询表达式,带聚合,不带分组,python,django,django-orm,Python,Django,Django Orm,继续从 我在Django中有以下查询表达式: fields = { 'impressions': models.Sum('impressions'), 'clicks': models.Sum('clicks'), } calc_fields = { 'ctr': models.Case(models.When(impressions = 0, then = 0), default = 1.0 * models.F('clicks') / models.F('impr

继续从

我在Django中有以下查询表达式:

fields = {
    'impressions': models.Sum('impressions'), 
    'clicks': models.Sum('clicks'), 
}
calc_fields = {
    'ctr': models.Case(models.When(impressions = 0, then = 0), default = 1.0 * models.F('clicks') / models.F('impressions'), output_field = models.FloatField()),
}

Stats.objects.values('product').annotate(**fields).annotate(**calc_fields)
这将正确计算聚合字段
印象
单击
和按
产品
分组的
ctr
,并生成以下postgres查询:

SELECT 
    "stats"."product_id", 
    SUM("stats"."impressions") AS "impressions", 
    SUM("stats"."clicks") AS "clicks", 
    CASE WHEN SUM("stats"."impressions") = 0 THEN 0 ELSE ((1.0 * SUM("stats"."clicks")) / SUM("stats"."impressions")) END AS "ctr" 
FROM "stats" 
GROUP BY "stats"."product_id";
现在我只想修改这个表达式,这样当不提供分组时,它只返回整个表中的聚合值。

看起来比我想象的要难。问题的其余部分可以跳过,我只是列出我尝试过的内容

1) 第一次尝试删除
值()

这会产生一个错误:

The annotation 'impressions' conflicts with a field on the model.
Error: 'dict' object has no attribute 'aggregate'
这可能是因为它现在尝试返回一个包含所有字段的完整
Stats
对象列表,而不是像以前一样只返回自定义字段。也许有办法禁用它,只返回自定义字段

我尝试重命名字段,但结果是按主索引分组,因此它返回表中的所有记录,而不是一条记录

2) 也许我需要用聚合替换注释

Stats.objects.aggregate(**fields).aggregate(**calc_fields)
这会产生一个错误:

The annotation 'impressions' conflicts with a field on the model.
Error: 'dict' object has no attribute 'aggregate'
好的,也许它们无法链接,让我们将字段合并在一起,并在案例中用
Sum
交换
F

fields = {
    'impressions': models.Sum('impressions'), 
    'clicks': models.Sum('clicks'), 
    'ctr': models.Case(models.When(impressions = 0, then = 0), default = 1.0 * models.Sum('clicks') / models.Sum('impressions'), output_field = models.FloatField()),
}

Stats.objects.aggregate(**fields)
这似乎工作正常。但当我添加额外的字段时(所有值都是相同的,只是名称不同),地狱再次爆发:

问题似乎是由多个
模型引起的。当(impressions=0)
时,它会生成错误的sql:

SELECT 
    CASE WHEN "stats"."impressions" = 0 THEN 0 ELSE ((1.0 * SUM("stats"."clicks")) / SUM("stats"."impressions")) END AS "ctr", 
    CASE WHEN SUM("fstats"."impressions") = 0 THEN 0 ELSE ((1.0 * SUM("stats"."clicks")) / SUM("impressions")) END AS "ctr2", 
    SUM("stats"."impressions") AS "impressions", 
    SUM("stats"."impressions") AS "impressions2", 
    SUM("stats"."clicks") AS "clicks",
    SUM("stats"."clicks") AS "clicks2", 
FROM "stats";
请注意,
ctr
的情况如何被错误地计算为:

CASE WHEN "stats"."impressions" = 0
对于
ctr2
而言,这是正确的:

CASE WHEN SUM("stats"."impressions") = 0
这会导致数据库错误:

column "stats.impressions" must appear in the GROUP BY clause or be used in an aggregate function
3) 将所有聚合字段重命名为不同于模型字段,以避免混淆:

fields = {
    'impressions_total': models.Sum('impressions'), 
    'impressions_total2': models.Sum('impressions'), 
    'clicks_total': models.Sum('clicks'), 
    'clicks_total2': models.Sum('clicks'), 
    'ctr': models.Case(models.When(impressions_total = 0, then = 0), default = 1.0 * models.Sum('clicks') / models.Sum('impressions'), output_field = models.FloatField()),
    'ctr2': models.Case(models.When(impressions_total = 0, then = 0), default = 1.0 * models.Sum('clicks') / models.Sum('impressions'), output_field = models.FloatField()),
}

Stats.objects.aggregate(**fields)
这会产生错误:

Error: Cannot resolve keyword 'impressions_total' into field. Choices are: clicks, clicks_total, impressions, impressions_total2, product, product_id
如果我离开单
ctr
而没有
ctr2
它工作正常。由于某种原因,再次添加额外字段会破坏它


有什么建议吗?我希望它只返回一个自定义字段数组,而不是完整的对象。

我跳过了问题的其余部分。我的印象是,
impressions
字段是模型/记录的一部分,因此与注释冲突,正如您所指出的。如果是这样,您是否尝试过将注释字段的名称更改为其他名称?e、 g.
fields={'imprex':models.Sum('impressions'),..
@Pynchia要与
aggregate()
一起使用?如果尝试了它,它会产生一个django错误(我在“3”下列出了结果)@Pynchia如果与
annotate()
一起使用,它会附加
group by stats.id
(主索引)在这种情况下,您是否尝试过
Stats.objects.annotate(**fields).aggregate(**calc_fields)
?@Pynchia仍然按主id分组