[Django] #30044: F expressions don't work with MTI

10 views
Skip to first unread message

Django

unread,
Dec 16, 2018, 6:20:40 AM12/16/18
to django-...@googlegroups.com
#30044: F expressions don't work with MTI
-------------------------------------+-------------------------------------
Reporter: Tom | Owner: nobody
Carrick |
Type: Bug | Status: new
Component: Database | Version: 2.1
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
First, I'm not sure if it is or should be possible to do this, but I think
at least the error message could be improved.


{{{
class Parent(models.Model):
date_x = models.DateTimeField(blank=True, null=True)

class Child(Parent):
date_y = models.DateTimeField(blank=True, null=True)


>>> Child.objects.update(date_y=F('date_x'))
Traceback (most recent call last):
File "/Users/tom/.local/share/virtualenvs/test-PwakbHlc/lib/python3.6
/site-packages/django/db/backends/utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
File "/Users/tom/.local/share/virtualenvs/test-PwakbHlc/lib/python3.6
/site-packages/django/db/backends/sqlite3/base.py", line 296, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: no such column: mtitest_parent.date_x
}}}

This error is confusing as it says it's looking at the parent model, but
the field is right there on the parent model.

On another project using postgres, the error is better but it makes it
seem like a bug in django (not sure if it is or isn't):

{{{
>>> Project.objects.update(deactivation_date=F('last_activity'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.5/site-
packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/local/lib/python3.5/site-packages/django/db/models/query.py",
line 695, in update
rows = query.get_compiler(self.db).execute_sql(CURSOR)
File "/usr/local/lib/python3.5/site-
packages/django/db/models/sql/compiler.py", line 1379, in execute_sql
cursor = super().execute_sql(result_type)
File "/usr/local/lib/python3.5/site-
packages/django/db/models/sql/compiler.py", line 1068, in execute_sql
cursor.execute(sql, params)
File "/usr/local/lib/python3.5/site-
packages/django/db/backends/utils.py", line 100, in execute
return super().execute(sql, params)
File "/usr/local/lib/python3.5/site-
packages/raven/contrib/django/client.py", line 123, in execute
return real_execute(self, sql, params)
File "/usr/local/lib/python3.5/site-
packages/django/db/backends/utils.py", line 68, in execute
return self._execute_with_wrappers(sql, params, many=False,
executor=self._execute)
File "/usr/local/lib/python3.5/site-
packages/django/db/backends/utils.py", line 77, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/usr/local/lib/python3.5/site-
packages/django/db/backends/utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python3.5/site-packages/django/db/utils.py", line
89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/usr/local/lib/python3.5/site-
packages/django/db/backends/utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: missing FROM-clause entry for table
"content_contentmodel"
LINE 1: ...DATE "projects_project" SET "deactivation_date" = "content_c...
^
missing FROM-clause entry for table "content_contentmodel"
LINE 1: ...DATE "projects_project" SET "deactivation_date" = "content_c...
}}}

I don't know if it's possible to fix this, but if not it would be nice if
the user could be informed this isn't possible.

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

Django

unread,
Dec 16, 2018, 10:39:56 AM12/16/18
to django-...@googlegroups.com
#30044: F expressions don't work with MTI
-------------------------------------+-------------------------------------
Reporter: Tom Carrick | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 2.1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Simon Charette):

This looks like #14104 (Allow joined field in `F()`s) in disguise because
in the case of MTI `F('date_x')` actually translates to
`F('parent_ptr__date_x')`.

I assume you get a `FieldError('Joined field references are not permitted
in this query')` error if you pass `F('parent_ptr__date_x')`?

If you do I assume we could keep this PR opened as a cleanup to raise the
same error on inherited fields since they require a join.

Adding support `update()` through joins is being revisited in #25643.

--
Ticket URL: <https://code.djangoproject.com/ticket/30044#comment:1>

Django

unread,
Dec 16, 2018, 11:32:00 AM12/16/18
to django-...@googlegroups.com
#30044: F expressions don't work with MTI
-------------------------------------+-------------------------------------
Reporter: Tom Carrick | Owner: nobody
Type: Bug | Status: new

Component: Database layer | Version: 2.1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Tom Carrick):

Yeah, I think you're right. I already tried specifying the related field
to the `F()` expression and got the error you described.

I guess that means the issue is mostly that the error doesn't tell the
user anything useful (and seems straight up misleading in the sqlite
example).

Also this limitation doesn't seem to be documented anywhere.

--
Ticket URL: <https://code.djangoproject.com/ticket/30044#comment:2>

Django

unread,
Dec 16, 2018, 11:59:57 AM12/16/18
to django-...@googlegroups.com
#30044: A FieldError should be raised when trying to update with F reference to MTI
inherited field

-------------------------------------+-------------------------------------
Reporter: Tom Carrick | Owner: nobody
Type: | Status: new
Cleanup/optimization |
Component: Database layer | Version: master

(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Simon Charette):

* version: 2.1 => master
* type: Bug => Cleanup/optimization
* stage: Unreviewed => Accepted


Comment:

> Also this limitation doesn't seem to be documented anywhere.

We usually don't document bugs but since we explicitly error out in this
case I guess we could include a mention in `update()` as well. Any
thoughts on that Tim?

--
Ticket URL: <https://code.djangoproject.com/ticket/30044#comment:3>

Django

unread,
Jan 16, 2019, 12:41:43 AM1/16/19
to django-...@googlegroups.com
#30044: A FieldError should be raised when trying to update with F reference to MTI
inherited field
-------------------------------------+-------------------------------------
Reporter: Tom Carrick | Owner: nobody
Type: | Status: new
Cleanup/optimization |
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Simon Charette):

* has_patch: 0 => 1


--
Ticket URL: <https://code.djangoproject.com/ticket/30044#comment:4>

Django

unread,
Jan 16, 2019, 2:29:12 PM1/16/19
to django-...@googlegroups.com
#30044: A FieldError should be raised when trying to update with F reference to MTI
inherited field
-------------------------------------+-------------------------------------
Reporter: Tom Carrick | Owner: nobody
Type: | Status: closed

Cleanup/optimization |
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham <timograham@…>):

* status: new => closed
* resolution: => fixed


Comment:

In [changeset:"9e5e5a657b95ee49923fe3d2691c5d73813b4c53" 9e5e5a65]:
{{{
#!CommitTicketReference repository=""
revision="9e5e5a657b95ee49923fe3d2691c5d73813b4c53"
Fixed #30044 -- Raised a FieldError on inherited field update attempts.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/30044#comment:5>

Reply all
Reply to author
Forward
0 new messages