Django - Поле "Один к одному" иногда не сохраняет присвоенное полю значение после вызова сохранения без ошибок
В настоящее время мы сталкиваемся с проблемой с полем "один к одному" в Django, когда данные не сохраняются после присвоения значения, а вызов сохранения проходит успешно без каких-либо ошибок. Это происходит не со всеми записями. Я бы сказал, что 60% из них не сохраняются, а 40% сохраняются. Это происходит только на нашем рабочем сервере, где есть миллионы строк для Model1 и Model2 и происходит очень много процессов. Мы также присваиваем значение другим полям и вызываем сохранение в других частях процесса после вызова метода link_item.
models.py
class Model2(models.Model):
# Some other fields here
class Model1(models.Model):
field1 = models.OneToOneField(Model2, on_delete=models.SET_NULL, null=True, blank=True, default=None)
# Some other fields here
def link_item(self, model2_id):
logger.info(f'Linking {self.id} to {model2_id}')
field1 = Model2.objects.get(id=model2_id)
self.field1 = field1
self.save()
logger.info(f'Field 1 was set to {self.field1}')
views.py
import module
def my_view(requests):
model1_obj = Model1.objects.get(id=model1_id)
result = module.another_function(model1_obj, request_data)
return result
module.py
def another_function(model1_obj, request_data):
logger.info(f'Request data was {request_data}')
if request_data['status'] == 'completed':
model1_obj.some_process() # .save() is called here after assigning a value to attribute
model1_obj.some_process2() # .save() is also called here after assigning a value to attribute
model1_obj.link_item(request_data['model2_id']) # Logs were shown but field1 value was not set
Я вижу, что все журналы на сервере корректны, но когда я проверяю значение поля 1, иногда оно не обновляется до ожидаемого значения. Мы используем Django 4.0 и Postgres 14. Есть идеи почему?
Это было решено. Проблема заключается в том, что у нас есть задача celery, которая обновляет тот же самый model1_obj, вызывая переопределение данных, поскольку она также вызывает метод save в задаче. Мы исправили это, добавив конкретное поле для обновления в задачу celery следующим образом: save(update_fields=['field_name'])