Opened 6 years ago
Closed 6 years ago
#30044 closed Cleanup/optimization (fixed)
A FieldError should be raised when trying to update with F reference to MTI inherited field
Reported by: | Tom Carrick | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
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.
Change History (5)
comment:2 by , 6 years ago
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.
comment:3 by , 6 years ago
Summary: | F expressions don't work with MTI → A FieldError should be raised when trying to update with F reference to MTI inherited field |
---|---|
Triage Stage: | Unreviewed → Accepted |
Type: | Bug → Cleanup/optimization |
Version: | 2.1 → master |
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?
This looks like #14104 (Allow joined field in
F()
s) in disguise because in the case of MTIF('date_x')
actually translates toF('parent_ptr__date_x')
.I assume you get a
FieldError('Joined field references are not permitted in this query')
error if you passF('parent_ptr__date_x')
?If you do I assume we could keep this ticket opened as a cleanup to raise the same error on inherited fields since they require a join.
Adding support for
update()
through joins is being revisited in #25643.