Skip to content

Commit

Permalink
Don't save all fields of a model when bumping the update date
Browse files Browse the repository at this point in the history
Instead, use a specialized method that only changes the date. This
provides the following advantages:

* Prevents the date updates from overwriting updates to other fields that
  may happen at the same time.

* Possibly makes the updates more efficient due to fewer columns being
  updated (I have no data on this, though).

* Makes it easier to recognize the purpose of the query when analyzing
  logs/live statistics.

* Makes the purpose of the code more obvious.

The name of the method references the standard POSIX touch utility.
  • Loading branch information
SpecLad committed Feb 7, 2024
1 parent c4f5750 commit 1574c66
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 18 deletions.
7 changes: 2 additions & 5 deletions cvat/apps/dataset_manager/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

from django.db import transaction
from django.db.models.query import Prefetch
from django.utils import timezone
from rest_framework.exceptions import ValidationError

from cvat.apps.engine import models, serializers
Expand Down Expand Up @@ -389,9 +388,7 @@ def _save_tags_to_db(self, tags):
self.ir_data.tags = tags

def _set_updated_date(self):
db_task = self.db_job.segment.task
db_task.updated_date = timezone.now()
db_task.save()
self.db_job.segment.task.touch()

def _save_to_db(self, data):
self.reset()
Expand All @@ -404,7 +401,7 @@ def _save_to_db(self, data):
def _create(self, data):
if self._save_to_db(data):
self._set_updated_date()
self.db_job.save()
self.db_job.touch()

def create(self, data):
self._create(data)
Expand Down
3 changes: 3 additions & 0 deletions cvat/apps/engine/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,9 @@ class TimestampedModel(models.Model):
class Meta:
abstract = True

def touch(self) -> None:
self.save(update_fields=["updated_date"])

class Project(TimestampedModel):
name = SafeCharField(max_length=256)
owner = models.ForeignKey(User, null=True, blank=True,
Expand Down
7 changes: 3 additions & 4 deletions cvat/apps/engine/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def __save_job_handler(instance, created, **kwargs):

if status != db_task.status:
db_task.status = status
db_task.save()
db_task.save(update_fields=["status", "updated_date"])

@receiver(post_save, sender=User,
dispatch_uid=__name__ + ".save_user_handler")
Expand Down Expand Up @@ -60,9 +60,8 @@ def __delete_task_handler(instance, **kwargs):
instance.data.delete()

try:
if instance.project: # update project
db_project = instance.project
db_project.save()
if db_project := instance.project: # update project
db_project.touch()
except Project.DoesNotExist:
pass # probably the project has been deleted

Expand Down
17 changes: 8 additions & 9 deletions cvat/apps/engine/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -894,9 +894,9 @@ def perform_update(self, serializer):
updated_instance = serializer.instance

if instance.project:
instance.project.save()
instance.project.touch()
if updated_instance.project:
updated_instance.project.save()
updated_instance.project.touch()

@transaction.atomic
def perform_create(self, serializer, **kwargs):
Expand All @@ -905,9 +905,8 @@ def perform_create(self, serializer, **kwargs):
organization=self.request.iam_context['organization']
)

if serializer.instance.project:
db_project = serializer.instance.project
db_project.save()
if db_project := serializer.instance.project:
db_project.touch()
assert serializer.instance.organization == db_project.organization

# Required for the extra summary information added in the queryset
Expand Down Expand Up @@ -1944,9 +1943,9 @@ def metadata(self, request, pk):
db_data.deleted_frames,
))
db_data = serializer.save()
db_job.segment.task.save()
db_job.segment.task.touch()
if db_job.segment.task.project:
db_job.segment.task.project.save()
db_job.segment.task.project.touch()

if hasattr(db_data, 'video'):
media = [db_data.video]
Expand Down Expand Up @@ -2285,10 +2284,10 @@ def perform_destroy(self, instance: models.Label):
code=status.HTTP_400_BAD_REQUEST)

if project := instance.project:
project.save(update_fields=['updated_date'])
project.touch()
ProjectWriteSerializer(project).update_child_objects_on_labels_update(project)
elif task := instance.task:
task.save(update_fields=['updated_date'])
task.touch()
TaskWriteSerializer(task).update_child_objects_on_labels_update(task)

return super().perform_destroy(instance)
Expand Down

0 comments on commit 1574c66

Please sign in to comment.