Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update a queryset that has been annotated?

Tags:

orm

django

I have the following models:

class Work(models.Model):
    visible = models.BooleanField(default=False)

class Book(models.Model):
    work = models.ForeignKey('Work')    

I am attempting to update some rows like so:

qs=Work.objects.all()
qs.annotate(Count('book')).filter(Q(book__count__gt=1)).update(visible=False)

However, this is giving an error:

DatabaseError: subquery has too many columns LINE 1: ...SET "visible" = false WHERE "app_work"."id" IN (SELECT...

If I remove the update clause, the query runs with no problems and returns what I am expecting.

It looks like this error happens for queries with an annotate followed by an update. Is there some other way to write this?

like image 768
Jess Avatar asked Nov 26 '12 06:11

Jess


1 Answers

You can also clear the annotations off a queryset quite simply:

qs.query.annotations.clear()
qs.update(..)

And this means you're only firing off one query, not one into another, but don't use this if your query relies on an annotation to filter. This is great for stripping out database-generated concatenations, and the utility rubbish that I occasionally add into model's default queries... but the example in the question is a perfect example of where this would not work.

like image 134
Oli Avatar answered Sep 18 '22 07:09

Oli