#28408: Incorrect error message with QuerySet.update() that requires a join on 
an
annotated F expression
-------------------------------------+-------------------------------------
     Reporter:  Kevin Marsh          |                    Owner:  nobody
         Type:  Bug                  |                   Status:  new
    Component:  Database layer       |                  Version:  master
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:  annotate, F, update  |             Triage Stage:  Accepted
    Has patch:  1                    |      Needs documentation:  1
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Changes (by Asif Saifuddin Auvi):

 * needs_docs:  0 => 1
 * version:  1.11 => master


Old description:

> I ran into a bit of a nasty error yesterday on Django 1.11, Postgres 9.5
> where I was trying to do an update using an `F` expression where the
> value in that expression referred to an annotation of an annotation, each
> using a `Case` statement inside the annotation. The error message it was
> giving me was something like the following:
>

> {{{
> ProgrammingError                          Traceback (most recent call
> last)
> <ipython-input-1-29e48364245c> in <module>()
> ----> 1 MyModel.objects.causing_problems()
>
> /usr/src/app/apps/myapp/managers.py in causing_problems(self)
>     833                 ).update(
> --> 834                         my_field=F('my_annotated_field'),
>     835                 )
>     836
>
> /usr/src/app/apps/django/db/models/query.py in update(self, **kwargs)
>     645         query._annotations = None
>     646         with transaction.atomic(using=self.db, savepoint=False):
> --> 647             rows =
> query.get_compiler(self.db).execute_sql(CURSOR)
>     648         self._result_cache = None
>     649         return rows
>
> /usr/src/app/apps/django/db/models/sql/compiler.py in execute_sql(self,
> result_type)
>    1189         related queries are not available.
>    1190         """
> -> 1191         cursor = super(SQLUpdateCompiler,
> self).execute_sql(result_type)
>    1192         try:
>    1193             rows = cursor.rowcount if cursor else 0
>
> /usr/src/app/apps/django/db/models/sql/compiler.py in execute_sql(self,
> result_type, chunked_fetch)
>     884                 # silencing when dropping Python 2 compatibility.
>     885                 pass
> --> 886             raise original_exception
>     887
>     888         if result_type == CURSOR:
>
> ProgrammingError: missing FROM-clause entry for table "myapp_mymodel"
> LINE 1: ...false END, "a_field" = CASE WHEN CASE WHEN ("myapp_my...
> }}}
>
> Spent a while trying to debug where it was going wrong, ended up
> narrowing down the problem to trying to update a field using an `F`
> expression on an annotated field which included a join in it. I'm not
> sure if better error message would have helped in my case but in the much
> simpler test attached it'd be usfeul if the first and second assertions
> raised the same or similar error message.

New description:

 I ran into a bit of a nasty error yesterday on Django 1.11, Postgres 9.5
 where I was trying to do an update using an `F` expression where the value
 in that expression referred to an annotation of an annotation, each using
 a `Case` statement inside the annotation. The error message it was giving
 me was something like the following:


 {{{
 ProgrammingError                          Traceback (most recent call
 last)
 <ipython-input-1-29e48364245c> in <module>()
 ----> 1 MyModel.objects.causing_problems()

 /usr/src/app/apps/myapp/managers.py in causing_problems(self)
     833                 ).update(
 --> 834                         my_field=F('my_annotated_field'),
     835                 )
     836

 /usr/src/app/apps/django/db/models/query.py in update(self, **kwargs)
     645         query._annotations = None
     646         with transaction.atomic(using=self.db, savepoint=False):
 --> 647             rows = query.get_compiler(self.db).execute_sql(CURSOR)
     648         self._result_cache = None
     649         return rows

 /usr/src/app/apps/django/db/models/sql/compiler.py in execute_sql(self,
 result_type)
    1189         related queries are not available.
    1190         """
 -> 1191         cursor = super(SQLUpdateCompiler,
 self).execute_sql(result_type)
    1192         try:
    1193             rows = cursor.rowcount if cursor else 0

 /usr/src/app/apps/django/db/models/sql/compiler.py in execute_sql(self,
 result_type, chunked_fetch)
     884                 # silencing when dropping Python 2 compatibility.
     885                 pass
 --> 886             raise original_exception
     887
     888         if result_type == CURSOR:

 ProgrammingError: missing FROM-clause entry for table "myapp_mymodel"
 LINE 1: ...false END, "a_field" = CASE WHEN CASE WHEN ("myapp_my...
 }}}

 Spent a while trying to debug where it was going wrong, ended up narrowing
 down the problem to trying to update a field using an `F` expression on an
 annotated field which included a join in it. I'm not sure if better error
 message would have helped in my case but in the much simpler test attached
 it'd be useful if the first and second assertions raised the same or
 similar error message.

--

-- 
Ticket URL: <https://code.djangoproject.com/ticket/28408#comment:5>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/068.07c780b9053d905fbf176427a20dc797%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to