From f62dd76d94459c084f2f18489036dd919b13bab4 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Wed, 17 Nov 2021 09:40:07 +0100 Subject: [PATCH] #35 Sanity command * adds sanity check for deadlines and geometries --- konova/management/commands/sanitize_db.py | 104 +++++++++++++++++++++- 1 file changed, 100 insertions(+), 4 deletions(-) diff --git a/konova/management/commands/sanitize_db.py b/konova/management/commands/sanitize_db.py index 30e3aa3a..de3c249d 100644 --- a/konova/management/commands/sanitize_db.py +++ b/konova/management/commands/sanitize_db.py @@ -9,6 +9,7 @@ from compensation.models import CompensationState, Compensation, EcoAccount, Com from ema.models import Ema from intervention.models import Intervention from konova.management.commands.setup import BaseKonovaCommand +from konova.models import Deadline, Geometry from user.models import UserActionLogEntry @@ -20,6 +21,8 @@ class Command(BaseKonovaCommand): self.sanitize_log_entries() self.sanitize_compensation_states() self.sanitize_actions() + self.sanitize_deadlines() + self.sanitize_geometries() except KeyboardInterrupt: self._break_line() exit(-1) @@ -64,7 +67,7 @@ class Command(BaseKonovaCommand): num_entries = unattached_log_entries.count() if num_entries > 0: - self._write_warning(f"Found {num_entries} log entries not attached to anything. Delete now...") + self._write_error(f"Found {num_entries} log entries not attached to anything. Delete now...") unattached_log_entries.delete() self._write_success("Log entries deleted.") else: @@ -92,7 +95,7 @@ class Command(BaseKonovaCommand): return all_ids def sanitize_actions(self): - """ Removes log entries which are not attached to any logs + """ Removes actions which are not attached to any entries Returns: @@ -110,13 +113,106 @@ class Command(BaseKonovaCommand): num_entries = unattached_actions.count() if num_entries > 0: - self._write_warning(f"Found {num_entries} actions not attached to anything. Delete now...") + self._write_error(f"Found {num_entries} actions not attached to anything. Delete now...") unattached_actions.delete() self._write_success("Actions deleted.") else: self._write_success("No unattached actions found.") self._break_line() + def get_all_deadline_ids(self, cls): + """ Getter for all deadline ids of a model + + Args: + cls (Compensation|Ema|EcoAccount): The model class + + Returns: + + """ + all_objects = cls.objects.all().prefetch_related( + "deadlines", + ) + all_ids = all_objects.exclude( + deadlines__isnull=True, + ).values_list( + "deadlines__id", + flat=True, + ) + return all_ids + + def sanitize_deadlines(self): + """ Removes deadlines which are not attached to any entries + + Returns: + + """ + self._write_warning("=== Sanitize deadlines ===") + all_deadlines = Deadline.objects.all() + + compensation_deadline_ids = self.get_all_deadline_ids(Compensation) + attached_deadline_ids = compensation_deadline_ids.union( + self.get_all_deadline_ids(EcoAccount), + self.get_all_deadline_ids(Ema), + ) + + unattached_deadlines = all_deadlines.exclude(id__in=attached_deadline_ids) + + num_entries = unattached_deadlines.count() + if num_entries > 0: + self._write_error(f"Found {num_entries} deadlines not attached to anything. Delete now...") + unattached_deadlines.delete() + self._write_success("Deadlines deleted.") + else: + self._write_success("No unattached deadlines found.") + self._break_line() + + def get_all_geometry_ids(self, cls): + """ Getter for all geometry ids of a model + + Args: + cls (Intervention|Compensation|Ema|EcoAccount): The model class + + Returns: + + """ + all_objects = cls.objects.all().prefetch_related( + "geometry", + ) + all_ids = all_objects.exclude( + geometry__isnull=True, + ).values_list( + "geometry__id", + flat=True, + ) + return all_ids + + def sanitize_geometries(self): + """ Removes geometries which are not attached to any entries + + Returns: + + """ + self._write_warning("=== Sanitize geometries ===") + all_geometries = Geometry.objects.all() + + compensation_geometry_ids = self.get_all_geometry_ids(Compensation) + attached_geometry_ids = compensation_geometry_ids.union( + self.get_all_geometry_ids(Intervention), + self.get_all_geometry_ids(EcoAccount), + self.get_all_geometry_ids(Ema), + ) + + unattached_geometries = all_geometries.exclude(id__in=attached_geometry_ids) + + num_entries = unattached_geometries.count() + if num_entries > 0: + self._write_error(f"Found {num_entries} geometries not attached to anything. Delete now...") + unattached_geometries.delete() + self._write_success("Deadlines deleted.") + else: + self._write_success("No unattached geometries found.") + self._break_line() + def get_all_state_ids(self, cls): """ Getter for all states (before and after) of a class @@ -163,7 +259,7 @@ class Command(BaseKonovaCommand): ) num_unattached_states = unattached_states.count() if num_unattached_states > 0: - self._write_warning(f"Found {num_unattached_states} unused compensation states. Delete now...") + self._write_error(f"Found {num_unattached_states} unused compensation states. Delete now...") unattached_states.delete() self._write_success("Unused states deleted.") else: