diff --git a/arkindex/documents/management/commands/load_export.py b/arkindex/documents/management/commands/load_export.py index 55ec306ee4752ba525ca7c99e850a55e76aff2ce..fcf94b613938f592423531dba08748e324b963ec 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 0000000000000000000000000000000000000000..fa85cdd9892304fd3e012986546d69fdc2b53408 --- /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 e8dd6c7f7b3b3ee3cc8e0ab72fd3c77c717b9624..bd963b51ac17a520f0d0631c0cfde391643654b2 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.", + ), ]