Django 1.8。当我们在值中使用id字段并在django中注释操作时,忽略结果sql-query中的另一个字段

问题描述 投票:0回答:1

我想将Django从1.7.11更新到1.11.18。但我发现了一个问题。 Django为不同的Django版本提供不同的sql查询。例如。我有一个问题:

Account.objects
       .values('id', 'name', invoice__payment__payment_gateway')
       .annotate(
         pay_paid=Sum('invoice__payment__amount'),
         pay_refunded=Sum('invoice__payment__amount_refunded')
       )
       .order_by('-name', )

Django 1.7.11的sql-query:

SELECT `member_account`.`id`, 
       `member_account`.`name`, 
       `member_payment`.`payment_gateway`, 
       SUM(`member_payment`.`amount_refunded`) AS `pay_refunded`, 
       SUM(`member_payment`.`amount`) AS `pay_paid` 
FROM `member_account` 
  LEFT OUTER JOIN `member_invoice` ON ( `member_account`.`id` = `member_invoice`.`account_id` ) 
  LEFT OUTER JOIN `member_payment` ON ( `member_invoice`.`id` = `member_payment`.`invoice_id` ) 
GROUP BY `member_account`.`id`, `member_account`.`name`, `member_payment`.`payment_gateway` 
ORDER BY `member_account`.`name` DESC

请注意GROUP BY部分。有3个字段:id,name,payment_gateway。

但我们对Django 1.8.19进行了以下sql-query:

SELECT `member_account`.`id`, 
       `member_account`.`name`, 
       `member_payment`.`payment_gateway`, 
       SUM(`member_payment`.`amount_refunded`) AS `pay_refunded`, 
       SUM(`member_payment`.`amount`) AS `pay_paid` 
FROM `member_account` 
  LEFT OUTER JOIN `member_invoice` ON ( `member_account`.`id` = `member_invoice`.`account_id` ) 
  LEFT OUTER JOIN `member_payment` ON ( `member_invoice`.`id` = `member_payment`.`invoice_id` ) 
GROUP BY `member_account`.`id` 
ORDER BY `member_account`.`name` DESC

而且我们在GROUP BY部分只有一个字段。为什么我们只有一个id字段?这是一个主要问题。

但是当我从values部分删除id字段时,Django 1.8会生成有效的sql-query:

SELECT `member_account`.`name`, 
       `member_payment`.`payment_gateway`, 
       SUM(`member_payment`.`amount_refunded`) AS `pay_refunded`, 
       SUM(`member_payment`.`amount`) AS `pay_paid` 
FROM `member_account` 
  LEFT OUTER JOIN `member_invoice` ON ( `member_account`.`id` = `member_invoice`.`account_id` ) 
  LEFT OUTER JOIN `member_payment` ON ( `member_invoice`.`id` = `member_payment`.`invoice_id` ) 
GROUP BY `member_account`.`name`, `member_payment`.`payment_gateway` 
ORDER BY `member_account`.`name` DESC
python django group-by annotate
1个回答
0
投票

最近的Django版本似乎省略了group by子句中的冗余字段。如果按表中的唯一字段进行分组,则无法按该表中的任何其他字段进行分组。这肯定解释了member_account.name的遗漏,如果你在查询中有唯一的member_account.id,这是多余的。

payment_gateway也是如此,如果你有限制,每个帐户只有一个payment_gateway。如果帐户可以有多个支付网关,那么我没有立即解释为什么Django认为该字段是group_by目的多余的。

如果您显示相关模型的定义,我们可能会告诉您更多。

© www.soinside.com 2019 - 2024. All rights reserved.