#33052 closed Bug (wontfix)
save() on object with pk with default and existing value results in error and not update.
Reported by: | Vikash Singh | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 3.2 |
Severity: | Normal | Keywords: | |
Cc: | vikash.duliajan@…, Vikash Singh | Triage Stage: | Unreviewed |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
# This test case works fine. def test_save_primary_with_default(self): # An UPDATE attempt is skipped when a primary key has default. with self.assertNumQueries(1): PrimaryKeyWithDefault().save() # This new test case fails. def test_update_primary_with_default(self): obj = PrimaryKeyWithDefault() obj.save() obj_2 = PrimaryKeyWithDefault(uuid=obj.uuid) obj_2.save()
Error stack trace:
Traceback (most recent call last): File "/Users/vikash/Documents/django3.2/tests/basic/tests.py", line 165, in test_update_primary_with_default obj_2.save() File "/Users/vikash/Documents/django3.2/django/db/models/base.py", line 802, in save self.save_base( File "/Users/vikash/Documents/django3.2/django/db/models/base.py", line 853, in save_base updated = self._save_table( File "/Users/vikash/Documents/django3.2/django/db/models/base.py", line 1006, in _save_table results = self._do_insert( File "/Users/vikash/Documents/django3.2/django/db/models/base.py", line 1047, in _do_insert return manager._insert( File "/Users/vikash/Documents/django3.2/django/db/models/manager.py", line 85, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) File "/Users/vikash/Documents/django3.2/django/db/models/query.py", line 1426, in _insert return query.get_compiler(using=using).execute_sql(returning_fields) File "/Users/vikash/Documents/django3.2/django/db/models/sql/compiler.py", line 1630, in execute_sql cursor.execute(sql, params) File "/Users/vikash/Documents/django3.2/django/db/backends/utils.py", line 66, in execute return self._execute_with_wrappers( File "/Users/vikash/Documents/django3.2/django/db/backends/utils.py", line 79, in _execute_with_wrappers return executor(sql, params, many, context) File "/Users/vikash/Documents/django3.2/django/db/backends/utils.py", line 92, in _execute return self.cursor.execute(sql, params) File "/Users/vikash/Documents/django3.2/django/db/utils.py", line 90, in __exit__ raise dj_exc_value.with_traceback(traceback) from exc_value File "/Users/vikash/Documents/django3.2/django/db/backends/utils.py", line 92, in _execute return self.cursor.execute(sql, params) File "/Users/vikash/Documents/django3.2/django/db/backends/mysql/base.py", line 73, in execute return self.cursor.execute(query, args) File "/Users/vikash/.virtualenvs/django3.2/lib/python3.9/site-packages/MySQLdb/cursors.py", line 206, in execute res = self._query(query) File "/Users/vikash/.virtualenvs/django3.2/lib/python3.9/site-packages/MySQLdb/cursors.py", line 319, in _query db.query(q) File "/Users/vikash/.virtualenvs/django3.2/lib/python3.9/site-packages/MySQLdb/connections.py", line 259, in query _mysql.connection.query(self, query) django.db.utils.IntegrityError: (1062, "Duplicate entry '3023cab946d44309a1bdfa8237705ee7' for key 'basic_primarykeywithdefault.PRIMARY'")
A workaround is present if we fetch the entry from the db first and then update the values and save it.
Another workaround is to set the value of _state.adding as False.
# This new test case passes. def test_update_primary_with_default(self): obj = PrimaryKeyWithDefault() obj.save() obj_2 = PrimaryKeyWithDefault(uuid=obj.uuid) obj_2._state.adding = False obj_2.save()
before calling save on it.
This issue is not present in django version = 2.2. The error occurs because additional check was introduced in commit to resolve ticket.
Django test suit has a bunch of tests Example_1, Example_2 (At this point there is already an entry in db in table Site with id=1, and domain='example.com'), where objects are updated based on primary key and not fetched from db and then updated. While those test cases pass if the primary key field is integer or auto increment, if some one changes primary key to uuid they fail.
Change History (3)
comment:1 by , 3 years ago
Cc: | added |
---|
comment:2 by , 3 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
comment:3 by , 3 years ago
Summary: | calling save on object with p_key as UUIDField and value already present in db results in error and not update → save() on object with pk with default and existing value results in error and not update. |
---|
This is an intended and documented change in the previous behavior.