我想将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
最近的Django版本似乎省略了group by
子句中的冗余字段。如果按表中的唯一字段进行分组,则无法按该表中的任何其他字段进行分组。这肯定解释了member_account.name
的遗漏,如果你在查询中有唯一的member_account.id
,这是多余的。
payment_gateway
也是如此,如果你有限制,每个帐户只有一个payment_gateway
。如果帐户可以有多个支付网关,那么我没有立即解释为什么Django认为该字段是group_by
目的多余的。
如果您显示相关模型的定义,我们可能会告诉您更多。