From 3bdb1a1fade3280faa534bee7232986cb30f5aaa Mon Sep 17 00:00:00 2001 From: Erwan Rouchet <rouchet@teklia.com> Date: Thu, 11 Jul 2024 15:59:53 +0200 Subject: [PATCH] Prevent empty WorkerConfiguration names --- .../management/commands/load_export.py | 3 ++ ...039_worker_configuration_name_not_empty.py | 47 +++++++++++++++++++ arkindex/process/models.py | 9 +++- 3 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 arkindex/process/migrations/0039_worker_configuration_name_not_empty.py diff --git a/arkindex/documents/management/commands/load_export.py b/arkindex/documents/management/commands/load_export.py index 55ec306ee4..fcf94b6139 100644 --- a/arkindex/documents/management/commands/load_export.py +++ b/arkindex/documents/management/commands/load_export.py @@ -459,6 +459,9 @@ class Command(BaseCommand): configuration, _ = WorkerConfiguration.objects.get_or_create( worker=Worker.objects.get(versions__id=worker_version_id), configuration=json.loads(row["configuration"]), + # Configuration names are unique, but there are no configuration names in exports, + # so we use the closest unique field we have + defaults={"name": row["configuration_id"]}, ) return self.local_process.worker_runs.get_or_create( diff --git a/arkindex/process/migrations/0039_worker_configuration_name_not_empty.py b/arkindex/process/migrations/0039_worker_configuration_name_not_empty.py new file mode 100644 index 0000000000..fa85cdd989 --- /dev/null +++ b/arkindex/process/migrations/0039_worker_configuration_name_not_empty.py @@ -0,0 +1,47 @@ +# Generated by Django 5.0.6 on 2024-07-11 13:47 + +from django.core.validators import MinLengthValidator +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("process", "0038_remove_repository_worker_rights"), + ] + + operations = [ + # This does not make any change in the database, since validators are only Python-side + migrations.AlterField( + model_name="workerconfiguration", + name="name", + field=models.CharField( + max_length=250, + validators=[MinLengthValidator(1)], + ), + ), + # Give configurations with empty names some default name, "Configuration <n>" + migrations.RunSQL( + """ + WITH to_update (id, name) AS ( + SELECT id, 'Configuration ' || ROW_NUMBER() OVER (PARTITION BY worker_id ORDER BY id) + FROM process_workerconfiguration + WHERE name = '' + ) + UPDATE process_workerconfiguration + SET name = to_update.name + FROM to_update + WHERE process_workerconfiguration.id = to_update.id + """, + reverse_sql=migrations.RunSQL.noop, + elidable=True, + ), + migrations.AddConstraint( + model_name="workerconfiguration", + constraint=models.CheckConstraint( + check=~models.Q(name=""), + name="worker_configuration_name_not_empty", + violation_error_message="Worker configuration name cannot be empty.", + ), + ), + ] diff --git a/arkindex/process/models.py b/arkindex/process/models.py index e8dd6c7f7b..bd963b51ac 100644 --- a/arkindex/process/models.py +++ b/arkindex/process/models.py @@ -819,7 +819,7 @@ class WorkerVersion(models.Model): class WorkerConfiguration(IndexableModel): - name = models.CharField(max_length=250) + name = models.CharField(max_length=250, validators=[MinLengthValidator(1)]) configuration = models.JSONField(default=dict) configuration_hash = MD5HashField() archived = models.BooleanField(default=False) @@ -844,7 +844,12 @@ class WorkerConfiguration(IndexableModel): models.CheckConstraint( check=models.Q(configuration__typeof="object"), name="worker_configuration_configuration_objects", - ) + ), + models.CheckConstraint( + check=~Q(name=""), + name="worker_configuration_name_not_empty", + violation_error_message="Worker configuration name cannot be empty.", + ), ] -- GitLab