为什么我从Django查询中获取此sql语法错误?

时间:2011-07-15 14:49:19

标签: mysql sql django

在Django中,我在视图中有以下查询

applicant=Applicants.objects.get(ben=entity_number)
f471s=applicant.form471_set.order_by("-funding_year","number")
enrollment=f471s.values("schooldata__ben").annotate(f=Max("number")).filter(
           number=F("f")).values().aggregate(
           s=Sum("schooldata__student_count"))['s']

当我尝试访问该视图的页面时,出现错误

DatabaseError
(1064, "You have an error in your SQL syntax; check the manual that 
corresponds to your MySQL server version for the right syntax to use 
near 'FROM (SELECT `frontend_form471`.`number` AS `number`,
`frontend_form471`.`form_s' at line 1")

我让记录器打印出Django正在生成的SQL,我得到了

(0.001) SELECT  FROM (SELECT `frontend_form471`.`number` AS `number`,
`frontend_form471`.`form_status` AS `form_status`, `frontend_form471`.`ben_id`
AS `ben_id`, `frontend_form471`.`funding_year` AS `funding_year`,
MAX(`frontend_form471`.`number`) AS `f` FROM `frontend_form471` LEFT OUTER JOIN
`SchoolData` ON (`frontend_form471`.`number` = `SchoolData`.`f471 Application Number`)
WHERE (`frontend_form471`.`ben_id` = 122871 ) GROUP BY `frontend_form471`.`number`,
`frontend_form471`.`number`, `frontend_form471`.`form_status`,
`frontend_form471`.`ben_id`, `frontend_form471`.`funding_year` HAVING
`frontend_form471`.`number` =  MAX(`frontend_form471`.`number`) ORDER BY
`frontend_form471`.`funding_year` DESC, `frontend_form471`.`number` ASC) 
subquery; args=(u'122871',)

供参考,我使用的是MySQL 5.1.54-1ubuntu4。看起来语法错误在第一行,但我不明白为什么Django使用不正确的语法生成SQL代码。有什么方法可以改变一些东西(可能是一个设置)来解决这个问题吗?

编辑:为了回答答案,我还尝试在没有第二次.values()调用的情况下运行第三行python代码并获得完全相同的效果。

3 个答案:

答案 0 :(得分:0)

我最终通过用以下代码替换我的第三行python代码来避免这个问题:

latest=SchoolData.objects.filter(f471__ben=entity_number).values(
       'ben').annotate(m=Max('f471__number')).order_by().distinct()
enrollment=sum(SchoolData.objects.filter(ben=l['ben']).get(
           f471__number=l['m']).student_count for l in latest)

这很有效,但速度很慢。最后,一些关于我数据的额外信息让我可以像这样进行优化:

latestYear=f471s.aggregate(m=Max('funding_year'))['m']
enrollment=SchoolData.objects.filter(f471__ben=entity_number,
           f471__funding_year=latestYear).distinct().aggregate(
           s=Sum('student_count'))['s']

这不是完全相同的事情,但更好地解决了我的特定问题。

答案 1 :(得分:0)

如果其他人像我一样想知道,这是一个公认的Django错误: https://code.djangoproject.com/ticket/15624

答案 2 :(得分:-1)

问题是注释后的第二个空值()子句。你实际上是在告诉django不要在select中包含任何列。