2011-07-15 33 views
1

在Django中我有一个观点为什么我从Django查询中得到这个sql语法错误?

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") 

我已经记录仪打印出的SQL Django正在生成,我得到了

(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代码。有什么办法可以改变一些事情(可能是一种设置)来解决这个问题吗?

编辑:为了回应一个答案,我也尝试运行python代码的第三行,没有第二个.values()调用,并得到完全相同的效果。

+0

@美国洛特是的,但用表/型号名称是不够资格的,它不应该是一个问题。 – murgatroid99

+0

“SELECT FROM(SELECT”) SELECT之后没有任何东西 - 这是无效的SQL语法!也许这是一个错误,因为您调用values()并且它不知道可用字段,当您查找所有此注释时,聚合和过滤的东西!尝试运行它没有values()... – benjaoming

+0

@benjaoming你应该阅读注释的文档。以前的值是如何创建一个GROUP BY子句。所以不,他不应该尝试没有 – John

回答

-1

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

+0

https: //docs.djangoproject.com/en/1.3/ref/models/querysets/#django.db.models.query.QuerySet.values表示如果args为空,'values()'选择所有列。我以前运行过代码没有空值调用,并得到完全相同的结果 – murgatroid99

+0

只是为了好奇才尝试简化事情,去掉第二个聚集和过滤器,看看你得到了什么。正确的,然后建立它备份。 – John

+0

我试过了,发现如果将第二个'values()'更改为'values(“schooldata__student_count”)'',那么语法错误消失,但聚合调用返回空字典。我现在意识到我可以使用'values_list'和'sum'来避免这个问题。 – murgatroid99

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'] 

不做同样的事情,但解决了我特别的问题更好。