Django: IntegrityError (дублирование ключа) при сохранении существующей записи
Надеюсь, у всех все хорошо!
У меня есть проблема, когда я сохраняю существующую запись в моем приложении. Поскольку при моделировании данных мне нужно, чтобы все таблицы в модели имели одинаковые основные поля идентификации и аудита, у меня есть абстрактный класс, все классы расширяются от него:
#models.py
import uuid
from django.db import models
from django_currentuser.db.models import CurrentUserField
class BasicMonitoringTable(models.Model):
ium_uuid = models.UUIDField(
verbose_name='UUID',
help_text='''
Unique register ID in the system
''',
db_column='ium_uuid',
db_index=True,
primary_key=True,
max_length=40,
unique=True,
null=False,
blank=False,
default=uuid.uuid4,
editable=False,
)
ium_active = models.BooleanField(
verbose_name='Active',
help_text='''
Determines whether record is active. Inactive records are not used by the system (logical deletion)
''',
db_column='ium_active',
db_index=True,
unique=False,
null=False,
blank=False,
editable=True,
)
ium_mod_count = models.BigIntegerField(
verbose_name='Updates Count',
help_text='''
Number of times the record was updated
''',
db_column='ium_mod_count',
db_index=True,
unique=False,
null=False,
blank=False,
editable=False,
)
ium_created = models.DateTimeField(
verbose_name='Created Date Time',
help_text='''
Record creation date and time
''',
db_column='ium_created',
db_index=True,
unique=False,
null=False,
blank=False,
editable=False,
auto_now_add=True,
)
ium_created_by = CurrentUserField(
verbose_name='Created By User',
help_text='''
Record creator user
''',
db_column='ium_created_by',
db_index=True,
unique=False,
null=False,
blank=False,
editable=False,
on_delete=models.DO_NOTHING,
related_name='+',
)
ium_updated = models.DateTimeField(
verbose_name='Updated Date Time',
help_text='''
Record last update date and time
''',
db_column='ium_updated',
db_index=True,
unique=False,
null=False,
blank=False,
editable=False,
auto_now=True,
)
ium_update_by = CurrentUserField(
verbose_name='Update By User',
help_text='''
Record creator user
''',
db_column='ium_update_by',
db_index=True,
unique=False,
null=False,
blank=False,
editable=False,
max_length=MAX_LEN_DEFAULT,
on_delete=models.DO_NOTHING,
on_update=True,
related_name='+',
)
def save(self, *args, **kwargs) -> None:
if self.ium_mod_count == None: #first save
self.ium_mod_count = 1
else:
self.ium_mod_count +=1
super().save(self, *args, **kwargs)
class Meta:
abstract = True
Пример расширенного класса:
#models.py
class UserAlertRole(BasicMonitoringTable):
name = models.CharField(
verbose_name='Role Name',
help_text='''
Name of the role, tile or position of a user
''',
unique=True,
null=False,
blank=False,
max_length=255,
db_index=True,
db_column='user_alert_role_name'
)
class Meta:
abstract = False
db_table = 'ium_tb_user_alert_role'
verbose_name = 'User Alert Role'
verbose_name_plural = 'User Alert Roles'
ordering = ['name']
def __str__(self) -> str:
return self.name
Когда я обновляю запись (независимо от того, делаю ли я это через форму администрирования приложения или через promt), возникает следующее исключение:
Тип исключения: IntegrityError at /admin/monitoring/useralertrole/67e1c5839d254c3682422b8dd5c2c50a/change/ Значение исключения: (1062, "Дублирующая запись '67e1c5839d254c3682422b8dd5c2c50a' для ключа 'PRIMARY'")
>
В качестве возможного решения я попытался использовать параметр force_update=True
в методе save()
абстрактного класса (BasicMonitoringTable
), чтобы заставить django сначала попытаться выполнить обновление перед выполнением вставки, как показано в документации
Но когда я ввожу этот параметр, я получаю исключение, что информируется как опция force_update, так и опция force_insert, что не может произойти согласно документации django. Глядя на экран исключения администратора, я заметил следующее поведение:
/src/my_site/my_app/models.py, строка 127, in save super().save(self, *args, **kwargs)
▼ Local vars Variable value __class__ <class 'monitoring.models.BasicMonitoringTable'> args () kwargs {} self <UserAlertRole: TEST>
/src/venv/lib/python3.10/site-packages/django/db/models/base.py, line 739, in save self.save_base(using=using, force_insert=force_insert,force_update=force_update, update_fields=update_fields)
>▼ Local vars Variable value deferred_fields set() force_insert <UserAlertRole: TEST> force_update True self <UserAlertRole: TEST> update_fields None using 'default'
Я не в состоянии понять и решить ни одну из двух проблем.
Мое окружение:
- OS: Ubuntu Desktop 22.04.1 LTS .
- python: 3.10.07
- requirements:
- asgiref==3.5.2
- Django==3.2.15
- django-currentuser==0.5.3
- mysqlclient==2.1.1
- pytz==2022.2.1
- sqlparse==0.4.2
- DB: 10.9.2-MariaDB-1:10.9.2+maria~ubu2204
Tks :-)