简体   繁体   中英

Why am I getting this sql syntax error from a Django query?

In Django I have the following queries in a view

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

When I try to access the page for that view, I get the error

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

I had the logger print out the SQL that Django is generating and I got

(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',)

For reference, I am using MySQL 5.1.54-1ubuntu4. It looks like the syntax error is in the first line, but I do not understand why Django is generating SQL code with improper syntax. Is there any way I can change something (a setting, possibly) to fix this?

Edit: in response to an answer, I also tried running the third line of python code without the second .values() call and got exactly the same effect.

In case other folks are wondering as I was, this is an accepted Django bug: https://code.djangoproject.com/ticket/15624

I ended up avoiding the problem by replacing my third line of python code with:

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)

This worked but it was very slow. In the end some extra information about my data allowed me to optimize like this:

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

which does not do exactly the same thing but solved my particular problem better.

The issue is the second empty values() clause after the annotate. You're literally telling django not to include any columns in the select.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM