#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 , 4 years ago
| Cc: | added |
|---|
comment:2 by , 4 years ago
| Resolution: | → wontfix |
|---|---|
| Status: | new → closed |
comment:3 by , 4 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.