diff --git a/arkindex/documents/migrations/0001_initial.py b/arkindex/documents/migrations/0001_initial.py index 5d631e8b42b3516677b14075de5414e6cf0035cd..93e291d49f8c948473df6459e5b7275e34640bdc 100644 --- a/arkindex/documents/migrations/0001_initial.py +++ b/arkindex/documents/migrations/0001_initial.py @@ -1,44 +1,27 @@ -# Generated by Django 2.2.9 on 2020-01-17 15:39 +# Generated by Django 4.1.7 on 2023-05-29 11:49 import uuid import django.contrib.postgres.fields.hstore +import django.core.validators import django.db.models.deletion import enumfields.fields from django.db import migrations, models -from enumfields import Enum import arkindex.documents.dates import arkindex.documents.models +import arkindex.project.aws import arkindex.project.fields -class OldEntityType(Enum): - Person = 'person' - Location = 'location' - Subject = 'subject' - Organization = 'organization' - Misc = 'misc' - Number = 'number' - Date = 'date' - - class Migration(migrations.Migration): initial = True dependencies = [ - ('images', '0001_initial'), - ('process', '0001_initial'), ] operations = [ - # Leave this when resetting migrations to avoid issues with HStoreField - # django.db.utils.ProgrammingError: type "hstore" does not exist - migrations.RunSQL( - "CREATE EXTENSION IF NOT EXISTS hstore", - reverse_sql=migrations.RunSQL.noop, - ), migrations.CreateModel( name='AllowedMetaData', fields=[ @@ -62,25 +45,30 @@ class Migration(migrations.Migration): migrations.CreateModel( name='Corpus', fields=[ + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), ('name', models.CharField(max_length=250)), ('description', models.TextField(default='')), ('public', models.BooleanField(default=False)), + ('indexable', models.BooleanField(default=False)), ], options={ 'verbose_name_plural': 'corpora', }, ), migrations.CreateModel( - name='DataSource', + name='CorpusExport', fields=[ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('type', enumfields.fields.EnumField(enum=Enum('MLToolType', ''), max_length=10)), - ('slug', models.CharField(max_length=100)), - ('name', models.CharField(max_length=100)), - ('revision', models.CharField(max_length=100)), - ('internal', models.BooleanField()), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('state', enumfields.fields.EnumField(default='created', enum=arkindex.documents.models.CorpusExportState, max_length=10)), ], + options={ + 'abstract': False, + }, + bases=(arkindex.project.aws.S3FileMixin, models.Model), ), migrations.CreateModel( name='Element', @@ -89,10 +77,11 @@ class Migration(migrations.Migration): ('created', models.DateTimeField(auto_now_add=True)), ('updated', models.DateTimeField(auto_now=True)), ('name', models.CharField(max_length=250)), + ('polygon', arkindex.project.fields.LinearRingField(blank=True, null=True, srid=0)), + ('rotation_angle', models.SmallIntegerField(default=0, help_text='Clockwise rotation to apply to the image after cropping, in degrees.', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(359)])), + ('mirrored', models.BooleanField(default=False, help_text='Mirror the image along the vertical axis before rotating.')), + ('confidence', models.FloatField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(1)])), ], - options={ - 'abstract': False, - }, ), migrations.CreateModel( name='ElementPath', @@ -109,8 +98,7 @@ class Migration(migrations.Migration): ('slug', models.SlugField()), ('display_name', models.CharField(max_length=250)), ('folder', models.BooleanField(default=False)), - ('hidden', models.BooleanField(default=False)), - ('default_view', models.BooleanField(default=False)), + ('indexable', models.BooleanField(default=False)), ], ), migrations.CreateModel( @@ -118,141 +106,83 @@ class Migration(migrations.Migration): fields=[ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), ('name', models.TextField()), - ('type', enumfields.fields.EnumField(db_index=True, enum=OldEntityType, max_length=50)), ('metas', django.contrib.postgres.fields.hstore.HStoreField(blank=True, null=True)), ('validated', models.BooleanField(default=False)), - ('corpus', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='entities', to='documents.Corpus')), ], options={ 'verbose_name_plural': 'Entities', }, - bases=(arkindex.documents.dates.InterpretedDateMixin, models.Model), ), migrations.CreateModel( - name='MLClass', + name='EntityLink', fields=[ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('name', models.CharField(max_length=100)), - ('corpus', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ml_classes', to='documents.Corpus')), ], - options={ - 'verbose_name_plural': 'classes', - 'ordering': ('corpus', 'name'), - }, ), migrations.CreateModel( - name='Region', + name='EntityRole', fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('confidence', models.FloatField(blank=True, null=True)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('parent_name', models.CharField(max_length=250)), + ('child_name', models.CharField(max_length=250)), ], - options={ - 'default_related_name': 'regions', - }, ), migrations.CreateModel( - name='Transcription', + name='EntityType', fields=[ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('type', models.CharField(db_index=True, default='word', max_length=50)), - ('text', models.TextField(blank=True, null=True)), - ('score', models.FloatField(blank=True, null=True)), - ('element', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='transcriptions', to='documents.Element')), + ('name', models.CharField(max_length=250)), + ('color', models.CharField(default='ff0000', max_length=6)), ], ), migrations.CreateModel( - name='TranscriptionEntity', + name='MetaData', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('offset', models.PositiveIntegerField()), - ('length', models.PositiveIntegerField()), - ('entity', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='transcription_entities', to='documents.Entity')), - ('transcription', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='transcription_entities', to='documents.Transcription')), + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('name', models.CharField(max_length=250)), + ('type', enumfields.fields.EnumField(db_index=True, enum=arkindex.documents.models.MetaType, max_length=50)), + ('value', models.TextField()), ], - ), - migrations.AddField( - model_name='transcription', - name='entities', - field=models.ManyToManyField(related_name='transcriptions', through='documents.TranscriptionEntity', to='documents.Entity'), - ), - migrations.AddField( - model_name='transcription', - name='source', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='transcriptions', to='documents.DataSource'), - ), - migrations.AddField( - model_name='transcription', - name='zone', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='transcriptions', to='images.Zone'), + options={ + 'ordering': ('element', 'name', 'id'), + }, + bases=(arkindex.documents.dates.InterpretedDateMixin, models.Model), ), migrations.CreateModel( - name='RegionElement', + name='MLClass', fields=[ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('ordering', models.PositiveIntegerField(default=0)), - ('element', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='region_elements', to='documents.Element')), - ('region', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='region_elements', to='documents.Region')), + ('name', models.CharField(max_length=1024)), ], options={ - 'ordering': ('element', 'ordering'), - 'default_related_name': 'region_elements', + 'verbose_name_plural': 'classes', + 'ordering': ('corpus', 'name'), }, ), - migrations.AddField( - model_name='region', - name='elements', - field=models.ManyToManyField(related_name='regions', through='documents.RegionElement', to='documents.Element'), - ), - migrations.AddField( - model_name='region', - name='ml_class', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='regions', to='documents.MLClass'), - ), - migrations.AddField( - model_name='region', - name='source', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='regions', to='documents.DataSource'), - ), - migrations.AddField( - model_name='region', - name='zone', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='regions', to='images.Zone'), - ), migrations.CreateModel( - name='MetaData', + name='Selection', fields=[ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('name', models.CharField(max_length=250)), - ('type', enumfields.fields.EnumField(db_index=True, enum=arkindex.documents.models.MetaType, max_length=50)), - ('value', models.TextField()), - ('index', models.PositiveIntegerField(default=0)), - ('element', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='metadatas', to='documents.Element')), - ('entity', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='metadatas', to='documents.Entity')), - ('revision', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='process.Revision')), ], - options={ - 'ordering': ('element', 'name', 'index'), - }, - bases=(arkindex.documents.dates.InterpretedDateMixin, models.Model), ), migrations.CreateModel( - name='EntityRole', + name='Transcription', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('parent_name', models.CharField(max_length=250)), - ('child_name', models.CharField(max_length=250)), - ('parent_type', enumfields.fields.EnumField(enum=OldEntityType, max_length=50)), - ('child_type', enumfields.fields.EnumField(enum=OldEntityType, max_length=50)), - ('corpus', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='roles', to='documents.Corpus')), + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('text', models.TextField()), + ('orientation', enumfields.fields.EnumField(default='horizontal-lr', enum=arkindex.documents.models.TextOrientation, max_length=50)), + ('confidence', models.FloatField(blank=True, null=True)), ], ), migrations.CreateModel( - name='EntityLink', + name='TranscriptionEntity', fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('child', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='children', to='documents.Entity')), - ('parent', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='parents', to='documents.Entity')), - ('role', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='links', to='documents.EntityRole')), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('offset', models.PositiveIntegerField()), + ('length', models.PositiveIntegerField(validators=[django.core.validators.MinValueValidator(1)])), + ('confidence', models.FloatField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(1)])), + ('entity', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='transcription_entities', to='documents.entity')), + ('transcription', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='transcription_entities', to='documents.transcription')), ], ), ] diff --git a/arkindex/documents/migrations/0002_initial.py b/arkindex/documents/migrations/0002_initial.py index fdafe7182bb8b496cb121a736ecc629c22c995a7..f094cf105fd74ed61ca18b02b672a95ac94583ff 100644 --- a/arkindex/documents/migrations/0002_initial.py +++ b/arkindex/documents/migrations/0002_initial.py @@ -1,8 +1,6 @@ -# Generated by Django 2.2.9 on 2020-01-17 15:39 +# Generated by Django 4.1.7 on 2023-05-29 11:49 -import django.contrib.postgres.indexes import django.db.models.deletion -from django.conf import settings from django.db import migrations, models @@ -11,164 +9,44 @@ class Migration(migrations.Migration): initial = True dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('process', '0001_initial'), ('documents', '0001_initial'), - ('images', '0001_initial'), ] operations = [ migrations.AddField( - model_name='entity', - name='moderator', - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name='entities', - to=settings.AUTH_USER_MODEL, - ), + model_name='transcriptionentity', + name='worker_run', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='transcription_entities', to='process.workerrun'), ), migrations.AddField( - model_name='entity', - name='source', - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='entities', - to='documents.DataSource', - ), + model_name='transcriptionentity', + name='worker_version', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='transcription_entities', to='process.workerversion'), ), migrations.AddField( - model_name='elementtype', - name='corpus', - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='types', - to='documents.Corpus', - ), - ), - migrations.AddField( - model_name='elementpath', + model_name='transcription', name='element', - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='paths', - to='documents.Element', - ), + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='transcriptions', to='documents.element'), ), migrations.AddField( - model_name='element', - name='corpus', - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='elements', - to='documents.Corpus', - ), + model_name='transcription', + name='entities', + field=models.ManyToManyField(related_name='transcriptions', through='documents.TranscriptionEntity', to='documents.entity'), ), migrations.AddField( - model_name='element', - name='type', - field=models.ForeignKey( - on_delete=django.db.models.deletion.PROTECT, - related_name='elements', - to='documents.ElementType', - ), + model_name='transcription', + name='worker_run', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='transcriptions', to='process.workerrun'), ), migrations.AddField( - model_name='element', - name='zone', - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name='elements', - to='images.Zone', - ), - ), - migrations.AlterUniqueTogether( - name='datasource', - unique_together={('type', 'slug', 'revision')}, + model_name='transcription', + name='worker_version', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='transcriptions', to='process.workerversion'), ), migrations.AddField( - model_name='classification', + model_name='selection', name='element', - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='classifications', - to='documents.Element', - ), - ), - migrations.AddField( - model_name='classification', - name='ml_class', - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='classifications', - to='documents.MLClass', - ), - ), - migrations.AddField( - model_name='classification', - name='moderator', - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name='classifications', - to=settings.AUTH_USER_MODEL, - ), - ), - migrations.AddField( - model_name='classification', - name='source', - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='classifications', - to='documents.DataSource', - ), - ), - migrations.AddField( - model_name='allowedmetadata', - name='corpus', - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='allowed_metadatas', - to='documents.Corpus', - ), - ), - migrations.AlterUniqueTogether( - name='transcriptionentity', - unique_together={('transcription', 'entity', 'offset', 'length')}, - ), - migrations.AlterUniqueTogether( - name='regionelement', - unique_together={('element', 'region')}, - ), - migrations.AlterUniqueTogether( - name='mlclass', - unique_together={('name', 'corpus')}, - ), - migrations.AlterUniqueTogether( - name='metadata', - unique_together={('element', 'name', 'index')}, - ), - migrations.AlterUniqueTogether( - name='entityrole', - unique_together={('parent_name', 'child_name', 'parent_type', 'child_type', 'corpus')}, - ), - migrations.AddConstraint( - model_name='elementtype', - constraint=models.UniqueConstraint(fields=('corpus', 'slug'), name='corpus_unique_type_slug'), - ), - migrations.AddIndex( - model_name='elementpath', - index=django.contrib.postgres.indexes.GinIndex(fields=['path'], name='documents_e_path_15a4b8_gin'), - ), - migrations.AlterUniqueTogether( - name='classification', - unique_together={('element', 'source', 'ml_class')}, - ), - migrations.AlterUniqueTogether( - name='allowedmetadata', - unique_together={('corpus', 'type', 'name')}, + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='selections', to='documents.element'), ), ] diff --git a/arkindex/documents/migrations/0003_auto_20200218_1118.py b/arkindex/documents/migrations/0003_auto_20200218_1118.py deleted file mode 100644 index a3396c0aa07c05d61d820eff3da7f55abe9c5876..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0003_auto_20200218_1118.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 2.2.9 on 2020-02-18 11:18 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0002_initial'), - ] - - operations = [ - migrations.AlterField( - model_name='mlclass', - name='name', - field=models.CharField(max_length=1024), - ), - ] diff --git a/arkindex/documents/migrations/0003_initial.py b/arkindex/documents/migrations/0003_initial.py new file mode 100644 index 0000000000000000000000000000000000000000..0f37c575b7cbb7b51e88572a756ae6ebff23dc9d --- /dev/null +++ b/arkindex/documents/migrations/0003_initial.py @@ -0,0 +1,336 @@ +# Generated by Django 4.1.7 on 2023-05-29 11:49 + +import django.contrib.gis.db.models.functions +import django.contrib.postgres.constraints +import django.contrib.postgres.indexes +import django.db.models.constraints +import django.db.models.deletion +import django.db.models.functions.comparison +from django.conf import settings +from django.contrib.postgres.operations import BtreeGistExtension +from django.db import migrations, models + +import arkindex.documents.models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('process', '0002_initial'), + ('documents', '0002_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('images', '0001_initial'), + ] + + operations = [ + BtreeGistExtension(), + migrations.AddField( + model_name='selection', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='selections', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='mlclass', + name='corpus', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ml_classes', to='documents.corpus'), + ), + migrations.AddField( + model_name='metadata', + name='element', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='metadatas', to='documents.element'), + ), + migrations.AddField( + model_name='metadata', + name='entity', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='metadatas', to='documents.entity'), + ), + migrations.AddField( + model_name='metadata', + name='worker_run', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='metadatas', to='process.workerrun'), + ), + migrations.AddField( + model_name='metadata', + name='worker_version', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='metadatas', to='process.workerversion'), + ), + migrations.AddField( + model_name='entitytype', + name='corpus', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='entity_types', to='documents.corpus'), + ), + migrations.AddField( + model_name='entityrole', + name='child_type', + field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='child_role', to='documents.entitytype'), + ), + migrations.AddField( + model_name='entityrole', + name='corpus', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='roles', to='documents.corpus'), + ), + migrations.AddField( + model_name='entityrole', + name='parent_type', + field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='parent_role', to='documents.entitytype'), + ), + migrations.AddField( + model_name='entitylink', + name='child', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='children', to='documents.entity'), + ), + migrations.AddField( + model_name='entitylink', + name='parent', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='parents', to='documents.entity'), + ), + migrations.AddField( + model_name='entitylink', + name='role', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='links', to='documents.entityrole'), + ), + migrations.AddField( + model_name='entity', + name='corpus', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='entities', to='documents.corpus'), + ), + migrations.AddField( + model_name='entity', + name='moderator', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='entities', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='entity', + name='type', + field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='entities', to='documents.entitytype'), + ), + migrations.AddField( + model_name='entity', + name='worker_run', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='entities', to='process.workerrun'), + ), + migrations.AddField( + model_name='entity', + name='worker_version', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='entities', to='process.workerversion'), + ), + migrations.AddField( + model_name='elementtype', + name='corpus', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='types', to='documents.corpus'), + ), + migrations.AddField( + model_name='elementpath', + name='element', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='paths', to='documents.element'), + ), + migrations.AddField( + model_name='element', + name='corpus', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='elements', to='documents.corpus'), + ), + migrations.AddField( + model_name='element', + name='creator', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='elements', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='element', + name='image', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='elements', to='images.image'), + ), + migrations.AddField( + model_name='element', + name='type', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='elements', to='documents.elementtype'), + ), + migrations.AddField( + model_name='element', + name='worker_run', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='elements', to='process.workerrun'), + ), + migrations.AddField( + model_name='element', + name='worker_version', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='elements', to='process.workerversion'), + ), + migrations.AddField( + model_name='corpusexport', + name='corpus', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='exports', to='documents.corpus'), + ), + migrations.AddField( + model_name='corpusexport', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='exports', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='corpus', + name='top_level_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='top_level_corpora', to='documents.elementtype'), + ), + migrations.AddField( + model_name='classification', + name='element', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='classifications', to='documents.element'), + ), + migrations.AddField( + model_name='classification', + name='ml_class', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='classifications', to='documents.mlclass'), + ), + migrations.AddField( + model_name='classification', + name='moderator', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='classifications', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='classification', + name='worker_run', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='classifications', to='process.workerrun'), + ), + migrations.AddField( + model_name='classification', + name='worker_version', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='classifications', to='process.workerversion'), + ), + migrations.AddField( + model_name='allowedmetadata', + name='corpus', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='allowed_metadatas', to='documents.corpus'), + ), + migrations.AddConstraint( + model_name='transcriptionentity', + constraint=models.CheckConstraint(check=models.Q(('worker_version_id__isnull', False), ('worker_run_id__isnull', True), _connector='OR'), name='transcription_entity_worker_run_requires_worker_version'), + ), + migrations.AddConstraint( + model_name='transcriptionentity', + constraint=models.UniqueConstraint(condition=models.Q(('worker_version_id__isnull', True)), fields=('transcription', 'entity', 'offset', 'length'), name='transcription_entity_unique_manual'), + ), + migrations.AddConstraint( + model_name='transcriptionentity', + constraint=models.UniqueConstraint(condition=models.Q(('worker_run_id__isnull', True), ('worker_version_id__isnull', False)), fields=('transcription', 'entity', 'offset', 'length', 'worker_version'), name='transcription_entity_unique_worker_version'), + ), + migrations.AddConstraint( + model_name='transcriptionentity', + constraint=models.UniqueConstraint(condition=models.Q(('worker_run_id__isnull', False)), fields=('transcription', 'entity', 'offset', 'length', 'worker_run'), name='transcription_entity_unique_worker_run'), + ), + migrations.AddConstraint( + model_name='transcription', + constraint=models.CheckConstraint(check=models.Q(('worker_version_id__isnull', False), ('worker_run_id__isnull', True), _connector='OR'), name='transcription_worker_run_requires_worker_version'), + ), + migrations.AlterUniqueTogether( + name='selection', + unique_together={('element', 'user')}, + ), + migrations.AlterUniqueTogether( + name='mlclass', + unique_together={('name', 'corpus')}, + ), + migrations.AddIndex( + model_name='metadata', + index=models.Index(django.db.models.functions.comparison.Cast('value', output_field=models.FloatField()), condition=models.Q(('type', arkindex.documents.models.MetaType['Numeric'])), name='metadata_numeric_index'), + ), + migrations.AddConstraint( + model_name='metadata', + constraint=models.CheckConstraint(check=models.Q(models.Q(('type', arkindex.documents.models.MetaType['Numeric']), _negated=True), ('value__iregex', '^[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:E[+-]?\\d+)?$'), _connector='OR'), name='metadata_numeric_values'), + ), + migrations.AddConstraint( + model_name='metadata', + constraint=models.CheckConstraint(check=models.Q(('worker_version_id__isnull', False), ('worker_run_id__isnull', True), _connector='OR'), name='metadata_worker_run_requires_worker_version'), + ), + migrations.AlterUniqueTogether( + name='entitytype', + unique_together={('name', 'corpus')}, + ), + migrations.AlterUniqueTogether( + name='entityrole', + unique_together={('parent_name', 'child_name', 'parent_type', 'child_type', 'corpus')}, + ), + migrations.AddIndex( + model_name='entity', + index=models.Index(fields=['corpus_id', 'name', 'id'], name='entity_list_index'), + ), + migrations.AddConstraint( + model_name='entity', + constraint=models.CheckConstraint(check=models.Q(('worker_run_id__isnull', True), ('worker_version_id__isnull', False), _connector='OR'), name='entity_worker_run_requires_worker_version'), + ), + migrations.AddConstraint( + model_name='elementtype', + constraint=models.UniqueConstraint(fields=('corpus', 'slug'), name='corpus_unique_type_slug'), + ), + migrations.AddIndex( + model_name='elementpath', + index=django.contrib.postgres.indexes.GinIndex(fields=['path'], name='documents_e_path_15a4b8_gin'), + ), + migrations.AddIndex( + model_name='elementpath', + index=models.Index(models.F('path__last'), name='element_path_last'), + ), + migrations.AddConstraint( + model_name='elementpath', + constraint=models.UniqueConstraint(fields=('element', 'path'), name='unique_element_paths'), + ), + migrations.AddConstraint( + model_name='elementpath', + constraint=django.contrib.postgres.constraints.ExclusionConstraint(deferrable=django.db.models.constraints.Deferrable['DEFERRED'], expressions=[('element', '='), (django.db.models.functions.comparison.Least('path__len', 1), '<>')], name='unique_top_level'), + ), + migrations.AddConstraint( + model_name='elementpath', + constraint=django.contrib.postgres.constraints.ExclusionConstraint(deferrable=django.db.models.constraints.Deferrable['DEFERRED'], expressions=[('element', '='), ('path__last', '='), ('ordering', '<>')], name='unique_element_orderings'), + ), + migrations.AddConstraint( + model_name='elementpath', + constraint=django.contrib.postgres.constraints.ExclusionConstraint(deferrable=django.db.models.constraints.Deferrable['DEFERRED'], expressions=[('path__last', '='), ('ordering', '='), ('element', '<>')], name='unique_parent_orderings'), + ), + migrations.AddConstraint( + model_name='element', + constraint=models.CheckConstraint(check=models.Q(models.Q(('image_id', None), ('polygon', None)), models.Q(models.Q(('image_id', None), ('polygon', None), _connector='OR'), _negated=True), _connector='OR'), name='element_image_and_polygon'), + ), + migrations.AddConstraint( + model_name='element', + constraint=models.CheckConstraint(check=models.Q(('polygon', None), ('polygon__isclosed', True), _connector='OR'), name='element_polygon_closed'), + ), + migrations.AddConstraint( + model_name='element', + constraint=models.CheckConstraint(check=models.Q(('polygon', None), ('polygon', django.contrib.gis.db.models.functions.SnapToGrid('polygon', 1)), _connector='OR'), name='element_polygon_integer_coordinates'), + ), + migrations.AddConstraint( + model_name='element', + constraint=models.CheckConstraint(check=models.Q(('polygon', None), ('polygon__numpoints__gte', 4), _connector='OR'), name='element_polygon_size'), + ), + migrations.AddConstraint( + model_name='element', + constraint=models.CheckConstraint(check=models.Q(('rotation_angle__gte', 0), ('rotation_angle__lte', 359)), name='element_rotation_angle'), + ), + migrations.AddConstraint( + model_name='element', + constraint=models.CheckConstraint(check=models.Q(('creator_id', None), ('worker_version_id', None), _connector='OR'), name='element_creator_nand_worker_version'), + ), + migrations.AddConstraint( + model_name='element', + constraint=models.CheckConstraint(check=models.Q(('worker_run_id__isnull', True), ('worker_version_id__isnull', False), _connector='OR'), name='element_worker_run_requires_worker_version'), + ), + migrations.AddConstraint( + model_name='classification', + constraint=models.CheckConstraint(check=models.Q(('worker_version_id__isnull', False), ('worker_run_id__isnull', True), _connector='OR'), name='classification_worker_run_requires_worker_version'), + ), + migrations.AddConstraint( + model_name='classification', + constraint=models.UniqueConstraint(condition=models.Q(('worker_version_id__isnull', True)), fields=('element', 'ml_class'), name='classification_unique_manual'), + ), + migrations.AddConstraint( + model_name='classification', + constraint=models.UniqueConstraint(condition=models.Q(('worker_run_id__isnull', True), ('worker_version_id__isnull', False)), fields=('element', 'ml_class', 'worker_version'), name='classification_unique_worker_version'), + ), + migrations.AddConstraint( + model_name='classification', + constraint=models.UniqueConstraint(condition=models.Q(('worker_run_id__isnull', False)), fields=('element', 'ml_class', 'worker_run'), name='classification_unique_worker_run'), + ), + migrations.AlterUniqueTogether( + name='allowedmetadata', + unique_together={('corpus', 'type', 'name')}, + ), + ] diff --git a/arkindex/documents/migrations/0004_remove_elementtype_hidden.py b/arkindex/documents/migrations/0004_remove_elementtype_hidden.py deleted file mode 100644 index 6307e1346a5f579119b8b710f412ac13060fd9e0..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0004_remove_elementtype_hidden.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 2.2.10 on 2020-03-05 13:20 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0003_auto_20200218_1118'), - ] - - operations = [ - migrations.RemoveField( - model_name='elementtype', - name='hidden', - ), - ] diff --git a/arkindex/documents/migrations/0005_element_source.py b/arkindex/documents/migrations/0005_element_source.py deleted file mode 100644 index f29467f574da7d6a80a557cadb2cb12bdc917a7b..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0005_element_source.py +++ /dev/null @@ -1,25 +0,0 @@ -# Generated by Django 2.2.10 on 2020-03-10 10:17 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0004_remove_elementtype_hidden'), - ] - - operations = [ - migrations.AddField( - model_name='element', - name='source', - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name='elements', - to='documents.DataSource', - ), - ), - ] diff --git a/arkindex/documents/migrations/0006_preflight.py b/arkindex/documents/migrations/0006_preflight.py deleted file mode 100644 index 8266824a1927d868403089abdafe28db7c5dc3c8..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0006_preflight.py +++ /dev/null @@ -1,28 +0,0 @@ -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0005_element_source'), - ] - - operations = [ - # Remove extra regions tied to several elements - # We can't to keep the first region element item to preserve the link - # for the followup migration - migrations.RunSQL( - """ - SELECT region_id, array_agg(id) as ids into remove FROM documents_regionelement - GROUP BY region_id - HAVING COUNT(region_id) > 1; - - DELETE FROM documents_regionelement WHERE id in - (select unnest(ids[2:]) from remove); - - DROP table remove; - """, - reverse_sql=migrations.RunSQL.noop, - elidable=True, - ), - ] diff --git a/arkindex/documents/migrations/0006_region_fk.py b/arkindex/documents/migrations/0006_region_fk.py deleted file mode 100644 index fdb8f4e27150c72d1031f51b2c28a4208bd7c450..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0006_region_fk.py +++ /dev/null @@ -1,54 +0,0 @@ -from django.db import migrations, models - - -def check_m2m(apps, schema_editor): - """ - Ensure the RegionElement many-to-many relationship only has one - element per region, making it possible to turn it into a foreign key. - """ - db_alias = schema_editor.connection.alias - RegionElement = apps.get_model('documents', 'RegionElement') - duplicates = RegionElement \ - .objects \ - .using(db_alias) \ - .values('region_id') \ - .annotate(count=models.Count('id')) \ - .filter(count__gt=1) - assert not duplicates.exists(), 'Some regions are linked to more than one element.' - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0006_preflight'), - ] - - operations = [ - # Initial check before turning the M2M into a foreign key - migrations.RunPython( - check_m2m, - reverse_code=migrations.RunPython.noop, - elidable=True, - ), - # Rename the Regions M2M to avoid a collision on Element.regions - migrations.AlterField( - model_name='Region', - name='elements', - field=models.ManyToManyField( - related_name='regions_m2m', - through='documents.RegionElement', - to='documents.Element', - ), - ), - # Add the new foreign key - migrations.AddField( - model_name='Region', - name='element', - field=models.ForeignKey( - on_delete=models.deletion.CASCADE, - related_name='regions', - to='documents.Element', - null=True, - ), - ), - ] diff --git a/arkindex/documents/migrations/0007_fill_region_fk.py b/arkindex/documents/migrations/0007_fill_region_fk.py deleted file mode 100644 index 9c5d736b73ff22768c51a2e280a2d87fe253b2d8..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0007_fill_region_fk.py +++ /dev/null @@ -1,24 +0,0 @@ -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0006_region_fk'), - ] - - operations = [ - # Move RegionElement.element_id to Region.element_id - # and remove regions that will not be migrated into elements - migrations.RunSQL( - """ - UPDATE documents_region - SET element_id = documents_regionelement.element_id - FROM documents_regionelement - WHERE documents_regionelement.region_id = documents_region.id; - DELETE FROM documents_region WHERE element_id IS NULL; - """, - reverse_sql=migrations.RunSQL.noop, - elidable=True, - ), - ] diff --git a/arkindex/documents/migrations/0008_remove_regionelement.py b/arkindex/documents/migrations/0008_remove_regionelement.py deleted file mode 100644 index ffa89a28b9175e07e60ea8f2684e0b957b5bd281..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0008_remove_regionelement.py +++ /dev/null @@ -1,41 +0,0 @@ -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0007_fill_region_fk'), - ] - - operations = [ - # Make the foreign key non-nullable - migrations.AlterField( - model_name='Region', - name='element', - field=models.ForeignKey( - on_delete=models.deletion.CASCADE, - related_name='regions', - to='documents.Element', - ), - ), - # Drop RegionElement - migrations.RemoveField( - model_name='Region', - name='elements', - ), - migrations.AlterUniqueTogether( - name='RegionElement', - unique_together=None, - ), - migrations.RemoveField( - model_name='RegionElement', - name='element', - ), - migrations.RemoveField( - model_name='RegionElement', - name='region', - ), - migrations.DeleteModel( - name='RegionElement', - ), - ] diff --git a/arkindex/documents/migrations/0009_migrate_regions.py b/arkindex/documents/migrations/0009_migrate_regions.py deleted file mode 100644 index 92942b0f42e7cadd30e0b30737f7ce236934771b..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0009_migrate_regions.py +++ /dev/null @@ -1,84 +0,0 @@ -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0008_remove_regionelement'), - ] - - operations = [ - # This performs the whole regions migration in just a few SQL queries - # by exploiting the fact that UUIDs have a lot of combinations and it is - # reasonable to assume that they are unique even across tables. - - # This turns MLClass IDs into element type IDs and region IDs into element IDs. - # This way, no checks are required to ensure the foreign key constraints are respected. - # The element names are generated as the class name and a number grouped by parent element. - # Then, element paths are created in two steps: - # * Create the paths from scratch for regions whose elements do not have paths; - # * Create the paths for regions whose elements already have paths by prepending the element ID to all paths. - # We do not have to care about existing paths, cycles or existing orderings since - # everything is in a transaction and uses new types. - - # The uuid-ossp Postgres extension is required to generate new UUIDs - # for classifications as those are created from scratch - # and Django handles defaults only in Python, not in the database. - - migrations.RunSQL( - """ - CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; - - INSERT INTO documents_elementtype (id, corpus_id, slug, display_name, folder, default_view) - SELECT id, corpus_id, 'region_' || name, name || ' region', FALSE, FALSE - FROM documents_mlclass - WHERE id in (SELECT DISTINCT ml_class_id FROM documents_region); - - INSERT INTO documents_element (id, corpus_id, type_id, name, zone_id, source_id, created, updated) - SELECT - region.id, - ml_class.corpus_id, - region.ml_class_id, - ml_class.name || ' ' || ROW_NUMBER() OVER ( - PARTITION BY region.element_id, region.ml_class_id ORDER BY region.id - ), - region.zone_id, - region.source_id, - CURRENT_TIMESTAMP, - CURRENT_TIMESTAMP - FROM documents_region region - LEFT JOIN documents_mlclass ml_class - ON (region.ml_class_id = ml_class.id); - - INSERT INTO documents_classification - (id, element_id, source_id, ml_class_id, confidence, high_confidence, state) - SELECT uuid_generate_v4(), id, source_id, ml_class_id, confidence, TRUE, 'pending' - FROM documents_region; - - INSERT INTO documents_elementpath (id, element_id, path, ordering) - SELECT - uuid_generate_v4(), - id, - ARRAY[element_id], - ROW_NUMBER() OVER ( - PARTITION BY element_id, ml_class_id ORDER BY id - ) - 1 - FROM documents_region - WHERE element_id NOT IN (SELECT element_id FROM documents_elementpath); - - INSERT INTO documents_elementpath (id, element_id, path, ordering) - SELECT - uuid_generate_v4(), - region.id, - ep.path || element_id, - ROW_NUMBER() OVER ( - PARTITION BY element_id, region.ml_class_id, ep.path[array_length(ep.path, 1)] ORDER BY region.id - ) - 1 - FROM documents_elementpath ep - FULL JOIN documents_region region USING (element_id) - WHERE region.id IS NOT NULL; - """, - reverse_sql=migrations.RunSQL.noop, - elidable=True, - ), - ] diff --git a/arkindex/documents/migrations/0010_remove_region.py b/arkindex/documents/migrations/0010_remove_region.py deleted file mode 100644 index 44840b792bbd83040aa6e767226a9c21053c5ccb..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0010_remove_region.py +++ /dev/null @@ -1,16 +0,0 @@ -# Generated by Django 2.2.10 on 2020-03-18 10:09 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0009_migrate_regions'), - ] - - operations = [ - migrations.DeleteModel( - name='Region', - ), - ] diff --git a/arkindex/documents/migrations/0011_auto_20200403_1456.py b/arkindex/documents/migrations/0011_auto_20200403_1456.py deleted file mode 100644 index de7be88dc8759b64e9a1b714fc81c14c47fd6481..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0011_auto_20200403_1456.py +++ /dev/null @@ -1,28 +0,0 @@ -# Generated by Django 2.2.10 on 2020-04-03 14:56 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0010_remove_region'), - ] - - operations = [ - migrations.AlterField( - model_name='transcription', - name='text', - field=models.TextField(), - ), - migrations.AlterField( - model_name='transcription', - name='zone', - field=models.ForeignKey( - on_delete=django.db.models.deletion.PROTECT, - related_name='transcriptions', - to='images.Zone', - ), - ), - ] diff --git a/arkindex/documents/migrations/0012_add_created_updated_corpus.py b/arkindex/documents/migrations/0012_add_created_updated_corpus.py deleted file mode 100644 index 45ba4088ab9b6e03fbf81a127b2e3b75f31131d5..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0012_add_created_updated_corpus.py +++ /dev/null @@ -1,25 +0,0 @@ -# Generated by Django 2.2.11 on 2020-05-08 07:51 - -import django.utils.timezone -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0011_auto_20200403_1456'), - ] - - operations = [ - migrations.AddField( - model_name='corpus', - name='created', - field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now), - preserve_default=False, - ), - migrations.AddField( - model_name='corpus', - name='updated', - field=models.DateTimeField(auto_now=True), - ), - ] diff --git a/arkindex/documents/migrations/0013_datasource_type_length.py b/arkindex/documents/migrations/0013_datasource_type_length.py deleted file mode 100644 index d9b10a58b7003c7dc119244b83a1503ae9077bad..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0013_datasource_type_length.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 2.2.10 on 2020-05-19 14:59 - -from enum import Enum - -import enumfields.fields -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0012_add_created_updated_corpus'), - ] - - operations = [ - migrations.AlterField( - model_name='datasource', - name='type', - field=enumfields.fields.EnumField(enum=Enum('MLToolType', ''), max_length=50), - ), - ] diff --git a/arkindex/documents/migrations/0014_nullable_transcription_zone.py b/arkindex/documents/migrations/0014_nullable_transcription_zone.py deleted file mode 100644 index b85d8fd846fbdfe76eb052af3cb1c5800d784430..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0014_nullable_transcription_zone.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 2.2.9 on 2020-05-27 09:03 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0013_datasource_type_length'), - ] - - operations = [ - migrations.AlterField( - model_name='transcription', - name='zone', - field=models.ForeignKey( - null=True, - on_delete=django.db.models.deletion.PROTECT, - related_name='transcriptions', - to='images.Zone' - ), - ), - ] diff --git a/arkindex/documents/migrations/0015_elementtype_allowed_transcription.py b/arkindex/documents/migrations/0015_elementtype_allowed_transcription.py deleted file mode 100644 index cec7e56a12fe7c5b4cf9a7d0dfbf5e7f63153c0e..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0015_elementtype_allowed_transcription.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 2.2.9 on 2020-06-03 13:26 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0014_nullable_transcription_zone'), - ] - - operations = [ - migrations.AddField( - model_name='elementtype', - name='allowed_transcription', - field=models.CharField( - blank=True, - max_length=10, - null=True - ), - ), - ] diff --git a/arkindex/documents/migrations/0016_selection.py b/arkindex/documents/migrations/0016_selection.py deleted file mode 100644 index 8f90a4ef6a37de4ce75c7c3d43921b2222f85f64..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0016_selection.py +++ /dev/null @@ -1,37 +0,0 @@ -# Generated by Django 2.2.13 on 2020-06-23 14:07 - -import uuid - -import django.db.models.deletion -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('documents', '0015_elementtype_allowed_transcription'), - ] - - operations = [ - migrations.CreateModel( - name='Selection', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('element', models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='selections', - to='documents.Element', - )), - ('user', models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='selections', - to=settings.AUTH_USER_MODEL, - )), - ], - options={ - 'unique_together': {('element', 'user')}, - }, - ), - ] diff --git a/arkindex/documents/migrations/0017_remove_elementtype_default_view.py b/arkindex/documents/migrations/0017_remove_elementtype_default_view.py deleted file mode 100644 index 96154183554fc8437e47842c9fcaaeab5319b7c1..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0017_remove_elementtype_default_view.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 2.2.13 on 2020-06-25 12:39 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0016_selection'), - ] - - operations = [ - migrations.RemoveField( - model_name='elementtype', - name='default_view', - ), - ] diff --git a/arkindex/documents/migrations/0018_worker_version_attributes.py b/arkindex/documents/migrations/0018_worker_version_attributes.py deleted file mode 100644 index c0d670af4a529d11af6d119236c01ceb4a9bd6ab..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0018_worker_version_attributes.py +++ /dev/null @@ -1,66 +0,0 @@ -# Generated by Django 2.2.13 on 2020-08-10 10:00 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0015_clear_payload'), - ('documents', '0017_remove_elementtype_default_view'), - ] - - operations = [ - migrations.AddField( - model_name='element', - name='worker_version', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='elements', to='process.WorkerVersion'), - ), - migrations.AddField( - model_name='transcription', - name='worker_version', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='transcriptions', to='process.WorkerVersion'), - ), - migrations.AlterField( - model_name='transcription', - name='source', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='transcriptions', to='documents.DataSource'), - ), - migrations.AddField( - model_name='classification', - name='worker_version', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='classifications', to='process.WorkerVersion'), - ), - migrations.AlterField( - model_name='classification', - name='source', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='classifications', to='documents.DataSource'), - ), - migrations.AlterUniqueTogether( - name='classification', - unique_together=set(), - ), - migrations.AddConstraint( - model_name='classification', - constraint=models.UniqueConstraint(condition=models.Q(worker_version_id__isnull=True), fields=('element', 'ml_class', 'source'), name='classification_unique_source'), - ), - migrations.AddConstraint( - model_name='classification', - constraint=models.UniqueConstraint(condition=models.Q(source_id__isnull=True), fields=('element', 'ml_class', 'worker_version'), name='classification_unique_worker_version'), - ), - migrations.AddConstraint( - model_name='classification', - constraint=models.CheckConstraint(check=models.Q(models.Q(('source_id__isnull', False), ('worker_version_id__isnull', True)), models.Q(('source_id__isnull', True), ('worker_version_id__isnull', False)), _connector='OR'), name='classification_source_xor_workerversion'), - ), - migrations.AddField( - model_name='entity', - name='worker_version', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='entities', to='process.WorkerVersion'), - ), - migrations.AlterField( - model_name='entity', - name='source', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='entities', to='documents.DataSource'), - ), - ] diff --git a/arkindex/documents/migrations/0019_corpus_repository.py b/arkindex/documents/migrations/0019_corpus_repository.py deleted file mode 100644 index 350c4465f4d7ed4fb4e59fa037d1421b7eff497f..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0019_corpus_repository.py +++ /dev/null @@ -1,40 +0,0 @@ -# Generated by Django 3.1 on 2020-09-11 07:26 - -import django.db.models.deletion -from django.db import migrations, models - -import arkindex.process.models - - -def copy_repository_corpus(apps, schema_editor): - Corpus = apps.get_model('documents', 'Corpus') - for corpus in Corpus.objects.all(): - repos = list(corpus.repos.filter(type=arkindex.process.models.RepositoryType.IIIF)) - if len(repos) == 0: - continue - elif len(repos) == 1: - corpus.repository = repos[0] - else: - raise Exception(f'"{corpus.name}" corpus is referenced by multiple IIIF repositories: {[r.url for r in repos]}') - corpus.save() - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0019_repository_type'), - ('documents', '0018_worker_version_attributes'), - ] - - operations = [ - migrations.AddField( - model_name='corpus', - name='repository', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='corpora', to='process.repository'), - ), - migrations.RunPython( - copy_repository_corpus, - reverse_code=migrations.RunPython.noop, - elidable=True - ) - ] diff --git a/arkindex/documents/migrations/0020_remove_source_xor_version_constraint.py b/arkindex/documents/migrations/0020_remove_source_xor_version_constraint.py deleted file mode 100644 index 8907ff7578fcfdd2237963ec17610a08c7470a2c..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0020_remove_source_xor_version_constraint.py +++ /dev/null @@ -1,33 +0,0 @@ -# Generated by Django 3.1 on 2020-10-14 13:56 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0019_corpus_repository'), - ] - - operations = [ - migrations.RemoveConstraint( - model_name='classification', - name='classification_unique_source', - ), - migrations.RemoveConstraint( - model_name='classification', - name='classification_unique_worker_version', - ), - migrations.RemoveConstraint( - model_name='classification', - name='classification_source_xor_workerversion', - ), - migrations.AddConstraint( - model_name='classification', - constraint=models.UniqueConstraint(condition=models.Q(('source_id__isnull', True), ('worker_version_id__isnull', True)), fields=('element', 'ml_class'), name='classification_unique_manual'), - ), - migrations.AddConstraint( - model_name='classification', - constraint=models.UniqueConstraint(condition=models.Q(('source_id__isnull', True), ('worker_version_id__isnull', False)), fields=('element', 'ml_class', 'worker_version'), name='classification_unique_worker_version'), - ), - ] diff --git a/arkindex/documents/migrations/0021_move_transcriptions.py b/arkindex/documents/migrations/0021_move_transcriptions.py deleted file mode 100644 index 7c4566b39314e7640952d0951298abd2b34fa255..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0021_move_transcriptions.py +++ /dev/null @@ -1,132 +0,0 @@ -# Generated by Django 3.1 on 2020-09-01 07:48 - -from django.db import migrations, models - - -def preflight_checks(apps, schema_editor): - ElementType = apps.get_model('documents', 'ElementType') - Transcription = apps.get_model('documents', 'Transcription') - existing_types = [] - - for ts_type in Transcription.objects.values('type').distinct(): - if ElementType.objects.filter(slug=f'transcription_{ts_type}').exists(): - existing_types.append(f'`transcription_{ts_type}`') - - if existing_types: - raise AssertionError( - 'This migration could not be run because one or more element types use the reserved slug(s) ' - + ', '.join(existing_types) - ) - - -FORWARD_SQL = [ - 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp";', - # Early handling for the edge case of transcriptions already on the correct element - """ - UPDATE documents_transcription transcription - SET zone_id = NULL - FROM documents_element element - WHERE transcription.element_id = element.id - AND transcription.zone_id IS NOT NULL - AND transcription.zone_id = element.zone_id; - """, - # Create element types starting with transcription_* as needed - """ - INSERT INTO documents_elementtype (id, corpus_id, slug, display_name, folder, allowed_transcription) - SELECT - uuid_generate_v4(), - element.corpus_id, - 'transcription_' || transcription.type, - initcap(transcription.type) || ' Transcription', - FALSE, - transcription.type - FROM documents_transcription transcription - INNER JOIN documents_element element ON (element.id = transcription.element_id) - WHERE transcription.zone_id IS NOT NULL - GROUP BY element.corpus_id, transcription.type; - """, - # Create new elements - """ - INSERT INTO documents_element (id, corpus_id, type_id, name, zone_id, source_id, worker_version_id, created, updated) - SELECT - transcription.id, - element.corpus_id, - type.id, - (ROW_NUMBER() OVER ( - PARTITION BY - transcription.element_id, - transcription.source_id, - transcription.worker_version_id, - transcription.type - ORDER BY - ST_Y(ST_StartPoint(polygon)), - ST_X(ST_StartPoint(polygon)) - ))::varchar, - transcription.zone_id, - transcription.source_id, - transcription.worker_version_id, - NOW(), - NOW() - FROM - documents_transcription transcription - INNER JOIN documents_element element on (transcription.element_id = element.id) - INNER JOIN documents_elementtype type ON (type.corpus_id = element.corpus_id AND type.slug = 'transcription_' || transcription.type) - INNER JOIN images_zone zone ON (transcription.zone_id = zone.id); - """, - # Create element paths - # Append to existing parent paths of the parent element, or create one new element path with the parent element itself in it - """ - INSERT INTO documents_elementpath (id, element_id, path, ordering) - SELECT - uuid_generate_v4(), - transcription.id, - COALESCE(path.path, ARRAY[]::uuid[]) || transcription.element_id, - ROW_NUMBER() OVER ( - PARTITION BY transcription.element_id - ORDER BY - ST_Y(ST_StartPoint(polygon)), - ST_X(ST_StartPoint(polygon)) - ) - FROM - documents_transcription transcription - INNER JOIN images_zone zone ON (zone.id = transcription.zone_id) - LEFT JOIN documents_elementpath path ON (path.element_id = transcription.element_id); - """, - # Move transcriptions to their new elements - """ - UPDATE documents_transcription - SET element_id = id - WHERE zone_id IS NOT NULL; - """, - # At this point, we can drop the zone column, but this would fail due to 'pending trigger events' - # Postgres does not allow editing the schema *after* editing the data in the same transcription; - # This migration is continued in documents.0021 to allow a new database transaction to happen. -] - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0020_remove_source_xor_version_constraint'), - ('images', '0005_polygon_index') - ] - - operations = [ - migrations.AddConstraint( - model_name='transcription', - constraint=models.CheckConstraint( - check=~models.Q(source_id__isnull=False, worker_version_id__isnull=False), - name='transcription_source_not_worker_version', - ) - ), - migrations.RunPython( - preflight_checks, - reverse_code=migrations.RunPython.noop, - elidable=True, - ), - migrations.RunSQL( - FORWARD_SQL, - reverse_sql=migrations.RunSQL.noop, - elidable=True, - ), - ] diff --git a/arkindex/documents/migrations/0022_remove_transcription_zone.py b/arkindex/documents/migrations/0022_remove_transcription_zone.py deleted file mode 100644 index edb333dab4f65cef1068ba654291e1468a32a201..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0022_remove_transcription_zone.py +++ /dev/null @@ -1,80 +0,0 @@ -# Generated by Django 3.1 on 2020-09-01 07:48 - -from django.db import migrations - -FORWARD_SQL = [ - # Use a temporary table here to iterate over transcriptions just once before deleting, - # causing this migration to only take a few minutes - # Note the strange join conditions as either source_id or worker_version_id are NULL, - # which causes a NATURAL JOIN or a JOIN … USING to fail since comparing NULLs returns NULL. - """ - CREATE TEMPORARY TABLE duplicate_ids AS - WITH filters AS ( - SELECT - sub.*, - FIRST_VALUE(id) OVER ( - PARTITION BY - transcription.element_id, - transcription.source_id, - transcription.worker_version_id - ) AS keep_id - FROM documents_transcription transcription - INNER JOIN ( - SELECT element_id, source_id, worker_version_id - FROM documents_transcription - GROUP BY element_id, source_id, worker_version_id - HAVING COUNT(*) > 1 - ) sub ON ( - sub.element_id = transcription.element_id AND ( - sub.source_id = transcription.source_id - OR sub.worker_version_id = transcription.worker_version_id - ) - ) - ) - SELECT id - FROM documents_transcription transcription - INNER JOIN filters ON ( - filters.element_id = transcription.element_id AND ( - filters.source_id = transcription.source_id - OR filters.worker_version_id = transcription.worker_version_id - ) - ) - WHERE keep_id != id; - """, - # Remove any TranscriptionEntity that could be linked to the duplicate transcriptions - """ - DELETE FROM documents_transcriptionentity transcriptionentity - USING duplicate_ids - WHERE transcriptionentity.transcription_id = duplicate_ids.id; - """, - # Remove duplicate transcriptions - """ - DELETE FROM documents_transcription transcription - USING duplicate_ids - WHERE transcription.id = duplicate_ids.id; - """, - 'DROP TABLE duplicate_ids;', -] - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0021_move_transcriptions'), - ] - - operations = [ - migrations.RemoveField( - model_name='transcription', - name='zone', - ), - # Remove the few remaining transcriptions that would break the unique constraints we will add in documents.0023. - # Those are transcriptions from the same source, on the same element, with the exact same zones. - # This query is rather complex as we want to only remove duplicates, and window functions have their limits, - # but the GROUP BY…HAVING will quickly exclude most of the table so it isn't slow. - migrations.RunSQL( - FORWARD_SQL, - reverse_sql=migrations.RunSQL.noop, - elidable=True, - ), - ] diff --git a/arkindex/documents/migrations/0023_remove_transcription_type.py b/arkindex/documents/migrations/0023_remove_transcription_type.py deleted file mode 100644 index 7d1c474b016cf59e1cf22da9a70ac1c7b55166ae..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0023_remove_transcription_type.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 3.1.3 on 2020-11-23 14:35 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0022_remove_transcription_zone'), - ] - - operations = [ - migrations.RemoveField( - model_name='elementtype', - name='allowed_transcription', - ), - migrations.RemoveField( - model_name='transcription', - name='type', - ), - ] diff --git a/arkindex/documents/migrations/0024_migrate_datasource.py b/arkindex/documents/migrations/0024_migrate_datasource.py deleted file mode 100644 index f52bb4c9cfeac673806275e1570906c237783686..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0024_migrate_datasource.py +++ /dev/null @@ -1,135 +0,0 @@ -# Generated by Django 3.1.3 on 2020-11-30 10:40 - -import os -import uuid - -from django.db import migrations, models - - -def migrate_data_sources(apps, schema_editor): - DataSource = apps.get_model('documents', 'DataSource') - if not DataSource.objects.exists(): - return - - repo_prefix = os.environ.get('REPOSITORY_PREFIX', 'https://gitlab.com/teklia/workers') - - Element = apps.get_model('documents', 'Element') - Classification = apps.get_model('documents', 'Classification') - Transcription = apps.get_model('documents', 'Transcription') - Entity = apps.get_model('documents', 'Entity') - Repository = apps.get_model('process', 'Repository') - Worker = apps.get_model('process', 'Worker') - - # Start by just removing the manual source, since a manual worker version is just None - print('Migrating manual sources…') - Element.objects.filter(source__slug='manual').update(source=None) - Classification.objects.filter(source__slug='manual').update(source=None) - Transcription.objects.filter(source__slug='manual').update(source=None) - Entity.objects.filter(source__slug='manual').update(source=None) - - # Only migrate sources that have related objects - to_migrate = DataSource.objects.filter( - id__in=Element.objects.values('source_id').union( - Classification.objects.values('source_id') - ).union( - Transcription.objects.values('source_id') - ).union( - Entity.objects.values('source_id') - ) - ) - for source in to_migrate: - print(f'Migrating {source.name} {source.revision} ({source.id})…') - repo, _ = Repository.objects.get_or_create( - url=f'{repo_prefix}/{source.slug}', - type='worker', - defaults={ - # This is supposed to be unique - 'hook_token': str(source.id), - }, - ) - worker, _ = Worker.objects.get_or_create( - repository=repo, - slug=source.slug, - defaults={ - 'name': source.name, - 'type': str(source.type), - } - ) - - # To ensure we cannot get duplicate worker version IDs when re-applying - # unique constraints later, we just keep on trying to get a new revision. - created = False - while not created: - revision, created = repo.revisions.get_or_create( - hash=uuid.uuid4().hex, - message='Migrated DataSource', - author='Arkindex', - ) - - version = worker.workerversion_set.create( - revision=revision, - configuration={}, - ) - - source.elements.update(source=None, worker_version=version) - source.classifications.update(source=None, worker_version=version) - source.transcriptions.update(source=None, worker_version=version) - source.entities.update(source=None, worker_version=version) - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0023_remove_transcription_type'), - ] - - operations = [ - migrations.AlterField( - model_name='DataSource', - name='type', - field=models.CharField(max_length=50), - ), - migrations.RemoveConstraint( - model_name='classification', - name='classification_unique_manual', - ), - migrations.RemoveConstraint( - model_name='classification', - name='classification_unique_worker_version', - ), - migrations.RemoveConstraint( - model_name='transcription', - name='transcription_source_not_worker_version', - ), - migrations.RunPython( - code=migrate_data_sources, - reverse_code=migrations.RunPython.noop, - elidable=True, - ), - # Duplicate classifications may still remain - migrations.RunSQL( - """ - DELETE FROM documents_classification WHERE id IN ( - SELECT id - FROM ( - SELECT c.id, ROW_NUMBER() OVER ( - PARTITION BY x.element_id - ORDER BY c.confidence DESC - ) AS nb - FROM ( - SELECT element_id, ml_class_id - FROM documents_classification - GROUP BY element_id, ml_class_id - HAVING COUNT(id) > 1 - ) AS x - INNER JOIN documents_classification AS c USING (element_id, ml_class_id) - ) AS y - WHERE y.nb > 1 - ); - """, - reverse_sql=migrations.RunSQL.noop, - elidable=True, - ), - # Deletion happens in another migration, since updating data then trying to update - # the structure causes errors with 'pending trigger events' - ] diff --git a/arkindex/documents/migrations/0025_drop_datasource.py b/arkindex/documents/migrations/0025_drop_datasource.py deleted file mode 100644 index 2f0bd0c09011bb065b0928b4fb156b33a8e98f20..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0025_drop_datasource.py +++ /dev/null @@ -1,52 +0,0 @@ -# Generated by Django 3.1.3 on 2020-12-10 13:57 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0024_migrate_datasource'), - ] - - operations = [ - migrations.AlterUniqueTogether( - name='datasource', - unique_together=None, - ), - migrations.RemoveField( - model_name='classification', - name='source', - ), - migrations.RemoveField( - model_name='element', - name='source', - ), - migrations.RemoveField( - model_name='entity', - name='source', - ), - migrations.RemoveField( - model_name='transcription', - name='source', - ), - migrations.AddConstraint( - model_name='classification', - constraint=models.UniqueConstraint( - condition=models.Q(worker_version_id__isnull=True), - fields=('element', 'ml_class'), - name='classification_unique_manual', - ), - ), - migrations.AddConstraint( - model_name='classification', - constraint=models.UniqueConstraint( - condition=models.Q(worker_version_id__isnull=False), - fields=('element', 'ml_class', 'worker_version'), - name='classification_unique_worker_version', - ), - ), - migrations.DeleteModel( - name='DataSource', - ), - ] diff --git a/arkindex/documents/migrations/0026_metadata_worker_version.py b/arkindex/documents/migrations/0026_metadata_worker_version.py deleted file mode 100644 index f419f9f370d92257dcf3e17c7e55819779ea13b3..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0026_metadata_worker_version.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 3.1.4 on 2020-12-30 15:31 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0025_dataimport_name'), - ('documents', '0025_drop_datasource'), - ] - - operations = [ - migrations.AddField( - model_name='metadata', - name='worker_version', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='metadatas', to='process.workerversion'), - ), - ] diff --git a/arkindex/documents/migrations/0027_remove_metadata_revision.py b/arkindex/documents/migrations/0027_remove_metadata_revision.py deleted file mode 100644 index 204826e1a697406d2c17acb44ac95be35a0cc82b..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0027_remove_metadata_revision.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 3.1.5 on 2021-01-29 09:23 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0026_metadata_worker_version'), - ] - - operations = [ - migrations.RemoveField( - model_name='metadata', - name='revision', - ), - ] diff --git a/arkindex/documents/migrations/0028_transcription_confidence.py b/arkindex/documents/migrations/0028_transcription_confidence.py deleted file mode 100644 index 54114c8f41f7e3f2dd9d1d772f05e3c46d36accb..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0028_transcription_confidence.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.1.6 on 2021-02-15 15:34 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0027_remove_metadata_revision'), - ] - - operations = [ - migrations.RenameField( - model_name='transcription', - old_name='score', - new_name='confidence', - ), - ] diff --git a/arkindex/documents/migrations/0029_corpus_top_level_type.py b/arkindex/documents/migrations/0029_corpus_top_level_type.py deleted file mode 100644 index cd2dd87d7a5f5bc133bf5e436a5ce4375e4d166c..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0029_corpus_top_level_type.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 3.1.5 on 2021-03-04 08:45 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0028_transcription_confidence'), - ] - - operations = [ - migrations.AddField( - model_name='corpus', - name='top_level_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='top_level_corpora', to='documents.elementtype'), - ), - ] diff --git a/arkindex/documents/migrations/0030_convert_html_metadata_as_markdown.py b/arkindex/documents/migrations/0030_convert_html_metadata_as_markdown.py deleted file mode 100644 index 87d49a4fe7012c3d88405517f96563792bea533a..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0030_convert_html_metadata_as_markdown.py +++ /dev/null @@ -1,33 +0,0 @@ -# Generated by Django 3.1.7 on 2021-03-17 08:26 -from django.db import migrations - -from arkindex.documents.models import MetaType - - -def convert_html_metadata_to_markdown(apps, schema_editor): - MetaData = apps.get_model('documents', 'MetaData') - AllowedMetaData = apps.get_model('documents', 'AllowedMetaData') - MetaData.objects.exclude(type__in=[mt.value for mt in MetaType]).update(type=MetaType.Markdown) - AllowedMetaData.objects.exclude(type__in=[mt.value for mt in MetaType]).update(type=MetaType.Markdown) - - -def convert_markdown_metadata_to_html(apps, schema_editor): - MetaData = apps.get_model('documents', 'MetaData') - AllowedMetaData = apps.get_model('documents', 'AllowedMetaData') - MetaData.objects.exclude(type__in=[mt.value for mt in MetaType]).update(type=MetaType.HTML) - AllowedMetaData.objects.exclude(type__in=[mt.value for mt in MetaType]).update(type=MetaType.HTML) - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0029_corpus_top_level_type'), - ] - - operations = [ - migrations.RunPython( - convert_html_metadata_to_markdown, - reverse_code=convert_markdown_metadata_to_html, - elidable=True, - ), - ] diff --git a/arkindex/documents/migrations/0031_add_indexable_fields.py b/arkindex/documents/migrations/0031_add_indexable_fields.py deleted file mode 100644 index daee5457e4dce1d2e0fc34fc5fd42de7a015ea9b..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0031_add_indexable_fields.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 3.1.7 on 2021-04-08 09:01 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0030_convert_html_metadata_as_markdown'), - ] - - operations = [ - migrations.AddField( - model_name='corpus', - name='indexable', - field=models.BooleanField(default=False), - ), - migrations.AddField( - model_name='elementtype', - name='indexable', - field=models.BooleanField(default=False), - ), - ] diff --git a/arkindex/documents/migrations/0032_alter_transcriptionentity_length.py b/arkindex/documents/migrations/0032_alter_transcriptionentity_length.py deleted file mode 100644 index 955d7d65e98015a425026db6fcaf1abc202525ec..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0032_alter_transcriptionentity_length.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 3.1.7 on 2021-04-28 10:10 - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0031_add_indexable_fields'), - ] - - operations = [ - migrations.AlterField( - model_name='transcriptionentity', - name='length', - field=models.PositiveIntegerField(validators=[django.core.validators.MinValueValidator(1)]), - ), - ] diff --git a/arkindex/documents/migrations/0033_corpus_thumbnail.py b/arkindex/documents/migrations/0033_corpus_thumbnail.py deleted file mode 100644 index 5fe75cd292b3bff9dccd04746cbc1d727d00edca..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0033_corpus_thumbnail.py +++ /dev/null @@ -1,26 +0,0 @@ -# Generated by Django 3.1.8 on 2021-04-16 13:29 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0032_alter_transcriptionentity_length'), - ] - - operations = [ - migrations.AddField( - model_name='corpus', - name='thumbnail', - field=models.OneToOneField( - blank=True, - help_text='Optional element used as the thumbnail for this corpus', - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name='thumbnail_corpus', - to='documents.element', - ), - ), - ] diff --git a/arkindex/documents/migrations/0034_transcriptionentity_worker_version.py b/arkindex/documents/migrations/0034_transcriptionentity_worker_version.py deleted file mode 100644 index be4222ae3ecc3d074f0299d3db17080ed429906e..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0034_transcriptionentity_worker_version.py +++ /dev/null @@ -1,44 +0,0 @@ -# Generated by Django 3.1.8 on 2021-05-05 15:27 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0032_dataimport_activity_state'), - ('documents', '0033_corpus_thumbnail'), - ] - - atomic = False - - operations = [ - migrations.AddField( - model_name='transcriptionentity', - name='worker_version', - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name='transcription_entities', - to='process.workerversion' - ), - ), - migrations.AlterUniqueTogether( - name='transcriptionentity', - unique_together={ - ('transcription', 'entity', 'offset', 'length', 'worker_version') - }, - ), - migrations.RunSQL( - """ - UPDATE documents_transcriptionentity tr_entity - SET worker_version_id = entity.worker_version_id - FROM documents_entity entity - WHERE tr_entity.entity_id = entity.id; - """, - reverse_sql=migrations.RunSQL.noop, - elidable=True, - ) - ] diff --git a/arkindex/documents/migrations/0035_corpusexport.py b/arkindex/documents/migrations/0035_corpusexport.py deleted file mode 100644 index 2af867c18621f52351039975528ba39acc21f7b4..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0035_corpusexport.py +++ /dev/null @@ -1,35 +0,0 @@ -# Generated by Django 3.2.3 on 2021-06-14 10:58 - -import uuid - -import django.db.models.deletion -import enumfields.fields -from django.conf import settings -from django.db import migrations, models - -import arkindex.documents.models - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('documents', '0034_transcriptionentity_worker_version'), - ] - - operations = [ - migrations.CreateModel( - name='CorpusExport', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('state', enumfields.fields.EnumField(default='created', enum=arkindex.documents.models.CorpusExportState, max_length=10)), - ('corpus', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='exports', to='documents.corpus')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='exports', to=settings.AUTH_USER_MODEL)), - ], - options={ - 'abstract': False, - }, - ), - ] diff --git a/arkindex/documents/migrations/0036_elementpath_unique.py b/arkindex/documents/migrations/0036_elementpath_unique.py deleted file mode 100644 index f2a52639ae6efe5d1048efb4d90f1c9e9f49a794..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0036_elementpath_unique.py +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by Django 3.2.3 on 2021-06-23 10:27 - -from django.db import migrations, models - -DEDUPLICATE_SQL = """ -DELETE FROM documents_elementpath WHERE id IN ( - SELECT id FROM ( - SELECT id, ROW_NUMBER() OVER (PARTITION BY element_id, path) > 1 AS is_duplicate - FROM documents_elementpath - ) AS a - WHERE is_duplicate IS TRUE -); -""" - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0035_corpusexport'), - ] - - operations = [ - migrations.RunSQL( - DEDUPLICATE_SQL, - reverse_sql=migrations.RunSQL.noop, - ), - migrations.AddConstraint( - model_name='elementpath', - constraint=models.UniqueConstraint(fields=('element', 'path'), name='unique_element_paths'), - ), - ] diff --git a/arkindex/documents/migrations/0037_metadata_numeric.py b/arkindex/documents/migrations/0037_metadata_numeric.py deleted file mode 100644 index 6c81b9a5346a6e83df50086e3bee688f9c1d64dc..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0037_metadata_numeric.py +++ /dev/null @@ -1,36 +0,0 @@ -# Generated by Django 3.2.3 on 2021-06-25 10:03 - -from django.db import migrations, models -from django.db.models.expressions import RawSQL -from django.db.models.functions import Cast - -from arkindex.documents.models import MetaType - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0036_elementpath_unique'), - ] - - operations = [ - migrations.AddConstraint( - model_name='metadata', - constraint=models.CheckConstraint( - check=~models.Q(type=MetaType.Numeric) | RawSQL( - 'value::double precision IS NOT NULL', - output_field=models.BooleanField(), - params=() - ), - name='metadata_numeric_values' - ), - ), - migrations.AddIndex( - model_name='metadata', - index=models.Index( - Cast('value', output_field=models.FloatField()), - condition=models.Q(type=MetaType.Numeric), - name='metadata_numeric_index', - ), - ), - ] diff --git a/arkindex/documents/migrations/0038_element_zone_fields.py b/arkindex/documents/migrations/0038_element_zone_fields.py deleted file mode 100644 index 3bf99401dae8b70784f18d995a2c0be94698ad75..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0038_element_zone_fields.py +++ /dev/null @@ -1,37 +0,0 @@ -# Generated by Django 3.2.3 on 2021-07-19 12:14 - -import django.db.models.deletion -from django.db import migrations, models - -import arkindex.project.fields - - -class Migration(migrations.Migration): - - dependencies = [ - ('images', '0007_update_zone_constraint'), - ('documents', '0037_metadata_numeric'), - ] - - operations = [ - migrations.AddField( - model_name='element', - name='image', - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name='elements', - to='images.image', - ), - ), - migrations.AddField( - model_name='element', - name='polygon', - field=arkindex.project.fields.LinearRingField( - blank=True, - null=True, - srid=0, - ), - ), - ] diff --git a/arkindex/documents/migrations/0039_migrate_zones.py b/arkindex/documents/migrations/0039_migrate_zones.py deleted file mode 100644 index b780514f5271b019ece91e4be7a683bd5046343c..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0039_migrate_zones.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 3.2.3 on 2021-07-19 12:14 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0038_element_zone_fields'), - ] - - operations = [ - migrations.RunSQL(""" - UPDATE documents_element - SET image_id = images_zone.image_id, polygon = images_zone.polygon - FROM images_zone - WHERE images_zone.id = documents_element.zone_id - """), - ] diff --git a/arkindex/documents/migrations/0040_element_zone_constraints.py b/arkindex/documents/migrations/0040_element_zone_constraints.py deleted file mode 100644 index 4255d9dd9ba0857595e08e5a5316873805e28212..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0040_element_zone_constraints.py +++ /dev/null @@ -1,46 +0,0 @@ -# Generated by Django 3.2.3 on 2021-07-19 12:14 - -from django.contrib.gis.db.models.functions import SnapToGrid -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0039_migrate_zones'), - ] - - operations = [ - migrations.AddConstraint( - model_name='element', - constraint=models.CheckConstraint( - check=models.Q(image_id=None, polygon=None) | ~(models.Q(image_id=None) | models.Q(polygon=None)), - name='element_image_and_polygon', - ), - ), - migrations.AddConstraint( - model_name='element', - constraint=models.CheckConstraint( - check=models.Q(polygon=None) | models.Q(polygon__isclosed=True), - name='element_polygon_closed', - ), - ), - migrations.AddConstraint( - model_name='element', - constraint=models.CheckConstraint( - check=models.Q(polygon=None) | models.Q(polygon=SnapToGrid('polygon', 1)), - name='element_polygon_integer_coordinates', - ), - ), - migrations.AddConstraint( - model_name='element', - constraint=models.CheckConstraint( - check=models.Q(polygon=None) | models.Q(polygon__numpoints__gte=4), - name='element_polygon_size', - ), - ), - migrations.RemoveField( - model_name='element', - name='zone', - ), - ] diff --git a/arkindex/documents/migrations/0041_rotation.py b/arkindex/documents/migrations/0041_rotation.py deleted file mode 100644 index 2493bd29d9711fc99a95c9421952bd8b7bea6929..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0041_rotation.py +++ /dev/null @@ -1,38 +0,0 @@ -# Generated by Django 3.2.3 on 2021-07-21 10:26 - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0040_element_zone_constraints'), - ] - - operations = [ - migrations.AddField( - model_name='element', - name='mirrored', - field=models.BooleanField( - default=False, - help_text='Mirror the image along the vertical axis before rotating.', - ), - ), - migrations.AddField( - model_name='element', - name='rotation_angle', - field=models.SmallIntegerField( - default=0, - help_text='Clockwise rotation to apply to the image after cropping, in degrees.', - validators=[django.core.validators.MaxValueValidator(359)], - ), - ), - migrations.AddConstraint( - model_name='element', - constraint=models.CheckConstraint( - check=models.Q(('rotation_angle__gte', 0), ('rotation_angle__lte', 359)), - name='element_rotation_angle', - ), - ), - ] diff --git a/arkindex/documents/migrations/0042_transcription_entity_confidence.py b/arkindex/documents/migrations/0042_transcription_entity_confidence.py deleted file mode 100644 index a20c9ef899a4ae4444cbfd46883537b30fd4b699..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0042_transcription_entity_confidence.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 3.2.6 on 2021-08-09 11:34 - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0034_worker_run_config'), - ('documents', '0041_rotation'), - ] - - operations = [ - migrations.AddField( - model_name='transcriptionentity', - name='confidence', - field=models.FloatField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(1)]), - ), - ] diff --git a/arkindex/documents/migrations/0043_element_creator.py b/arkindex/documents/migrations/0043_element_creator.py deleted file mode 100644 index 79fb2b1ecbabbe7351d73b9137aadf94e86a98f3..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0043_element_creator.py +++ /dev/null @@ -1,34 +0,0 @@ -# Generated by Django 3.2.3 on 2021-10-12 09:46 - -import django.db.models.deletion -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('documents', '0042_transcription_entity_confidence'), - ] - - operations = [ - migrations.AddField( - model_name='element', - name='creator', - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name='elements', - to=settings.AUTH_USER_MODEL, - ), - ), - migrations.AddConstraint( - model_name='element', - constraint=models.CheckConstraint( - check=models.Q(creator_id=None) | models.Q(worker_version_id=None), - name='element_creator_nand_worker_version', - ), - ), - ] diff --git a/arkindex/documents/migrations/0044_remove_metadata_index.py b/arkindex/documents/migrations/0044_remove_metadata_index.py deleted file mode 100644 index f3f948bd6fb36afb129b42738402ac574e4c9cff..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0044_remove_metadata_index.py +++ /dev/null @@ -1,25 +0,0 @@ -# Generated by Django 3.2.3 on 2021-10-22 14:18 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0043_element_creator'), - ] - - operations = [ - migrations.AlterModelOptions( - name='metadata', - options={'ordering': ('element', 'name', 'id')}, - ), - migrations.AlterUniqueTogether( - name='metadata', - unique_together=set(), - ), - migrations.RemoveField( - model_name='metadata', - name='index', - ), - ] diff --git a/arkindex/documents/migrations/0045_alter_element_rotation_angle.py b/arkindex/documents/migrations/0045_alter_element_rotation_angle.py deleted file mode 100644 index 230d026eb348c4407e3f0e3fdd7f3a777d5aec27..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0045_alter_element_rotation_angle.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 3.2.3 on 2021-11-03 09:27 - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0044_remove_metadata_index'), - ] - - operations = [ - migrations.AlterField( - model_name='element', - name='rotation_angle', - field=models.SmallIntegerField(default=0, help_text='Clockwise rotation to apply to the image after cropping, in degrees.', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(359)]), - ), - ] diff --git a/arkindex/documents/migrations/0046_transcription_orientation.py b/arkindex/documents/migrations/0046_transcription_orientation.py deleted file mode 100644 index d790743787e258c023c3c43cc4a59b041754b498..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0046_transcription_orientation.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 3.2.6 on 2021-10-22 08:27 - -import enumfields.fields -from django.db import migrations - -import arkindex.documents.models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0045_alter_element_rotation_angle'), - ] - - operations = [ - migrations.AddField( - model_name='transcription', - name='orientation', - field=enumfields.fields.EnumField(default='horizontal-lr', enum=arkindex.documents.models.TextOrientation, max_length=50), - ), - ] diff --git a/arkindex/documents/migrations/0047_elementpath_element_path_last.py b/arkindex/documents/migrations/0047_elementpath_element_path_last.py deleted file mode 100644 index e52cadae8ecc3282089e098502547468a8ce6b49..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0047_elementpath_element_path_last.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 4.0.1 on 2022-01-05 16:29 - -import django.db.models.expressions -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0046_transcription_orientation'), - ] - - operations = [ - migrations.AddIndex( - model_name='elementpath', - index=models.Index(django.db.models.expressions.F('path__last'), name='element_path_last'), - ), - # After this index is created, we need to analyze the table again to make its query planner see it; - # otherwise, it will keep its old way of querying and no performance improvement is made. - migrations.RunSQL( - "ANALYZE documents_elementpath", - reverse_sql=migrations.RunSQL.noop, - ) - ] diff --git a/arkindex/documents/migrations/0048_empty_paths.py b/arkindex/documents/migrations/0048_empty_paths.py deleted file mode 100644 index 4f462ca819a6c4bd85545f9c8bb2db5bbe33c7f6..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0048_empty_paths.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 2.2.13 on 2020-06-18 14:31 - -from django.db import migrations - -FORWARD_SQL = """ -INSERT INTO documents_elementpath (id, element_id, path, ordering) -SELECT uuid_generate_v4(), e.id, ARRAY[]::uuid[], 0 -FROM documents_element e -LEFT JOIN documents_elementpath p ON (p.element_id = e.id) -WHERE p.id IS NULL; -""" - -REVERSE_SQL = 'DELETE FROM documents_elementpath WHERE path = ARRAY[]::uuid[];' - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0047_elementpath_element_path_last'), - ] - - operations = [ - migrations.RunSQL(FORWARD_SQL, reverse_sql=REVERSE_SQL) - ] diff --git a/arkindex/documents/migrations/0049_empty_path_constraints.py b/arkindex/documents/migrations/0049_empty_path_constraints.py deleted file mode 100644 index 0fa647cc786e43529bf6ad945050fac3d840baa8..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0049_empty_path_constraints.py +++ /dev/null @@ -1,29 +0,0 @@ -# Generated by Django 4.0.1 on 2022-02-04 13:48 - -from django.contrib.postgres.constraints import ExclusionConstraint -from django.contrib.postgres.operations import BtreeGistExtension -from django.db import migrations -from django.db.models import Deferrable -from django.db.models.functions import Least - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0048_empty_paths'), - ] - - operations = [ - BtreeGistExtension(), - migrations.AddConstraint( - model_name='elementpath', - constraint=ExclusionConstraint( - name='unique_top_level', - expressions=[ - ('element', '='), - (Least('path__len', 1), '<>') - ], - deferrable=Deferrable.DEFERRED, - ) - ), - ] diff --git a/arkindex/documents/migrations/0050_element_confidence.py b/arkindex/documents/migrations/0050_element_confidence.py deleted file mode 100644 index 8f5eab08760b89107652c270dee4168c60cb838c..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0050_element_confidence.py +++ /dev/null @@ -1,26 +0,0 @@ -# Generated by Django 4.0.1 on 2022-05-06 09:25 - -from django.core.validators import MaxValueValidator, MinValueValidator -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0049_empty_path_constraints'), - ] - - operations = [ - migrations.AddField( - model_name='element', - name='confidence', - field=models.FloatField( - blank=True, - null=True, - validators=[ - MinValueValidator(0), - MaxValueValidator(1) - ] - ), - ), - ] diff --git a/arkindex/documents/migrations/0051_classification_worker_run.py b/arkindex/documents/migrations/0051_classification_worker_run.py deleted file mode 100644 index 46bc623c062332114f0cb5618d465cb316490238..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0051_classification_worker_run.py +++ /dev/null @@ -1,52 +0,0 @@ -# Generated by Django 4.0.1 on 2022-05-11 13:58 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0047_workerversion_model_usage'), - ('documents', '0050_element_confidence'), - ] - - operations = [ - migrations.AddField( - model_name='classification', - name='worker_run', - field=models.ForeignKey( - blank=True, - null=True, - on_delete=models.DO_NOTHING, - related_name='classifications', - to='process.workerrun', - ), - ), - migrations.AddConstraint( - model_name='classification', - constraint=models.CheckConstraint( - check=models.Q(worker_version_id__isnull=False) | models.Q(worker_run_id__isnull=True), - name='classification_worker_run_requires_worker_version', - ), - ), - migrations.RemoveConstraint( - model_name='classification', - name='classification_unique_worker_version', - ), - migrations.AddConstraint( - model_name='classification', - constraint=models.UniqueConstraint( - condition=models.Q(worker_run_id__isnull=True, worker_version_id__isnull=False), - fields=('element', 'ml_class', 'worker_version'), - name='classification_unique_worker_version', - ), - ), - migrations.AddConstraint( - model_name='classification', - constraint=models.UniqueConstraint( - condition=models.Q(worker_run_id__isnull=False), - fields=('element', 'ml_class', 'worker_run'), - name='classification_unique_worker_run', - ), - ), - ] diff --git a/arkindex/documents/migrations/0052_element_worker_run_and_more.py b/arkindex/documents/migrations/0052_element_worker_run_and_more.py deleted file mode 100644 index 65acd6687a4a521916601c85f2cca66f6adfb6ec..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0052_element_worker_run_and_more.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 4.0.2 on 2022-05-13 14:35 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0047_workerversion_model_usage'), - ('documents', '0051_classification_worker_run'), - ] - - operations = [ - migrations.AddField( - model_name='element', - name='worker_run', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='elements', to='process.workerrun'), - ), - migrations.AddConstraint( - model_name='element', - constraint=models.CheckConstraint(check=models.Q(('worker_run_id__isnull', True), ('worker_version_id__isnull', False), _connector='OR'), name='element_worker_run_requires_worker_version'), - ), - ] diff --git a/arkindex/documents/migrations/0053_metadata_worker_run_and_more.py b/arkindex/documents/migrations/0053_metadata_worker_run_and_more.py deleted file mode 100644 index 49e7520c791e6f14ff52c820ffbe806bd3fd9623..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0053_metadata_worker_run_and_more.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 4.0.2 on 2022-05-13 14:54 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0047_workerversion_model_usage'), - ('documents', '0052_element_worker_run_and_more'), - ] - - operations = [ - migrations.AddField( - model_name='metadata', - name='worker_run', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='metadatas', to='process.workerrun'), - ), - migrations.AddConstraint( - model_name='metadata', - constraint=models.CheckConstraint(check=models.Q(('worker_version_id__isnull', False), ('worker_run_id__isnull', True), _connector='OR'), name='metadata_worker_run_requires_worker_version'), - ), - ] diff --git a/arkindex/documents/migrations/0054_transcription_worker_run.py b/arkindex/documents/migrations/0054_transcription_worker_run.py deleted file mode 100644 index 6b401a75c29b022e25b223ad02c0062aa48b392d..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0054_transcription_worker_run.py +++ /dev/null @@ -1,32 +0,0 @@ -# Generated by Django 4.0.1 on 2022-05-13 12:13 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0047_workerversion_model_usage'), - ('documents', '0053_metadata_worker_run_and_more'), - ] - - operations = [ - migrations.AddField( - model_name='transcription', - name='worker_run', - field=models.ForeignKey( - blank=True, - null=True, - on_delete=models.DO_NOTHING, - related_name='transcriptions', - to='process.workerrun', - ), - ), - migrations.AddConstraint( - model_name='transcription', - constraint=models.CheckConstraint( - check=models.Q(worker_version_id__isnull=False) | models.Q(worker_run_id__isnull=True), - name='transcription_worker_run_requires_worker_version', - ), - ), - ] diff --git a/arkindex/documents/migrations/0055_entity_worker_run_and_more.py b/arkindex/documents/migrations/0055_entity_worker_run_and_more.py deleted file mode 100644 index 7b6c3b8a8888fd1d45ae3174ff544881b046792c..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0055_entity_worker_run_and_more.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 4.0.2 on 2022-05-17 12:41 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0048_workerrun_model_version'), - ('documents', '0054_transcription_worker_run'), - ] - - operations = [ - migrations.AddField( - model_name='entity', - name='worker_run', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='entities', to='process.workerrun'), - ), - migrations.AddConstraint( - model_name='entity', - constraint=models.CheckConstraint(check=models.Q(('worker_run_id__isnull', True), ('worker_version_id__isnull', False), _connector='OR'), name='entity_worker_run_requires_worker_version'), - ), - ] diff --git a/arkindex/documents/migrations/0056_alter_transcriptionentity_unique_together_and_more.py b/arkindex/documents/migrations/0056_alter_transcriptionentity_unique_together_and_more.py deleted file mode 100644 index fb4917827ddbb8ddceb4cd79290698df8dd02c06..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0056_alter_transcriptionentity_unique_together_and_more.py +++ /dev/null @@ -1,40 +0,0 @@ -# Generated by Django 4.0.2 on 2022-05-17 14:46 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0048_workerrun_model_version'), - ('documents', '0055_entity_worker_run_and_more'), - ] - - operations = [ - migrations.AlterUniqueTogether( - name='transcriptionentity', - unique_together=set(), - ), - migrations.AddField( - model_name='transcriptionentity', - name='worker_run', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='transcription_entities', to='process.workerrun'), - ), - migrations.AddConstraint( - model_name='transcriptionentity', - constraint=models.CheckConstraint(check=models.Q(('worker_version_id__isnull', False), ('worker_run_id__isnull', True), _connector='OR'), name='transcription_entity_worker_run_requires_worker_version'), - ), - migrations.AddConstraint( - model_name='transcriptionentity', - constraint=models.UniqueConstraint(condition=models.Q(('worker_version_id__isnull', True)), fields=('transcription', 'entity', 'offset', 'length'), name='transcription_entity_unique_manual'), - ), - migrations.AddConstraint( - model_name='transcriptionentity', - constraint=models.UniqueConstraint(condition=models.Q(('worker_run_id__isnull', True), ('worker_version_id__isnull', False)), fields=('transcription', 'entity', 'offset', 'length', 'worker_version'), name='transcription_entity_unique_worker_version'), - ), - migrations.AddConstraint( - model_name='transcriptionentity', - constraint=models.UniqueConstraint(condition=models.Q(('worker_run_id__isnull', False)), fields=('transcription', 'entity', 'offset', 'length', 'worker_run'), name='transcription_entity_unique_worker_run'), - ), - ] diff --git a/arkindex/documents/migrations/0057_entity_list_index.py b/arkindex/documents/migrations/0057_entity_list_index.py deleted file mode 100644 index 434a8a439210077f3871b863cb94478dd7ae31e2..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0057_entity_list_index.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 4.0.5 on 2022-07-01 13:22 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0056_alter_transcriptionentity_unique_together_and_more'), - ] - - operations = [ - migrations.AddIndex( - model_name='entity', - index=models.Index(fields=['corpus_id', 'name', 'id'], name='entity_list_index'), - ), - ] diff --git a/arkindex/documents/migrations/0058_remove_corpus_repository.py b/arkindex/documents/migrations/0058_remove_corpus_repository.py deleted file mode 100644 index 8c088e9e5fb17954f0546f5a04e4839245a91215..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0058_remove_corpus_repository.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 4.0.4 on 2022-08-05 11:49 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0057_entity_list_index'), - ] - - operations = [ - migrations.RemoveField( - model_name='corpus', - name='repository', - ), - ] diff --git a/arkindex/documents/migrations/0059_remove_corpus_thumbnail.py b/arkindex/documents/migrations/0059_remove_corpus_thumbnail.py deleted file mode 100644 index ed17dae05651bfb9fc95583c64e5b81066e8302b..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0059_remove_corpus_thumbnail.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 4.0.4 on 2022-08-30 10:16 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0058_remove_corpus_repository'), - ] - - operations = [ - migrations.RemoveField( - model_name='corpus', - name='thumbnail', - ), - ] diff --git a/arkindex/documents/migrations/0060_rewrite_metadata_numeric.py b/arkindex/documents/migrations/0060_rewrite_metadata_numeric.py deleted file mode 100644 index 8c785f6ee9bacc612dfff4f23723a4e718c939f4..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0060_rewrite_metadata_numeric.py +++ /dev/null @@ -1,26 +0,0 @@ -# Generated by Django 4.1.3 on 2022-12-05 16:16 - -from django.db import migrations, models - -from arkindex.documents.models import MetaType - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0059_remove_corpus_thumbnail'), - ] - - operations = [ - migrations.RemoveConstraint( - model_name='metadata', - name='metadata_numeric_values', - ), - migrations.AddConstraint( - model_name='metadata', - constraint=models.CheckConstraint( - check=~models.Q(type=MetaType.Numeric) | models.Q(value__iregex=r'^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:E[+-]?\d+)?$'), - name='metadata_numeric_values' - ), - ), - ] diff --git a/arkindex/documents/migrations/0061_create_new_entitytypes.py b/arkindex/documents/migrations/0061_create_new_entitytypes.py deleted file mode 100644 index 9877dee6695bb78368042f7aef2b52889bc7bcba..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0061_create_new_entitytypes.py +++ /dev/null @@ -1,94 +0,0 @@ -# Generated by Django 4.1.4 on 2023-01-09 16:51 - -import uuid - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("documents", "0060_rewrite_metadata_numeric"), - ] - - operations = [ - migrations.CreateModel( - name="EntityType", - fields=[ - ( - "id", - models.UUIDField( - default=uuid.uuid4, - editable=False, - primary_key=True, - serialize=False, - ), - ), - ("name", models.CharField(max_length=250)), - ("color", models.CharField(max_length=6, default='ff0000')), - ( - "corpus", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="entity_types", - to="documents.corpus", - ), - ), - ], - options={ - "unique_together": {("name", "corpus")}, - }, - ), - migrations.RenameField( - model_name='entity', - old_name='type', - new_name='old_type', - ), - migrations.RenameField( - model_name='entityrole', - old_name='child_type', - new_name='old_child_type', - ), - migrations.RenameField( - model_name='entityrole', - old_name='parent_type', - new_name='old_parent_type', - ), - migrations.AddField( - model_name="entity", - name="type", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="entities", - to="documents.entitytype", - null=True, - ) - ), - migrations.AddField( - model_name="entityrole", - name="child_type", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="child_role", - to="documents.entitytype", - null=True, - ), - ), - migrations.AddField( - model_name="entityrole", - name="parent_type", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="parent_role", - to="documents.entitytype", - null=True, - ), - ), - migrations.AlterUniqueTogether( - name="entityrole", - unique_together={ - ("parent_name", "child_name", "parent_type", "child_type", "corpus") - }, - ), - ] diff --git a/arkindex/documents/migrations/0062_migrate_entitytypes.py b/arkindex/documents/migrations/0062_migrate_entitytypes.py deleted file mode 100644 index ff1963477687c79900716b63863270f436edf259..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0062_migrate_entitytypes.py +++ /dev/null @@ -1,81 +0,0 @@ -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("documents", "0061_create_new_entitytypes"), - ] - - operations = [ - migrations.RunSQL( - """ - INSERT INTO documents_entitytype (id, corpus_id, name, color) - SELECT uuid_generate_v4(), corpus_id, name, - CASE WHEN old_type = 'location' THEN '28b62c' - WHEN old_type = 'date' THEN 'ff4136' - WHEN old_type = 'person' THEN '3273dc' - WHEN old_type = 'subject' THEN 'ffdd57' - WHEN old_type = 'organization' THEN 'ea4aaa' - WHEN old_type = 'misc' THEN '363636' - WHEN old_type = 'number' THEN '00d1b2' - ELSE 'ff0000' END - FROM ( - SELECT DISTINCT ON (corpus_id, name) * - FROM ( - SELECT - corpus_id, - COALESCE(metas->'subtype', old_type) AS name, - old_type - FROM documents_entity - UNION ALL - SELECT - corpus_id, - old_parent_type AS name, - old_parent_type AS old_type - FROM documents_entityrole - UNION ALL - SELECT - corpus_id, - old_child_type AS name, - old_child_type AS old_type - FROM documents_entityrole - ) AS all_old_types - ) AS old_types - """, - reverse_sql=migrations.RunSQL.noop, - elidable=True, - ), - migrations.RunSQL( - """ - UPDATE documents_entity e - SET type_id = t.id - FROM documents_entitytype t - WHERE t.corpus_id = e.corpus_id - AND - t.name = COALESCE(e.metas->'subtype', e.old_type) - """, - reverse_sql=migrations.RunSQL.noop, - elidable=True, - ), - migrations.RunSQL( - """ - UPDATE documents_entityrole r - SET child_type_id = t.id - FROM documents_entitytype t - WHERE t.corpus_id = r.corpus_id AND t.name = r.old_child_type - """, - reverse_sql=migrations.RunSQL.noop, - elidable=True, - ), - migrations.RunSQL( - """ - UPDATE documents_entityrole r - SET parent_type_id = t.id - FROM documents_entitytype t - WHERE t.corpus_id = r.corpus_id AND t.name = r.old_parent_type - """, - reverse_sql=migrations.RunSQL.noop, - elidable=True, - ), - ] diff --git a/arkindex/documents/migrations/0063_remove_old_entitypes.py b/arkindex/documents/migrations/0063_remove_old_entitypes.py deleted file mode 100644 index f28e0313f292da8377b1afa4d52e13ee6313cb60..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0063_remove_old_entitypes.py +++ /dev/null @@ -1,58 +0,0 @@ -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("documents", "0062_migrate_entitytypes"), - ] - - operations = [ - migrations.RemoveField( - model_name='entity', - name='old_type' - ), - migrations.RemoveField( - model_name='entityrole', - name='old_child_type' - ), - migrations.RemoveField( - model_name='entityrole', - name='old_parent_type' - ), - migrations.RunSQL( - """ - UPDATE documents_entity SET metas = metas - 'subtype'::text WHERE metas ? 'subtype' - """, - reverse_sql=migrations.RunSQL.noop, - elidable=True, - ), - migrations.AlterField( - model_name='entity', - name='type', - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="entities", - to="documents.entitytype", - ) - ), - migrations.AlterField( - model_name='entityrole', - name='child_type', - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="child_role", - to="documents.entitytype", - ) - ), - migrations.AlterField( - model_name='entityrole', - name='parent_type', - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="parent_role", - to="documents.entitytype", - ) - ) - ] diff --git a/arkindex/documents/migrations/0064_alter_entity_type_alter_entityrole_child_type_and_more.py b/arkindex/documents/migrations/0064_alter_entity_type_alter_entityrole_child_type_and_more.py deleted file mode 100644 index b57cf3d8c296b7c652debe17793443c9bc0be780..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0064_alter_entity_type_alter_entityrole_child_type_and_more.py +++ /dev/null @@ -1,41 +0,0 @@ -# Generated by Django 4.1.4 on 2023-02-01 10:46 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("documents", "0063_remove_old_entitypes"), - ] - - operations = [ - migrations.AlterField( - model_name="entity", - name="type", - field=models.ForeignKey( - on_delete=django.db.models.deletion.DO_NOTHING, - related_name="entities", - to="documents.entitytype", - ), - ), - migrations.AlterField( - model_name="entityrole", - name="child_type", - field=models.ForeignKey( - on_delete=django.db.models.deletion.DO_NOTHING, - related_name="child_role", - to="documents.entitytype", - ), - ), - migrations.AlterField( - model_name="entityrole", - name="parent_type", - field=models.ForeignKey( - on_delete=django.db.models.deletion.DO_NOTHING, - related_name="parent_role", - to="documents.entitytype", - ), - ), - ] diff --git a/arkindex/documents/migrations/0065_elementpath_constraints.py b/arkindex/documents/migrations/0065_elementpath_constraints.py deleted file mode 100644 index 6f8ad212c60b860c5708f0bc3cbfbbe79c492046..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0065_elementpath_constraints.py +++ /dev/null @@ -1,40 +0,0 @@ -# Generated by Django 4.1.7 on 2023-04-26 14:12 - -from django.contrib.postgres.constraints import ExclusionConstraint -from django.contrib.postgres.fields import RangeOperators -from django.db import migrations -from django.db.models import Deferrable - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0064_alter_entity_type_alter_entityrole_child_type_and_more'), - ] - - operations = [ - migrations.AddConstraint( - model_name='elementpath', - constraint=ExclusionConstraint( - name='unique_element_orderings', - expressions=[ - ('element', RangeOperators.EQUAL), - ('path__last', RangeOperators.EQUAL), - ('ordering', RangeOperators.NOT_EQUAL), - ], - deferrable=Deferrable.DEFERRED, - ), - ), - migrations.AddConstraint( - model_name='elementpath', - constraint=ExclusionConstraint( - name='unique_parent_orderings', - expressions=[ - ('path__last', RangeOperators.EQUAL), - ('ordering', RangeOperators.EQUAL), - ('element', RangeOperators.NOT_EQUAL), - ], - deferrable=Deferrable.DEFERRED, - ), - ), - ] diff --git a/arkindex/documents/migrations/0066_element_type_implies_corpus.py b/arkindex/documents/migrations/0066_element_type_implies_corpus.py deleted file mode 100644 index 44ddb9a4cd80034d796bc818e646b6407253663b..0000000000000000000000000000000000000000 --- a/arkindex/documents/migrations/0066_element_type_implies_corpus.py +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by Django 4.1.7 on 2023-05-23 12:42 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0065_elementpath_constraints'), - ] - - operations = [ - # This gives a hint to PostgreSQL's query planner that the element's corpus can be deduced from the type. - # If you filter by a specific type ID, then the corpus ID will be constant; - # all elements of the same type ID should be in the same corpus. - # - # This causes the query planner to create significantly better query plans when filtering by both corpus and type ID, - # as it understands that filtering on both type and corpus is the same as only filtering on the type, - # and the corpus filter will not reduce the planner's estimated row counts. - # - # On freshly created databases, this applies immediately. On existing databases, this will only have an effect after - # an autovacuum completes or after an administrator runs `ANALYZE documents_element`. - # - # See https://gitlab.com/teklia/arkindex/backend/-/issues/1309#note_1401556847 for context. - - migrations.RunSQL( - "CREATE STATISTICS element_type_implies_corpus (dependencies) ON type_id, corpus_id FROM documents_element", - "DROP STATISTICS element_type_implies_corpus", - elidable=False, - ), - ] diff --git a/arkindex/images/migrations/0001_initial.py b/arkindex/images/migrations/0001_initial.py index 3015034398a494be04172393204775e44c62bed4..7c36bac3b14a9d1c41ab0c368aef82822f2786da 100644 --- a/arkindex/images/migrations/0001_initial.py +++ b/arkindex/images/migrations/0001_initial.py @@ -1,48 +1,28 @@ -# Generated by Django 2.2.9 on 2020-01-17 15:39 +# Generated by Django 4.1.7 on 2023-05-29 11:49 import uuid import django.db.models.deletion import enumfields.fields +from django.contrib.postgres.operations import CreateExtension from django.db import migrations, models import arkindex.project.aws import arkindex.project.fields -POLYGON_HASH_FORWARD_SQL = """ -ALTER TABLE images_zone - ADD COLUMN IF NOT EXISTS polygon_hash VARCHAR(32) - GENERATED ALWAYS AS (md5(polygon::varchar)) STORED; -CREATE UNIQUE INDEX zone_unique_image_polygon ON images_zone (image_id, polygon_hash); -""" - -POLYGON_HASH_REVERSE_SQL = """ -DROP INDEX IF EXISTS zone_unique_image_polygon; -ALTER TABLE images_zone DROP COLUMN IF EXISTS polygon_hash; -""" - - -class PolygonField(models.Field): - """ - Field to store a polygon; needs at least three set of points - """ - def db_type(self, connection): - return 'polygon' - class Migration(migrations.Migration): initial = True dependencies = [ - ('process', '0001_initial'), ] operations = [ + CreateExtension('postgis'), migrations.CreateModel( name='Image', fields=[ - ('status', enumfields.fields.EnumField(default='unchecked', enum=arkindex.project.aws.S3FileStatus, max_length=50)), ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), ('created', models.DateTimeField(auto_now_add=True)), ('updated', models.DateTimeField(auto_now=True)), @@ -50,7 +30,7 @@ class Migration(migrations.Migration): ('width', models.PositiveIntegerField(default=0)), ('height', models.PositiveIntegerField(default=0)), ('hash', arkindex.project.fields.MD5HashField(blank=True, max_length=32, null=True)), - ('datafile', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='images', to='process.DataFile')), + ('status', enumfields.fields.EnumField(default='unchecked', enum=arkindex.project.aws.S3FileStatus, max_length=50)), ], bases=(arkindex.project.aws.S3FileMixin, models.Model), ), @@ -62,47 +42,28 @@ class Migration(migrations.Migration): ('url', arkindex.project.fields.StripSlashURLField(unique=True)), ('s3_bucket', models.SlugField(blank=True, db_index=False, max_length=63, null=True)), ('s3_region', models.SlugField(blank=True, db_index=False, max_length=63, null=True)), + ('s3_read_only_bucket', models.BooleanField(default=False, help_text='Disable the extra image checks that are normally made for servers with S3 buckets.')), ('max_width', models.PositiveIntegerField(blank=True, null=True)), ('max_height', models.PositiveIntegerField(blank=True, null=True)), ('created', models.DateTimeField(auto_now_add=True)), ('updated', models.DateTimeField(auto_now=True)), - ('validated', models.BooleanField(default=False)), - ('read_only', models.BooleanField(default=False)), ], ), - migrations.CreateModel( - name='Zone', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('polygon', PolygonField()), - ('image', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='zones', to='images.Image')), - ], + migrations.AddConstraint( + model_name='imageserver', + constraint=models.CheckConstraint(check=models.Q(('s3_read_only_bucket', False), ('s3_bucket__isnull', False), _connector='OR'), name='s3_read_only_bucket_requires_s3_bucket'), ), migrations.AddField( model_name='image', name='server', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='images', to='images.ImageServer'), + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='images', to='images.imageserver'), ), - # When resetting migrations, replace the default AddConstraint on zone_unique_image_polygon with this RunSQL - # Required to add the unique constraint on the polygon_hash field, which is invisible to Django - # Otherwise, you will run into errors related to the requirement of an operator class for polygon on btree indexes. - migrations.RunSQL( - sql=POLYGON_HASH_FORWARD_SQL, - reverse_sql=POLYGON_HASH_REVERSE_SQL, - state_operations=[ - migrations.AddConstraint( - model_name='zone', - constraint=models.UniqueConstraint( - fields=('image', 'polygon'), - name='zone_unique_image_polygon', - ), - ), - ], + migrations.AddConstraint( + model_name='image', + constraint=models.CheckConstraint(check=models.Q(models.Q(('height__gt', 0), ('width__gt', 0)), models.Q(('status', arkindex.project.aws.S3FileStatus['Checked']), _negated=True), _connector='OR'), name='checked_image_dimensions'), ), migrations.AlterUniqueTogether( name='image', - unique_together={('server', 'path'), ('server', 'hash')}, + unique_together={('server', 'hash'), ('server', 'path')}, ), ] diff --git a/arkindex/images/migrations/0002_checked_dimensions.py b/arkindex/images/migrations/0002_checked_dimensions.py deleted file mode 100644 index cca62ee91a3346028ecaa9ebcec1c5ae301bbfed..0000000000000000000000000000000000000000 --- a/arkindex/images/migrations/0002_checked_dimensions.py +++ /dev/null @@ -1,34 +0,0 @@ -# Generated by Django 2.2.10 on 2020-05-13 15:17 - -from django.db import migrations, models - -import arkindex.project.aws - - -class Migration(migrations.Migration): - - dependencies = [ - ('images', '0001_initial'), - ] - - operations = [ - migrations.RunSQL( - sql=""" - UPDATE images_image - SET status = 'unchecked' - WHERE status = 'checked' AND (width = 0 OR height = 0); - """, - reverse_sql=migrations.RunSQL.noop, - ), - migrations.AddConstraint( - model_name='image', - constraint=models.CheckConstraint( - check=models.Q( - models.Q(('height__gt', 0), ('width__gt', 0)), - models.Q(_negated=True, status=arkindex.project.aws.S3FileStatus('checked')), - _connector='OR', - ), - name='checked_image_dimensions', - ), - ), - ] diff --git a/arkindex/images/migrations/0003_remove_image_datafile.py b/arkindex/images/migrations/0003_remove_image_datafile.py deleted file mode 100644 index 31fe8363edc6acaf3ceaf786da7c994090736882..0000000000000000000000000000000000000000 --- a/arkindex/images/migrations/0003_remove_image_datafile.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 2.2.13 on 2020-06-11 12:49 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('images', '0002_checked_dimensions'), - ] - - operations = [ - migrations.RemoveField( - model_name='image', - name='datafile', - ), - ] diff --git a/arkindex/images/migrations/0004_polygon_postgis.py b/arkindex/images/migrations/0004_polygon_postgis.py deleted file mode 100644 index 54bc4dcd2ed3346889048fa499b85e12319fabe2..0000000000000000000000000000000000000000 --- a/arkindex/images/migrations/0004_polygon_postgis.py +++ /dev/null @@ -1,118 +0,0 @@ -# Generated by Django 2.2.13 on 2020-07-29 12:24 - -from django.contrib.postgres.operations import CreateExtension -from django.db import migrations - -from arkindex.project.fields import LinearRingField -from arkindex.project.gis import SimplifyPreserveTopology - -POLYGON_HASH_FORWARD_SQL = """ -DROP INDEX IF EXISTS zone_unique_image_polygon; -ALTER TABLE images_zone DROP COLUMN IF EXISTS polygon_hash; -""" - -POLYGON_HASH_REVERSE_SQL = """ -ALTER TABLE images_zone - ADD COLUMN IF NOT EXISTS polygon_hash VARCHAR(32) - GENERATED ALWAYS AS (md5(polygon::varchar)) STORED; -CREATE UNIQUE INDEX zone_unique_image_polygon ON images_zone (image_id, polygon_hash); -""" - -# Experiments with production data has shown a tolerance of 15 is enough to simplify all polygons; -# we will try with tolerances from 1 to 20 to be safe. -MAX_TOLERANCE = 20 - - -def simplify_polygons(apps, schema_editor): - Zone = apps.get_model('images', 'Zone') - if not Zone.objects.exists(): - return - - print('Looking for polygons exceeding the maximum allowed size…') - count = Zone.objects.filter(polygon__memsize__gt=2664).count() - if not count: - return - - for tolerance in range(1, MAX_TOLERANCE - 1): - print(f'Simplifying {count} polygons with tolerance {tolerance}…') - Zone.objects \ - .filter(polygon__memsize__gt=2664) \ - .update(polygon=SimplifyPreserveTopology('polygon', tolerance)) - - count = Zone.objects.filter(polygon__memsize__gt=2664).count() - if not count: - print('Simplification successful!') - return - - raise ValueError('{count} existing polygons could not be simplified with a tolerance of {MAX_TOLERANCE}.') - - -class Migration(migrations.Migration): - - dependencies = [ - ('images', '0003_remove_image_datafile'), - ] - - operations = [ - CreateExtension('postgis'), - - # In images.0001, we made Django believe we managed to get a unique constraint - # on (image_id, polygon), so it now believes it does not need to change it. - # However, the previous unique constraint used a hack with polygon_hash, whereas - # the PostGIS geometry type allows an actual unique constraint without a generated column. - # Therefore, we first drop the previous constraint, and will recreate it differently later. - migrations.RunSQL( - POLYGON_HASH_FORWARD_SQL, - reverse_sql=POLYGON_HASH_REVERSE_SQL, - state_operations=[ - migrations.RemoveConstraint( - model_name='zone', - name='zone_unique_image_polygon' - ) - ], - ), - - # Django is unable to migrate from a polygon to a geometry(LINESTRING) - # since it would expect geometry(POLYGON). A PostGIS polygon has multiple rings, - # but we can only handle one ring, so a closed LineString is what we want. - # To update properly, we apply ST_Normalize and ST_RemoveRepeatedPoints - # (Polygon.reorder but for PostGIS), then we add potentially missing final points - # (ABCD instead of ABCDA), which would make a LineString be left open. - migrations.RunSQL( - sql=""" - ALTER TABLE images_zone - ALTER COLUMN polygon - TYPE geometry(LINESTRING, 0) - USING ST_RemoveRepeatedPoints(ST_ExteriorRing(ST_Normalize(polygon::geometry(POLYGON, 0)))); - - UPDATE images_zone - SET polygon = ST_AddPoint(polygon, ST_StartPoint(polygon)) - WHERE NOT ST_IsClosed(polygon); - """, - reverse_sql=""" - ALTER TABLE images_zone - ALTER COLUMN polygon - TYPE polygon - USING pclose(polygon::path)::polygon - """, - state_operations=[ - migrations.AlterField( - model_name='zone', - name='polygon', - field=LinearRingField(srid=0), - ) - ] - ), - - migrations.RunPython( - simplify_polygons, - reverse_code=migrations.RunPython.noop, - ), - - # ST_Normalize, the extra ending point and simplifications can lead to a small portion - # of the zones being duplicated due to that applying a more effective reordering than we did; - # this can require running `arkindex deduplicate_zones` to manually deduplicate zones - # before adding constraints. - # Adding the constraints is also done in another migration due to 'pending trigger events' - # on images_zone after the deduplication and simplification. - ] diff --git a/arkindex/images/migrations/0005_polygon_index.py b/arkindex/images/migrations/0005_polygon_index.py deleted file mode 100644 index 6b59929218f15e8cff0dcd6110e72781f971744d..0000000000000000000000000000000000000000 --- a/arkindex/images/migrations/0005_polygon_index.py +++ /dev/null @@ -1,42 +0,0 @@ -# Generated by Django 2.2.13 on 2020-07-30 13:54 - -from django.contrib.gis.db.models.functions import SnapToGrid -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('images', '0004_polygon_postgis'), - ] - - operations = [ - migrations.AddConstraint( - model_name='zone', - constraint=models.CheckConstraint( - check=models.Q(polygon__memsize__lte=2664), - name='zone_polygon_size', - ), - ), - migrations.AddConstraint( - model_name='zone', - constraint=models.CheckConstraint( - check=models.Q(polygon__isclosed=True), - name='zone_polygon_closed', - ), - ), - migrations.AddConstraint( - model_name='zone', - constraint=models.CheckConstraint( - check=models.Q(polygon=SnapToGrid('polygon', 1)), - name='zone_polygon_integer_coordinates', - ), - ), - migrations.AddConstraint( - model_name='zone', - constraint=models.UniqueConstraint( - fields=('image', 'polygon'), - name='zone_unique_image_polygon', - ), - ), - ] diff --git a/arkindex/images/migrations/0006_polygon_min_size.py b/arkindex/images/migrations/0006_polygon_min_size.py deleted file mode 100644 index 5c232c5cb21f724404319ea1fc45987a16c8e9ea..0000000000000000000000000000000000000000 --- a/arkindex/images/migrations/0006_polygon_min_size.py +++ /dev/null @@ -1,48 +0,0 @@ -# Generated by Django 3.1.3 on 2021-01-04 11:04 - -from django.db import migrations, models - - -def remove_small_polygons(apps, schema_editor): - """ - Removes polygons with less than 4 points. - """ - Element = apps.get_model('documents', 'Element') - Zone = apps.get_model('images', 'Zone') - - zone_ids = list(Zone.objects.using('default').filter(polygon__memsize__lt=96).values_list('id', flat=True)) - if not zone_ids: - return - - # Import the ElementQuerySet to access the trash() method - from arkindex.documents.managers import ElementQuerySet - ElementQuerySet(Element).filter(zone_id__in=zone_ids).trash() - - Zone.objects.filter(id__in=zone_ids)._raw_delete(using='default') - - -class Migration(migrations.Migration): - - dependencies = [ - ('images', '0005_polygon_index'), - ] - atomic = False - - operations = [ - migrations.RemoveConstraint( - model_name='zone', - name='zone_polygon_size', - ), - migrations.RunPython( - remove_small_polygons, - reverse_code=migrations.RunPython.noop, - elidable=True, - ), - migrations.AddConstraint( - model_name='zone', - constraint=models.CheckConstraint( - check=models.Q(polygon__memsize__gte=96, polygon__memsize__lte=2664), - name='zone_polygon_size' - ), - ), - ] diff --git a/arkindex/images/migrations/0007_update_zone_constraint.py b/arkindex/images/migrations/0007_update_zone_constraint.py deleted file mode 100644 index c84ddf1692fdcb0bf47b2d98fbc2e92eb0be9c8f..0000000000000000000000000000000000000000 --- a/arkindex/images/migrations/0007_update_zone_constraint.py +++ /dev/null @@ -1,25 +0,0 @@ -# Generated by Django 3.1.8 on 2021-04-26 13:32 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('images', '0006_polygon_min_size'), - ] - - operations = [ - migrations.RemoveConstraint( - model_name='zone', - name='zone_polygon_size', - ), - migrations.AddConstraint( - model_name='zone', - constraint=models.CheckConstraint(check=models.Q(('polygon__numpoints__gte', 4), ('polygon__numpoints__lte', 300)), name='zone_polygon_size'), - ), - migrations.AlterModelOptions( - name='zone', - options={'base_manager_name': 'objects'}, - ), - ] diff --git a/arkindex/images/migrations/0008_delete_zone.py b/arkindex/images/migrations/0008_delete_zone.py deleted file mode 100644 index cb2f4f771994b850f87717bcfed9145f6e2bb901..0000000000000000000000000000000000000000 --- a/arkindex/images/migrations/0008_delete_zone.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 3.2.3 on 2021-07-19 12:14 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0040_element_zone_constraints'), - ('images', '0007_update_zone_constraint'), - ] - - operations = [ - migrations.DeleteModel( - name='Zone', - ), - ] diff --git a/arkindex/images/migrations/0009_remove_imageserver_validated.py b/arkindex/images/migrations/0009_remove_imageserver_validated.py deleted file mode 100644 index 2ee2bcefac44c0db9b89fdafc451a0575f4e3f10..0000000000000000000000000000000000000000 --- a/arkindex/images/migrations/0009_remove_imageserver_validated.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 4.0.7 on 2022-10-12 14:39 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('images', '0008_delete_zone'), - ] - - operations = [ - migrations.RemoveField( - model_name='imageserver', - name='validated', - ), - ] diff --git a/arkindex/images/migrations/0010_rename_imageserver_readonly.py b/arkindex/images/migrations/0010_rename_imageserver_readonly.py deleted file mode 100644 index 70ac8072850cfd2c42ff0f06280efc75050979a6..0000000000000000000000000000000000000000 --- a/arkindex/images/migrations/0010_rename_imageserver_readonly.py +++ /dev/null @@ -1,47 +0,0 @@ -# Generated by Django 4.0.7 on 2022-10-14 13:27 - -from django.db import migrations, models - - -def disable_read_only_without_bucket(apps, schema_editor): - """ - Turn off s3_read_only_bucket on servers without S3 buckets - to ensure that the new check constraint is respected. - """ - ImageServer = apps.get_model('images', 'ImageServer') - ImageServer.objects.filter(s3_bucket__isnull=True).update(s3_read_only_bucket=False) - - -class Migration(migrations.Migration): - - dependencies = [ - ('images', '0009_remove_imageserver_validated'), - ] - - operations = [ - migrations.RenameField( - model_name='imageserver', - old_name='read_only', - new_name='s3_read_only_bucket', - ), - migrations.AlterField( - model_name='imageserver', - name='s3_read_only_bucket', - field=models.BooleanField( - default=False, - help_text='Disable the extra image checks that are normally made for servers with S3 buckets.', - ), - ), - migrations.RunPython( - disable_read_only_without_bucket, - reverse_code=migrations.RunPython.noop, - elidable=True, - ), - migrations.AddConstraint( - model_name='imageserver', - constraint=models.CheckConstraint( - check=models.Q(s3_read_only_bucket=False) | models.Q(s3_bucket__isnull=False), - name='s3_read_only_bucket_requires_s3_bucket' - ), - ), - ] diff --git a/arkindex/ponos/migrations/0001_initial.py b/arkindex/ponos/migrations/0001_initial.py index 083fb7c137f16e0e78805b6fc26612aac5358cbe..fd5bdd16a3e7ada7826e36d1b6773e46d868c21f 100644 --- a/arkindex/ponos/migrations/0001_initial.py +++ b/arkindex/ponos/migrations/0001_initial.py @@ -1,80 +1,170 @@ -# Generated by Django 2.1.4 on 2018-12-20 16:03 +# Generated by Django 4.1.7 on 2023-05-29 11:49 import uuid +import django.contrib.postgres.fields.hstore +import django.core.validators import django.db.models.deletion import enumfields.fields +from django.contrib.postgres.operations import HStoreExtension from django.db import migrations, models +import arkindex.ponos.keys import arkindex.ponos.models +import arkindex.ponos.validators +import arkindex.project.fields class Migration(migrations.Migration): initial = True - dependencies = [] + dependencies = [ + ] operations = [ + HStoreExtension(), + migrations.CreateModel( + name='Agent', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('public_key', models.TextField()), + ('hostname', models.SlugField(db_index=False, max_length=64)), + ('cpu_cores', models.PositiveSmallIntegerField(validators=[django.core.validators.MinValueValidator(1)])), + ('cpu_frequency', models.BigIntegerField(validators=[django.core.validators.MinValueValidator(1)])), + ('ram_total', models.BigIntegerField(validators=[django.core.validators.MinValueValidator(1)])), + ('cpu_load', models.FloatField(blank=True, null=True)), + ('ram_load', models.FloatField(blank=True, null=True)), + ('last_ping', models.DateTimeField(editable=False)), + ], + ), + migrations.CreateModel( + name='Artifact', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), + ('path', models.CharField(max_length=500)), + ('size', models.BigIntegerField(validators=[django.core.validators.MinValueValidator(1), arkindex.ponos.validators.MaxValueValidator(arkindex.ponos.models.artifact_max_size)])), + ('content_type', models.CharField(default='application/octet-stream', max_length=250)), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ], + options={ + 'ordering': ('task', 'path'), + }, + ), + migrations.CreateModel( + name='Farm', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), + ('name', models.CharField(max_length=250)), + ('seed', models.CharField(default=arkindex.ponos.models.generate_seed, max_length=64, unique=True, validators=[django.core.validators.RegexValidator('^[0-9a-f]{64}$')])), + ], + ), + migrations.CreateModel( + name='GPU', + fields=[ + ('id', models.UUIDField(primary_key=True, serialize=False)), + ('name', models.CharField(max_length=250)), + ('index', models.PositiveIntegerField()), + ('ram_total', models.BigIntegerField(validators=[django.core.validators.MinValueValidator(1)])), + ('agent', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='gpus', to='ponos.agent')), + ], + ), migrations.CreateModel( - name="Task", + name='Secret', fields=[ - ( - "id", - models.UUIDField( - default=uuid.uuid4, primary_key=True, serialize=False - ), - ), - ("run", models.PositiveIntegerField()), - ("depth", models.PositiveIntegerField()), - ("slug", models.CharField(max_length=250)), - ( - "state", - enumfields.fields.EnumField( - default="unscheduled", enum=arkindex.ponos.models.State, max_length=20 - ), - ), - ("container", models.CharField(blank=True, max_length=64, null=True)), - ("created", models.DateTimeField(auto_now_add=True)), - ("updated", models.DateTimeField(auto_now=True)), - ( - "parent", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="children", - to="ponos.Task", - ), - ), + ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), + ('name', models.CharField(max_length=250, unique=True)), + ('nonce', models.BinaryField(default=arkindex.ponos.keys.gen_nonce, max_length=16)), + ('content', models.BinaryField(editable=True)), ], - options={"ordering": ("workflow", "run", "depth", "slug")}, ), migrations.CreateModel( - name="Workflow", + name='Workflow', fields=[ - ( - "id", - models.UUIDField( - default=uuid.uuid4, primary_key=True, serialize=False - ), - ), - ("recipe", models.TextField()), - ("created", models.DateTimeField(auto_now_add=True)), - ("updated", models.DateTimeField(auto_now=True)), + ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('finished', models.DateTimeField(blank=True, null=True)), + ('farm', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='workflows', to='ponos.farm')), ], + options={ + 'ordering': ('-updated',), + }, + ), + migrations.CreateModel( + name='Task', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), + ('run', models.PositiveIntegerField()), + ('depth', models.PositiveIntegerField()), + ('slug', models.CharField(max_length=250, validators=[django.core.validators.MinLengthValidator(1)])), + ('priority', models.PositiveIntegerField(default=10)), + ('state', enumfields.fields.EnumField(default='unscheduled', enum=arkindex.ponos.models.State, max_length=20)), + ('tags', arkindex.project.fields.ArrayField(base_field=models.CharField(max_length=250), blank=True, default=list, size=16)), + ('image', models.CharField(max_length=250)), + ('shm_size', models.CharField(blank=True, editable=False, max_length=80, null=True)), + ('command', models.TextField(blank=True, null=True)), + ('env', django.contrib.postgres.fields.hstore.HStoreField(default=dict)), + ('has_docker_socket', models.BooleanField(default=False)), + ('requires_gpu', models.BooleanField(default=False)), + ('container', models.CharField(blank=True, max_length=64, null=True)), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('expiry', models.DateTimeField(default=arkindex.ponos.models.expiry_default)), + ('extra_files', django.contrib.postgres.fields.hstore.HStoreField(default=dict)), + ('token', models.CharField(default=arkindex.ponos.models.task_token_default, max_length=52, unique=True)), + ('agent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='tasks', to='ponos.agent')), + ('gpu', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='tasks', to='ponos.gpu')), + ('image_artifact', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='tasks_using_image', to='ponos.artifact')), + ('parents', models.ManyToManyField(related_name='children', to='ponos.task')), + ('workflow', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tasks', to='ponos.workflow')), + ], + options={ + 'ordering': ('workflow', 'run', 'depth', 'slug'), + }, ), migrations.AddField( - model_name="task", - name="workflow", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="tasks", - to="ponos.Workflow", - ), + model_name='artifact', + name='task', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='artifacts', to='ponos.task'), + ), + migrations.AddField( + model_name='agent', + name='farm', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='ponos.farm'), + ), + migrations.CreateModel( + name='AgentUser', + fields=[ + ], + options={ + 'proxy': True, + 'indexes': [], + 'constraints': [], + }, + bases=('ponos.agent',), + ), + migrations.AddConstraint( + model_name='workflow', + constraint=models.CheckConstraint(check=models.Q(('finished', None), ('finished__gte', models.F('created')), _connector='OR'), name='ponos_workflow_finished_after_created'), + ), + migrations.AddConstraint( + model_name='task', + constraint=models.UniqueConstraint(models.F('gpu'), condition=models.Q(('state__in', (arkindex.ponos.models.State['Unscheduled'], arkindex.ponos.models.State['Pending'], arkindex.ponos.models.State['Running'], arkindex.ponos.models.State['Stopping']))), name='unique_gpu_on_active_tasks'), + ), + migrations.AlterUniqueTogether( + name='task', + unique_together={('workflow', 'run', 'slug')}, + ), + migrations.AlterUniqueTogether( + name='gpu', + unique_together={('agent_id', 'index')}, ), migrations.AlterUniqueTogether( - name="task", - unique_together={("workflow", "run", "slug")}, + name='artifact', + unique_together={('task', 'path')}, ), ] diff --git a/arkindex/ponos/migrations/0002_recipe_validator.py b/arkindex/ponos/migrations/0002_recipe_validator.py deleted file mode 100644 index 6b971f659dd639eb02696bbd24739db503862ca4..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0002_recipe_validator.py +++ /dev/null @@ -1,26 +0,0 @@ -# Generated by Django 2.1.7 on 2019-06-24 08:57 - -from django.db import migrations, models - - -def recipe_validator(value) -> None: - """ - This previously was a validator for YAML recipes. - Since those recipes have now been removed, this function is left here only so that migrations remain consistent. - """ - pass - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0001_initial"), - ] - - operations = [ - migrations.AlterField( - model_name="workflow", - name="recipe", - field=models.TextField(validators=[recipe_validator]), - ), - ] diff --git a/arkindex/ponos/migrations/0003_no_empty_slugs.py b/arkindex/ponos/migrations/0003_no_empty_slugs.py deleted file mode 100644 index 6f3d1978d60b9bf6b50d5242860c1227dd2a8f7b..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0003_no_empty_slugs.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 2.1.7 on 2019-06-24 09:05 - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0002_recipe_validator"), - ] - - operations = [ - migrations.AlterField( - model_name="task", - name="slug", - field=models.CharField( - max_length=250, - validators=[django.core.validators.MinLengthValidator(1)], - ), - ), - ] diff --git a/arkindex/ponos/migrations/0004_agent.py b/arkindex/ponos/migrations/0004_agent.py deleted file mode 100644 index 26a3a3a84600be534045edd81f9a9e402caf08f5..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0004_agent.py +++ /dev/null @@ -1,76 +0,0 @@ -# Generated by Django 2.1.7 on 2019-06-05 08:48 - -import uuid - -import django.core.validators -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0003_no_empty_slugs"), - ] - - operations = [ - migrations.CreateModel( - name="Agent", - fields=[ - ( - "id", - models.UUIDField( - default=uuid.uuid4, primary_key=True, serialize=False - ), - ), - ("created", models.DateTimeField(auto_now_add=True)), - ("updated", models.DateTimeField(auto_now=True)), - ( - "token", - models.CharField( - max_length=250, - unique=True, - validators=[ - django.core.validators.RegexValidator(r"^[0-9a-f]{64}$") - ], - ), - ), - ("hostname", models.SlugField(db_index=False, max_length=64)), - ( - "cpu_cores", - models.PositiveSmallIntegerField( - validators=[django.core.validators.MinValueValidator(1)], - ), - ), - ( - "cpu_frequency", - models.BigIntegerField( - validators=[django.core.validators.MinValueValidator(1)], - ), - ), - ("gpu_names", models.TextField()), - ("gpu_count", models.PositiveSmallIntegerField()), - ], - ), - migrations.AlterModelOptions( - name="workflow", - options={"ordering": ("-updated",)}, - ), - migrations.AddField( - model_name="task", - name="agent", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name="tasks", - to="ponos.Agent", - ), - ), - migrations.CreateModel( - name="AgentUser", - fields=[], - options={"proxy": True, "indexes": []}, - bases=("ponos.agent",), - ), - ] diff --git a/arkindex/ponos/migrations/0005_gpu_names_blank.py b/arkindex/ponos/migrations/0005_gpu_names_blank.py deleted file mode 100644 index 5a33f4aea40121a12a35b110081360547a31e583..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0005_gpu_names_blank.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 2.1.7 on 2019-07-02 08:00 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0004_agent"), - ] - - operations = [ - migrations.AlterField( - model_name="agent", - name="gpu_names", - field=models.TextField(blank=True, null=True), - ), - ] diff --git a/arkindex/ponos/migrations/0006_add_parents.py b/arkindex/ponos/migrations/0006_add_parents.py deleted file mode 100644 index 5d9f103262922647fdf4533e376f24184b95eb93..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0006_add_parents.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 2.1.7 on 2019-06-21 09:31 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0005_gpu_names_blank"), - ] - - operations = [ - migrations.AddField( - model_name="task", - name="parents", - field=models.ManyToManyField( - related_name="children", to="ponos.Task", symmetrical=False - ), - ), - ] diff --git a/arkindex/ponos/migrations/0007_migrate_parents.py b/arkindex/ponos/migrations/0007_migrate_parents.py deleted file mode 100644 index d3d630314886714c8edd99b90d8ce35bc008612a..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0007_migrate_parents.py +++ /dev/null @@ -1,51 +0,0 @@ -# Generated by Django 2.1.7 on 2019-06-21 09:31 - -from django.db import migrations -from django.db.models import Count - - -def parent_to_parents(apps, schema_editor): - db_alias = schema_editor.connection.alias - Task = apps.get_model("ponos", "Task") - TaskParent = Task.parents.through - - new_parents = [] - for task in ( - Task.objects.using(db_alias).exclude(parent=None).only("id", "parent_id") - ): - new_parents.append( - TaskParent( - from_task_id=task.id, - to_task_id=task.parent_id, - ) - ) - TaskParent.objects.using(db_alias).bulk_create(new_parents) - - -def parents_to_parent(apps, schema_editor): - db_alias = schema_editor.connection.alias - Task = apps.get_model("ponos", "Task") - assert ( - not Task.objects.using(db_alias) - .annotate(parents_count=Count("parents")) - .filter(parents_count__gt=1) - .exists() - ), "Cannot migrate task with multiple parents backwards" - - for task in Task.objects.using(db_alias).filter(parents__isnull=False): - task.parent = task.parents.get() - task.save() - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0006_add_parents"), - ] - - operations = [ - migrations.RunPython( - parent_to_parents, - parents_to_parent, - ), - ] diff --git a/arkindex/ponos/migrations/0008_remove_parent.py b/arkindex/ponos/migrations/0008_remove_parent.py deleted file mode 100644 index 396fc3dedc3cdfb3e46e07a172997e6efc1265e5..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0008_remove_parent.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 2.1.7 on 2019-06-21 09:32 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0007_migrate_parents"), - ] - - operations = [ - migrations.RemoveField( - model_name="task", - name="parent", - ), - ] diff --git a/arkindex/ponos/migrations/0009_tags.py b/arkindex/ponos/migrations/0009_tags.py deleted file mode 100644 index a378c6a50d0ab60d37d74c82836f6e65ef01c61c..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0009_tags.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 2.1.7 on 2019-07-10 14:20 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0008_remove_parent"), - ] - - operations = [ - migrations.AddField( - model_name="agent", - name="tags", - field=models.CharField(default="", max_length=250), - ), - migrations.AddField( - model_name="task", - name="tags", - field=models.CharField(default="", max_length=250), - ), - ] diff --git a/arkindex/ponos/migrations/0010_farm.py b/arkindex/ponos/migrations/0010_farm.py deleted file mode 100644 index 8f01d0d329e777a2971bea8a9c64ecdc914e19c2..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0010_farm.py +++ /dev/null @@ -1,91 +0,0 @@ -# Generated by Django 2.1.7 on 2019-07-03 14:07 - -import uuid - -import django.core.validators -import django.db.models.deletion -from django.db import migrations, models - -import arkindex.ponos.models - - -def default_farm(apps, schema_editor): - db_alias = schema_editor.connection.alias - Agent = apps.get_model("ponos", "Agent") - if not Agent.objects.using(db_alias).exists(): - return - - Farm = apps.get_model("ponos", "Farm") - default_farm = Farm.objects.using(db_alias).create(name="default") - Agent.objects.using(db_alias).all().update(farm=default_farm) - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0009_tags"), - ] - - operations = [ - migrations.CreateModel( - name="Farm", - fields=[ - ( - "id", - models.UUIDField( - default=uuid.uuid4, - primary_key=True, - serialize=False, - ), - ), - ( - "name", - models.CharField( - max_length=250, - ), - ), - ( - "seed", - models.CharField( - default=arkindex.ponos.models.generate_seed, - max_length=64, - unique=True, - validators=[ - django.core.validators.RegexValidator("^[0-9a-f]{64}$") - ], - ), - ), - ], - ), - migrations.AddField( - model_name="agent", - name="farm", - field=models.ForeignKey( - on_delete=django.db.models.deletion.PROTECT, - to="ponos.Farm", - blank=True, - null=True, - ), - ), - migrations.RunPython( - default_farm, - reverse_code=migrations.RunPython.noop, - elidable=True, - ), - migrations.AlterField( - model_name="agent", - name="farm", - field=models.ForeignKey( - on_delete=django.db.models.deletion.PROTECT, - to="ponos.Farm", - ), - ), - migrations.AddField( - model_name="agent", - name="public_key", - field=models.TextField( - default="", - ), - preserve_default=False, - ), - ] diff --git a/arkindex/ponos/migrations/0011_remove_agent_token.py b/arkindex/ponos/migrations/0011_remove_agent_token.py deleted file mode 100644 index 6000d2cf471a709a1ed861f126fc47203ed9d19f..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0011_remove_agent_token.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 2.1.7 on 2019-07-04 13:34 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0010_farm"), - ] - - operations = [ - migrations.RemoveField( - model_name="agent", - name="token", - ), - ] diff --git a/arkindex/ponos/migrations/0012_advanced_tags.py b/arkindex/ponos/migrations/0012_advanced_tags.py deleted file mode 100644 index 073a13d5f28035b7a3f26e09a352fbe095d9e25d..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0012_advanced_tags.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 2.2.5 on 2019-09-04 13:34 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0011_remove_agent_token"), - ] - - operations = [ - migrations.RenameField( - model_name="agent", - old_name="tags", - new_name="include_tags", - ), - migrations.AddField( - model_name="agent", - name="exclude_tags", - field=models.CharField(default="", max_length=250), - ), - ] diff --git a/arkindex/ponos/migrations/0013_artifact.py b/arkindex/ponos/migrations/0013_artifact.py deleted file mode 100644 index 8f212321b4434e15296111680da3d9aec65c4067..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0013_artifact.py +++ /dev/null @@ -1,49 +0,0 @@ -# Generated by Django 2.2.12 on 2020-05-27 09:29 - -import uuid - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0012_advanced_tags"), - ] - - operations = [ - migrations.CreateModel( - name="Artifact", - fields=[ - ( - "id", - models.UUIDField( - default=uuid.uuid4, primary_key=True, serialize=False - ), - ), - ("path", models.CharField(max_length=500)), - ("size", models.PositiveIntegerField()), - ( - "content_type", - models.CharField( - default="application/octet-stream", max_length=250 - ), - ), - ( - "task", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="artifacts", - to="ponos.Task", - ), - ), - ("created", models.DateTimeField(auto_now_add=True)), - ("updated", models.DateTimeField(auto_now=True)), - ], - options={ - "ordering": ("task", "path"), - "unique_together": {("task", "path")}, - }, - ), - ] diff --git a/arkindex/ponos/migrations/0014_modify_task_model.py b/arkindex/ponos/migrations/0014_modify_task_model.py deleted file mode 100644 index eb07679696555688f37801317dac2c0cb6697d50..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0014_modify_task_model.py +++ /dev/null @@ -1,33 +0,0 @@ -# Generated by Django 2.2.12 on 2020-06-05 08:53 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0013_artifact"), - ] - - operations = [ - migrations.AddField( - model_name="task", - name="command", - field=models.TextField(null=True), - ), - migrations.AddField( - model_name="task", - name="env", - field=models.JSONField(null=True), - ), - migrations.AddField( - model_name="task", - name="image", - field=models.CharField(null=True, max_length=250), - ), - migrations.AlterField( - model_name="task", - name="image", - field=models.CharField(max_length=250), - ), - ] diff --git a/arkindex/ponos/migrations/0015_task_has_docker_socket.py b/arkindex/ponos/migrations/0015_task_has_docker_socket.py deleted file mode 100644 index de50d041674c133fdc9d393a2528c7d2bef95102..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0015_task_has_docker_socket.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 2.2.12 on 2020-06-11 08:30 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0014_modify_task_model"), - ] - - operations = [ - migrations.AddField( - model_name="task", - name="has_docker_socket", - field=models.BooleanField(default=False), - ), - ] diff --git a/arkindex/ponos/migrations/0016_task_image_artifact.py b/arkindex/ponos/migrations/0016_task_image_artifact.py deleted file mode 100644 index aa3cf3ea307e44e8fc1805e56e5754ad55864980..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0016_task_image_artifact.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 2.2.13 on 2020-07-07 08:42 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0015_task_has_docker_socket"), - ] - - operations = [ - migrations.AddField( - model_name="task", - name="image_artifact", - field=models.ForeignKey( - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name="tasks_using_image", - to="ponos.Artifact", - ), - ), - ] diff --git a/arkindex/ponos/migrations/0017_new_jsonfield.py b/arkindex/ponos/migrations/0017_new_jsonfield.py deleted file mode 100644 index 24e2875da652649b89095790f04cd2cea926923f..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0017_new_jsonfield.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.1 on 2020-08-10 14:59 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0016_task_image_artifact"), - ] - - operations = [ - migrations.AlterField( - model_name="task", - name="env", - field=models.JSONField(null=True), - ), - ] diff --git a/arkindex/ponos/migrations/0018_auto_20200814_0818.py b/arkindex/ponos/migrations/0018_auto_20200814_0818.py deleted file mode 100644 index 6ce079bf148d6e03cfb4f8a4b8c2620938750686..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0018_auto_20200814_0818.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.1 on 2020-08-14 08:18 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0017_new_jsonfield"), - ] - - operations = [ - migrations.AlterField( - model_name="artifact", - name="size", - field=models.PositiveBigIntegerField(), - ), - ] diff --git a/arkindex/ponos/migrations/0019_secret.py b/arkindex/ponos/migrations/0019_secret.py deleted file mode 100644 index bb33c07f76f45428bf23c489f5e4dfffd06404f5..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0019_secret.py +++ /dev/null @@ -1,34 +0,0 @@ -# Generated by Django 3.1 on 2020-09-24 14:12 - -import uuid - -from django.db import migrations, models - -import arkindex.ponos.keys - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0018_auto_20200814_0818"), - ] - - operations = [ - migrations.CreateModel( - name="Secret", - fields=[ - ( - "id", - models.UUIDField( - default=uuid.uuid4, primary_key=True, serialize=False - ), - ), - ("name", models.CharField(max_length=250, unique=True)), - ( - "nonce", - models.BinaryField(default=arkindex.ponos.keys.gen_nonce, max_length=16), - ), - ("content", models.BinaryField(editable=True)), - ], - ), - ] diff --git a/arkindex/ponos/migrations/0020_fix_admin_blank.py b/arkindex/ponos/migrations/0020_fix_admin_blank.py deleted file mode 100644 index d1e47bf09aec75e20c02f390d845067d087e9182..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0020_fix_admin_blank.py +++ /dev/null @@ -1,35 +0,0 @@ -# Generated by Django 3.1.2 on 2020-10-19 10:58 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0019_secret"), - ] - - operations = [ - migrations.AlterField( - model_name="task", - name="command", - field=models.TextField(blank=True, null=True), - ), - migrations.AlterField( - model_name="task", - name="env", - field=models.JSONField(blank=True, null=True), - ), - migrations.AlterField( - model_name="task", - name="image_artifact", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name="tasks_using_image", - to="ponos.artifact", - ), - ), - ] diff --git a/arkindex/ponos/migrations/0021_add_ping_and_ram_fields.py b/arkindex/ponos/migrations/0021_add_ping_and_ram_fields.py deleted file mode 100644 index d681f6af656ad549b669e85ba252f8966a3eb66a..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0021_add_ping_and_ram_fields.py +++ /dev/null @@ -1,53 +0,0 @@ -# Generated by Django 3.1 on 2020-10-27 10:44 - -import django.core.validators -from django.db import migrations, models - - -def set_default_ping(apps, schema_editor): - Agent = apps.get_model("ponos", "Agent") - Agent.objects.all().update(last_ping=models.F("updated")) - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0020_fix_admin_blank"), - ] - - operations = [ - migrations.AddField( - model_name="agent", - name="cpu_load", - field=models.FloatField(blank=True, null=True), - ), - migrations.AddField( - model_name="agent", - name="ram_load", - field=models.FloatField(blank=True, null=True), - ), - migrations.AddField( - model_name="agent", - name="ram_total", - field=models.BigIntegerField( - default=1, validators=[django.core.validators.MinValueValidator(1)] - ), - preserve_default=False, - ), - migrations.AddField( - model_name="agent", - name="last_ping", - field=models.DateTimeField(auto_now=True), - preserve_default=False, - ), - migrations.RunPython( - set_default_ping, - reverse_code=migrations.RunPython.noop, - elidable=True, - ), - migrations.AlterField( - model_name="agent", - name="last_ping", - field=models.DateTimeField(editable=False), - ), - ] diff --git a/arkindex/ponos/migrations/0022_rm_excluded_included_tags.py b/arkindex/ponos/migrations/0022_rm_excluded_included_tags.py deleted file mode 100644 index ae2e173b008a6d203722a7a033a420d1205e85a5..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0022_rm_excluded_included_tags.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 3.1 on 2020-11-02 10:37 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0021_add_ping_and_ram_fields"), - ] - - operations = [ - migrations.RemoveField( - model_name="agent", - name="exclude_tags", - ), - migrations.RemoveField( - model_name="agent", - name="include_tags", - ), - ] diff --git a/arkindex/ponos/migrations/0023_gpus.py b/arkindex/ponos/migrations/0023_gpus.py deleted file mode 100644 index 1d9cf6b56357a8e8137cce4349519df7f1466b7b..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0023_gpus.py +++ /dev/null @@ -1,62 +0,0 @@ -# Generated by Django 3.1.2 on 2020-11-18 09:30 - -import django.core.validators -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0022_rm_excluded_included_tags"), - ] - - operations = [ - migrations.RemoveField( - model_name="agent", - name="gpu_count", - ), - migrations.RemoveField( - model_name="agent", - name="gpu_names", - ), - migrations.CreateModel( - name="GPU", - fields=[ - ( - "id", - models.UUIDField(primary_key=True, serialize=False), - ), - ("name", models.CharField(max_length=250)), - ("index", models.PositiveIntegerField()), - ( - "ram_total", - models.BigIntegerField( - validators=[django.core.validators.MinValueValidator(1)] - ), - ), - ( - "agent", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="gpus", - to="ponos.agent", - ), - ), - ], - options={ - "unique_together": {("agent_id", "index")}, - }, - ), - migrations.AddField( - model_name="task", - name="gpu", - field=models.OneToOneField( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name="task", - to="ponos.gpu", - ), - ), - ] diff --git a/arkindex/ponos/migrations/0024_task_requires_gpu.py b/arkindex/ponos/migrations/0024_task_requires_gpu.py deleted file mode 100644 index 0d919b167e18a0e673c10073e1431d01223b302c..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0024_task_requires_gpu.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.1.2 on 2020-12-10 16:00 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0023_gpus"), - ] - - operations = [ - migrations.AddField( - model_name="task", - name="requires_gpu", - field=models.BooleanField(default=False), - ), - ] diff --git a/arkindex/ponos/migrations/0025_workflow_farm.py b/arkindex/ponos/migrations/0025_workflow_farm.py deleted file mode 100644 index b679ae75622d79f82dada0c8b072ff7368a35b86..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0025_workflow_farm.py +++ /dev/null @@ -1,53 +0,0 @@ -# Generated by Django 3.1.5 on 2021-02-23 15:52 - -import uuid - -import django.db.models.deletion -from django.db import migrations, models - -DEFAULT_FARM_ID = uuid.uuid4() - - -def set_default_farm(apps, schema_editor): - Workflow = apps.get_model("ponos", "Workflow") - Farm = apps.get_model("ponos", "Farm") - workflows = Workflow.objects.all() - if not workflows.exists(): - return - default_farm = Farm.objects.order_by().first() - if not default_farm: - # Create a default farm if required - default_farm = Farm.objects.create(name="Default farm") - workflows.update(farm_id=default_farm.id) - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0024_task_requires_gpu"), - ] - - operations = [ - migrations.AddField( - model_name="workflow", - name="farm", - field=models.ForeignKey( - on_delete=django.db.models.deletion.PROTECT, null=True, to="ponos.farm" - ), - ), - migrations.RunPython( - set_default_farm, - reverse_code=migrations.RunPython.noop, - # No workflow exists initially - elidable=True, - ), - migrations.AlterField( - model_name="workflow", - name="farm", - field=models.ForeignKey( - on_delete=django.db.models.deletion.PROTECT, - related_name="workflows", - to="ponos.farm", - ), - ), - ] diff --git a/arkindex/ponos/migrations/0026_alter_artifact_size.py b/arkindex/ponos/migrations/0026_alter_artifact_size.py deleted file mode 100644 index f2898ad0571057f98d4dddc92a07b117cecb5cf0..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0026_alter_artifact_size.py +++ /dev/null @@ -1,34 +0,0 @@ -# Generated by Django 3.2.3 on 2021-07-07 09:09 - -import django.core.validators -from django.db import migrations, models - - -def delete_large_artifacts(apps, schema_editor): - Artifact = apps.get_model("ponos", "Artifact") - Artifact.objects.filter( - models.Q(size__lt=1) | models.Q(size__gt=5368709120) - ).delete() - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0025_workflow_farm"), - ] - - operations = [ - migrations.RunPython( - delete_large_artifacts, reverse_code=migrations.RunPython.noop - ), - migrations.AlterField( - model_name="artifact", - name="size", - field=models.BigIntegerField( - validators=[ - django.core.validators.MinValueValidator(1), - django.core.validators.MaxValueValidator(5368709120), - ] - ), - ), - ] diff --git a/arkindex/ponos/migrations/0027_task_priority.py b/arkindex/ponos/migrations/0027_task_priority.py deleted file mode 100644 index cb1033c6a0f7624de65e1f21fb0d89a3353cb5d9..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0027_task_priority.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.2.5 on 2021-07-20 10:56 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0026_alter_artifact_size"), - ] - - operations = [ - migrations.AddField( - model_name="task", - name="priority", - field=models.PositiveIntegerField(default=10), - ), - ] diff --git a/arkindex/ponos/migrations/0028_workflow_finished.py b/arkindex/ponos/migrations/0028_workflow_finished.py deleted file mode 100644 index fef4a65faef0718ae7a65f5fbf5fe331305553bf..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0028_workflow_finished.py +++ /dev/null @@ -1,26 +0,0 @@ -# Generated by Django 4.0.1 on 2022-02-15 09:55 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0027_task_priority"), - ] - - operations = [ - migrations.AddField( - model_name="workflow", - name="finished", - field=models.DateTimeField(blank=True, null=True), - ), - migrations.AddConstraint( - model_name="workflow", - constraint=models.CheckConstraint( - check=models.Q(finished=None) - | models.Q(finished__gte=models.F("created")), - name="ponos_workflow_finished_after_created", - ), - ), - ] diff --git a/arkindex/ponos/migrations/0029_task_expiry.py b/arkindex/ponos/migrations/0029_task_expiry.py deleted file mode 100644 index 662f5f7e32aae84574116f97f19064f9af2f6908..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0029_task_expiry.py +++ /dev/null @@ -1,36 +0,0 @@ -# Generated by Django 4.0.1 on 2022-03-28 15:53 - -from datetime import timedelta - -from django.db import migrations, models - -from arkindex.ponos.models import expiry_default - - -def set_expiry(apps, schema_editor): - Task = apps.get_model("ponos", "Task") - Task.objects.update(expiry=models.F("updated") + timedelta(days=30)) - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0028_workflow_finished"), - ] - - operations = [ - migrations.AddField( - model_name="task", - name="expiry", - field=models.DateTimeField(null=True), - ), - migrations.RunPython( - set_expiry, - reverse_code=migrations.RunPython.noop, - ), - migrations.AlterField( - model_name="task", - name="expiry", - field=models.DateTimeField(default=expiry_default), - ), - ] diff --git a/arkindex/ponos/migrations/0030_task_extra_files.py b/arkindex/ponos/migrations/0030_task_extra_files.py deleted file mode 100644 index f36fa9f7c7526f369725a2e7f06183388e53aa5d..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0030_task_extra_files.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.0.2 on 2022-06-07 11:33 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0029_task_expiry"), - ] - - operations = [ - migrations.AddField( - model_name="task", - name="extra_files", - field=models.JSONField(default=dict), - ), - ] diff --git a/arkindex/ponos/migrations/0031_emptyable_jsonfield.py b/arkindex/ponos/migrations/0031_emptyable_jsonfield.py deleted file mode 100644 index c18fd739acc0b913bc1286f773ed2189f6d5608b..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0031_emptyable_jsonfield.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 4.0.5 on 2022-06-27 15:03 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0030_task_extra_files"), - ] - - operations = [ - migrations.AlterField( - model_name="task", - name="env", - field=models.JSONField(blank=True, null=True), - ), - migrations.AlterField( - model_name="task", - name="extra_files", - field=models.JSONField(default=dict), - ), - ] diff --git a/arkindex/ponos/migrations/0032_stringify_json.py b/arkindex/ponos/migrations/0032_stringify_json.py deleted file mode 100644 index ae2a768810615fb3084ca7c1a59be5400a5b7ed4..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0032_stringify_json.py +++ /dev/null @@ -1,68 +0,0 @@ -# Generated by Django 4.0.5 on 2022-06-27 15:08 - -from django.db import migrations - - -def stringify_json(apps, schema_editor): - if schema_editor.connection.vendor == "postgresql": - # Postgres' jsonb type allows to stringify all payloads in one query per column - schema_editor.execute( - """ - UPDATE ponos_task - SET env = ( - SELECT jsonb_object(array_agg(key), array_agg(value)) - FROM jsonb_each_text(env) - ) - WHERE id in ( - SELECT id FROM ponos_task, jsonb_each(env) AS env_items - WHERE jsonb_typeof(env_items.value) <> 'string' - ); - """ - ) - schema_editor.execute( - """ - UPDATE ponos_task - SET extra_files = ( - SELECT jsonb_object(array_agg(key), array_agg(value)) - FROM jsonb_each_text(extra_files) - ) - WHERE id in ( - SELECT id FROM ponos_task, jsonb_each(extra_files) AS extra_files_items - WHERE jsonb_typeof(extra_files_items.value) <> 'string' - ); - """ - ) - - else: - Task = apps.get_model("ponos", "Task") - to_update = [] - for task in Task.objects.only("id", "env", "extra_files"): - updated = False - - if task.env and not all(isinstance(value, str) for value in task.env): - task.env = {key: str(value) for key, value in task.env.items()} - updated = True - - if task.extra_files and not all( - isinstance(value, str) for value in task.extra_files - ): - task.extra_files = { - key: str(value) for key, value in task.extra_files.items() - } - updated = True - - if updated: - to_update.append(task) - - Task.objects.bulk_update(to_update, fields=["env", "extra_files"]) - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0031_emptyable_jsonfield"), - ] - - operations = [ - migrations.RunPython(stringify_json, reverse_code=migrations.RunPython.noop), - ] diff --git a/arkindex/ponos/migrations/0033_task_shm_size.py b/arkindex/ponos/migrations/0033_task_shm_size.py deleted file mode 100644 index 9623c8b669b387c17df7a2bc4a074b8973bd495d..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0033_task_shm_size.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 4.0.4 on 2022-10-20 14:37 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0032_stringify_json"), - ] - - operations = [ - migrations.AddField( - model_name="task", - name="shm_size", - field=models.CharField( - blank=True, editable=False, max_length=80, null=True - ), - ), - ] diff --git a/arkindex/ponos/migrations/0034_alter_artifact_size.py b/arkindex/ponos/migrations/0034_alter_artifact_size.py deleted file mode 100644 index 94a378d25a725b5bbde2bd66f41f25660898147f..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0034_alter_artifact_size.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 4.1.3 on 2023-01-09 09:52 - -from django.core.validators import MinValueValidator -from django.db import migrations, models - -from arkindex.ponos.models import artifact_max_size -from arkindex.ponos.validators import MaxValueValidator - - -class Migration(migrations.Migration): - - dependencies = [ - ("ponos", "0033_task_shm_size"), - ] - - operations = [ - migrations.AlterField( - model_name="artifact", - name="size", - field=models.BigIntegerField( - validators=[MinValueValidator(1), MaxValueValidator(artifact_max_size)] - ), - ), - ] diff --git a/arkindex/ponos/migrations/0035_alter_task_tags.py b/arkindex/ponos/migrations/0035_alter_task_tags.py deleted file mode 100644 index 82e05b839acc74c1a9ebc0988c55a73a358c439d..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0035_alter_task_tags.py +++ /dev/null @@ -1,64 +0,0 @@ -from django.db import migrations, models - -import arkindex.project.fields - - -def comma_sep_char_to_list(apps, schema_editor): - Task = apps.get_model("ponos", "Task") - tasks_attrs = Task.objects.using('default').values_list("id", "old_tags") - Task.objects.bulk_update( - ( - Task( - id=task_id, - tags=old_tags.split(",") if old_tags else [] - ) for task_id, old_tags in tasks_attrs - ), - ['tags'] - ) - - -def revert_comma_sep_char_to_list(apps, schema_editor): - Task = apps.get_model("ponos", "Task") - tasks_attrs = Task.objects.using('default').values_list("id", "tags") - Task.objects.bulk_update( - ( - Task( - id=task_id, - old_tags=",".join(tags) - ) for task_id, tags in tasks_attrs - ), - ['old_tags'] - ) - - -class Migration(migrations.Migration): - - dependencies = [ - ('ponos', '0034_alter_artifact_size'), - ] - - operations = [ - migrations.RenameField( - model_name="task", - old_name="tags", - new_name="old_tags", - ), - migrations.AddField( - model_name='task', - name='tags', - field=arkindex.project.fields.ArrayField( - base_field=models.CharField(max_length=250), - blank=True, - default=list, - size=16, - ), - ), - migrations.RunPython( - comma_sep_char_to_list, - reverse_code=revert_comma_sep_char_to_list, - ), - migrations.RemoveField( - model_name='task', - name='old_tags', - ), - ] diff --git a/arkindex/ponos/migrations/0036_hstore_task_env_and_extra_files.py b/arkindex/ponos/migrations/0036_hstore_task_env_and_extra_files.py deleted file mode 100644 index b2a1c4270b0f02f440298ee36d6ff5d56584acfd..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0036_hstore_task_env_and_extra_files.py +++ /dev/null @@ -1,62 +0,0 @@ -# Generated by Django 4.1.5 on 2023-02-03 08:39 - -import django.contrib.postgres.fields.hstore -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('ponos', '0035_alter_task_tags'), - ] - - operations = [ - migrations.RenameField( - model_name="task", - old_name="env", - new_name="old_env", - ), - migrations.RenameField( - model_name="task", - old_name="extra_files", - new_name="old_extra_files", - ), - migrations.AddField( - model_name='task', - name='env', - field=django.contrib.postgres.fields.hstore.HStoreField(default=dict), - ), - migrations.AddField( - model_name='task', - name='extra_files', - field=django.contrib.postgres.fields.hstore.HStoreField(default=dict), - ), - migrations.RunSQL( - """ - UPDATE ponos_task SET - env = ( - SELECT COALESCE(hstore(array_agg(key), array_agg(value)), hstore('')) - FROM jsonb_each_text(old_env) - ), - extra_files = ( - SELECT COALESCE(hstore(array_agg(key), array_agg(value)), hstore('')) - FROM jsonb_each_text(old_extra_files) - ) - ; - """, - reverse_sql=""" - UPDATE ponos_task SET - old_env = env::jsonb, - old_extra_files = extra_files::jsonb - ; - """ - ), - migrations.RemoveField( - model_name='task', - name='old_env', - ), - migrations.RemoveField( - model_name='task', - name='old_extra_files', - ), - ] diff --git a/arkindex/ponos/migrations/0037_task_token.py b/arkindex/ponos/migrations/0037_task_token.py deleted file mode 100644 index bb11372fc4392f47d87393344bb5c11ec4611a23..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0037_task_token.py +++ /dev/null @@ -1,38 +0,0 @@ -# Generated by Django 4.1.7 on 2023-03-07 15:19 - -from django.db import migrations, models - -from arkindex.ponos.models import task_token_default - - -def add_task_tokens(apps, schema_editor): - Task = apps.get_model('ponos', 'Task') - to_update = [] - for task in Task.objects.filter(token=None).only('id').iterator(): - task.token = task_token_default() - to_update.append(task) - Task.objects.bulk_update(to_update, ['token'], batch_size=100) - - -class Migration(migrations.Migration): - - dependencies = [ - ('ponos', '0036_hstore_task_env_and_extra_files'), - ] - - operations = [ - migrations.AddField( - model_name='task', - name='token', - field=models.CharField( - max_length=52, - # Make the field temporarily nullable and not unique, so that we can - # fill the tokens on existing tasks before adding the constraints. - null=True, - ), - ), - migrations.RunPython( - add_task_tokens, - reverse_code=migrations.RunPython.noop, - ), - ] diff --git a/arkindex/ponos/migrations/0038_task_token_unique.py b/arkindex/ponos/migrations/0038_task_token_unique.py deleted file mode 100644 index 5de95c85ee7afba67531028d0fd1fb9eaac1c586..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0038_task_token_unique.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 4.1.7 on 2023-03-07 15:25 - -from django.db import migrations, models - -from arkindex.ponos.models import task_token_default - - -class Migration(migrations.Migration): - - dependencies = [ - ('ponos', '0037_task_token'), - ] - - operations = [ - migrations.AlterField( - model_name='task', - name='token', - field=models.CharField( - default=task_token_default, - max_length=52, - unique=True, - ), - ), - ] diff --git a/arkindex/ponos/migrations/0039_keep_task_gpu.py b/arkindex/ponos/migrations/0039_keep_task_gpu.py deleted file mode 100644 index 9e32b31ec8583cd7de6271fca54114570279280d..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0039_keep_task_gpu.py +++ /dev/null @@ -1,34 +0,0 @@ -# Generated by Django 4.1.7 on 2023-04-20 08:06 - -from django.db import migrations, models - -from arkindex.ponos.models import ACTIVE_STATES - - -class Migration(migrations.Migration): - - dependencies = [ - ('ponos', '0038_task_token_unique'), - ] - - operations = [ - migrations.AlterField( - model_name='task', - name='gpu', - field=models.ForeignKey( - blank=True, - null=True, - on_delete=models.SET_NULL, - related_name='tasks', - to='ponos.gpu', - ), - ), - migrations.AddConstraint( - model_name='task', - constraint=models.UniqueConstraint( - 'gpu', - condition=models.Q(state__in=ACTIVE_STATES), - name='unique_gpu_on_active_tasks', - ), - ), - ] diff --git a/arkindex/ponos/migrations/0040_remove_workflow_recipe.py b/arkindex/ponos/migrations/0040_remove_workflow_recipe.py deleted file mode 100644 index 12a62ed997fde3af910006a169aaaa4afff21bfb..0000000000000000000000000000000000000000 --- a/arkindex/ponos/migrations/0040_remove_workflow_recipe.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 4.1.7 on 2023-04-28 13:07 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('ponos', '0039_keep_task_gpu'), - ] - - operations = [ - migrations.RemoveField( - model_name='workflow', - name='recipe', - ), - ] diff --git a/arkindex/process/migrations/0001_initial.py b/arkindex/process/migrations/0001_initial.py index 058bda1a3cc5da7e1ea2c562bb667c2997e5bbd3..43fbdce9a47026fd4593729ce0504bf8f46c564e 100644 --- a/arkindex/process/migrations/0001_initial.py +++ b/arkindex/process/migrations/0001_initial.py @@ -1,36 +1,42 @@ -# Generated by Django 2.2.9 on 2020-01-17 15:39 +# Generated by Django 4.1.7 on 2023-05-29 11:49 import uuid -import django.contrib.postgres.fields.jsonb +import django.core.validators +import django.db.models.deletion import enumfields.fields from django.db import migrations, models -from enumfields import Enum import arkindex.process.models import arkindex.project.aws import arkindex.project.fields -class EventType(Enum): - Addition = 'A' - Edit = 'M' - Deletion = 'D' - class Migration(migrations.Migration): initial = True + dependencies = [ + ('ponos', '0001_initial'), + ('documents', '0001_initial'), + ] + operations = [ + migrations.CreateModel( + name='CorpusWorkerVersion', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ], + ), migrations.CreateModel( name='DataFile', fields=[ - ('hash', arkindex.project.fields.MD5HashField(max_length=32)), - ('status', enumfields.fields.EnumField(default='unchecked', enum=arkindex.project.aws.S3FileStatus, max_length=50)), ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('name', models.CharField(max_length=100)), + ('name', models.CharField(max_length=255)), ('size', models.PositiveIntegerField(help_text='file size in bytes')), - ('content_type', models.CharField(max_length=50)), + ('content_type', models.CharField(max_length=120)), + ('status', enumfields.fields.EnumField(default='unchecked', enum=arkindex.project.aws.S3FileStatus, max_length=50)), + ('trashed', models.BooleanField(default=False)), ], options={ 'ordering': ['corpus', 'name'], @@ -38,29 +44,40 @@ class Migration(migrations.Migration): bases=(arkindex.project.aws.S3FileMixin, models.Model), ), migrations.CreateModel( - name='DataImport', + name='GitRef', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('type', enumfields.fields.EnumField(enum=arkindex.process.models.GitRefType, max_length=10)), + ('name', models.CharField(max_length=250)), + ], + ), + migrations.CreateModel( + name='Process', fields=[ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), ('created', models.DateTimeField(auto_now_add=True)), ('updated', models.DateTimeField(auto_now=True)), + ('name', models.CharField(blank=True, max_length=100, null=True)), ('mode', enumfields.fields.EnumField(enum=arkindex.process.models.ProcessMode, max_length=30)), - ('payload', django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True)), + ('activity_state', enumfields.fields.EnumField(default='disabled', enum=arkindex.process.models.ActivityState, max_length=32)), + ('name_contains', models.CharField(blank=True, max_length=250, null=True)), + ('load_children', models.BooleanField(default=False)), + ('collection_id', models.PositiveIntegerField(blank=True, null=True)), + ('use_cache', models.BooleanField(default=False)), + ('use_gpu', models.BooleanField(blank=True, default=False)), + ('bucket_name', models.CharField(blank=True, max_length=63, null=True, validators=[django.core.validators.MinLengthValidator(3)])), + ('prefix', models.CharField(blank=True, max_length=1024, null=True)), ], options={ + 'verbose_name_plural': 'processes', 'ordering': ['corpus', '-created'], }, ), migrations.CreateModel( - name='Event', + name='ProcessElement', fields=[ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('type', enumfields.fields.EnumField(enum=EventType, max_length=10)), ], - options={ - 'ordering': ['element_id', '-created'], - }, ), migrations.CreateModel( name='Repository', @@ -68,7 +85,6 @@ class Migration(migrations.Migration): ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), ('url', models.URLField(unique=True)), ('hook_token', models.CharField(max_length=250, unique=True)), - ('provider_name', models.CharField(choices=[('GitLabProvider', 'GitLab')], max_length=50)), ], options={ 'verbose_name_plural': 'repositories', @@ -81,9 +97,76 @@ class Migration(migrations.Migration): ('updated', models.DateTimeField(auto_now=True)), ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), ('hash', models.CharField(max_length=50)), - ('ref', models.CharField(max_length=50)), ('message', models.TextField()), ('author', models.CharField(max_length=50)), ], ), + migrations.CreateModel( + name='Worker', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100)), + ('slug', models.CharField(max_length=100)), + ('public', models.BooleanField(default=False)), + ], + ), + migrations.CreateModel( + name='WorkerActivity', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now_add=True)), + ('started', models.DateTimeField(blank=True, null=True)), + ('state', enumfields.fields.EnumField(default='queued', enum=arkindex.process.models.WorkerActivityState, max_length=10)), + ], + ), + migrations.CreateModel( + name='WorkerConfiguration', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('name', models.CharField(max_length=250)), + ('configuration', models.JSONField(default=dict)), + ('configuration_hash', arkindex.project.fields.MD5HashField(max_length=32)), + ('archived', models.BooleanField(default=False)), + ], + ), + migrations.CreateModel( + name='WorkerType', + fields=[ + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('slug', models.SlugField(max_length=100, unique=True)), + ('display_name', models.CharField(max_length=100)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='WorkerVersion', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('configuration', models.JSONField()), + ('state', enumfields.fields.EnumField(default='created', enum=arkindex.process.models.WorkerVersionState, max_length=10)), + ('gpu_usage', enumfields.fields.EnumField(blank=True, default='disabled', enum=arkindex.process.models.WorkerVersionGPUUsage, max_length=10)), + ('model_usage', models.BooleanField(default=False)), + ('docker_image_iid', models.CharField(blank=True, max_length=80, null=True)), + ('corpora', models.ManyToManyField(related_name='worker_versions', through='process.CorpusWorkerVersion', to='documents.corpus')), + ('docker_image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='ponos.artifact')), + ('revision', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='versions', to='process.revision')), + ('worker', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='versions', to='process.worker')), + ], + ), + migrations.CreateModel( + name='WorkerRun', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('parents', arkindex.project.fields.ArrayField(base_field=models.UUIDField(), size=None)), + ('summary', models.TextField()), + ('configuration', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='worker_runs', to='process.workerconfiguration')), + ], + ), ] diff --git a/arkindex/process/migrations/0002_initial.py b/arkindex/process/migrations/0002_initial.py index b332e6ed4c1cbd09f25d4b93e446e93a244aa3f2..24acaea602cbdd6f5bc31bf445a6d5995010863d 100644 --- a/arkindex/process/migrations/0002_initial.py +++ b/arkindex/process/migrations/0002_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 2.2.9 on 2020-01-17 15:39 +# Generated by Django 4.1.7 on 2023-05-29 11:49 import django.db.models.deletion from django.db import migrations, models @@ -9,36 +9,65 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('documents', '0001_initial'), + ('training', '0001_initial'), ('process', '0001_initial'), + ('documents', '0002_initial'), ] operations = [ migrations.AddField( - model_name='revision', - name='elements', - field=models.ManyToManyField( - related_name='revisions', - through='process.Event', - to='documents.Element', - ), + model_name='workerrun', + name='model_version', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='worker_runs', to='training.modelversion'), + ), + migrations.AddField( + model_name='workerrun', + name='process', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='worker_runs', to='process.process'), + ), + migrations.AddField( + model_name='workerrun', + name='version', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='worker_runs', to='process.workerversion'), + ), + migrations.AddField( + model_name='workerconfiguration', + name='worker', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='configurations', to='process.worker'), + ), + migrations.AddField( + model_name='workeractivity', + name='configuration', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='worker_activities', to='process.workerconfiguration'), + ), + migrations.AddField( + model_name='workeractivity', + name='element', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='activities', to='documents.element'), + ), + migrations.AddField( + model_name='workeractivity', + name='process', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='activities', to='process.process'), + ), + migrations.AddField( + model_name='workeractivity', + name='worker_version', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='activities', to='process.workerversion'), + ), + migrations.AddField( + model_name='worker', + name='repository', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='workers', to='process.repository'), + ), + migrations.AddField( + model_name='worker', + name='type', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='type', to='process.workertype'), ), migrations.AddField( model_name='revision', name='repo', - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='revisions', - to='process.Repository', - ), - ), - migrations.AddField( - model_name='repository', - name='corpus', - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='repos', - to='documents.Corpus', - ), + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='revisions', to='process.repository'), ), ] diff --git a/arkindex/process/migrations/0003_initial.py b/arkindex/process/migrations/0003_initial.py index 16fbfe3480a8db4696975373dd7066192de90311..18b9f8989b6de308a75c9707c92d41f50ba6585b 100644 --- a/arkindex/process/migrations/0003_initial.py +++ b/arkindex/process/migrations/0003_initial.py @@ -1,120 +1,218 @@ -# Generated by Django 2.2.9 on 2020-01-17 15:39 +# Generated by Django 4.1.7 on 2023-05-29 11:49 import django.db.models.deletion from django.conf import settings from django.db import migrations, models +import arkindex.process.models +import pgtrigger.compiler +import pgtrigger.migrations + class Migration(migrations.Migration): initial = True dependencies = [ + ('training', '0001_initial'), + ('ponos', '0001_initial'), + ('users', '0001_initial'), ('process', '0002_initial'), + ('documents', '0003_initial'), migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('documents', '0002_initial'), - ('ponos', '0012_advanced_tags'), - ('users', '0001_initial'), ] operations = [ migrations.AddField( model_name='repository', name='credentials', - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name='repos', - to='users.OAuthCredentials', - ), + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='repos', to='users.oauthcredentials'), + ), + migrations.AddField( + model_name='repository', + name='git_ref_revisions', + field=models.ManyToManyField(through='process.GitRef', to='process.revision'), ), migrations.AddField( - model_name='event', + model_name='processelement', name='element', - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='events', - to='documents.Element', - ), + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='process_elements', to='documents.element'), ), migrations.AddField( - model_name='event', - name='revision', - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name='events', - to='process.Revision', - ), + model_name='processelement', + name='process', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='process_elements', to='process.process'), ), migrations.AddField( - model_name='dataimport', + model_name='process', name='corpus', - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='imports', - to='documents.Corpus', - ), + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='processes', to='documents.corpus'), ), migrations.AddField( - model_name='dataimport', + model_name='process', name='creator', - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='imports', - to=settings.AUTH_USER_MODEL, - ), + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='processes', to=settings.AUTH_USER_MODEL), ), migrations.AddField( - model_name='dataimport', + model_name='process', + name='element', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='documents.element'), + ), + migrations.AddField( + model_name='process', + name='element_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='element_imports', to='documents.elementtype'), + ), + migrations.AddField( + model_name='process', + name='elements', + field=models.ManyToManyField(related_name='processes', through='process.ProcessElement', to='documents.element'), + ), + migrations.AddField( + model_name='process', name='files', - field=models.ManyToManyField( - related_name='imports', - to='process.DataFile', - ), + field=models.ManyToManyField(related_name='processes', to='process.datafile'), ), migrations.AddField( - model_name='dataimport', + model_name='process', + name='folder_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='folder_imports', to='documents.elementtype'), + ), + migrations.AddField( + model_name='process', + name='model', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='training_processes', to='training.model'), + ), + migrations.AddField( + model_name='process', name='revision', - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name='dataimports', - to='process.Revision', - ), + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='processes', to='process.revision'), + ), + migrations.AddField( + model_name='process', + name='template', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='applications', to='process.process'), + ), + migrations.AddField( + model_name='process', + name='test_folder', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='test_folder_processes', to='documents.element'), ), migrations.AddField( - model_name='dataimport', + model_name='process', + name='train_folder', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='train_folder_processes', to='documents.element'), + ), + migrations.AddField( + model_name='process', + name='validation_folder', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='validation_folder_processes', to='documents.element'), + ), + migrations.AddField( + model_name='process', + name='versions', + field=models.ManyToManyField(related_name='processes', through='process.WorkerRun', to='process.workerversion'), + ), + migrations.AddField( + model_name='process', name='workflow', - field=models.OneToOneField( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - to='ponos.Workflow', - ), + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='ponos.workflow'), + ), + migrations.AddField( + model_name='gitref', + name='repository', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='refs', to='process.repository'), + ), + migrations.AddField( + model_name='gitref', + name='revision', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='refs', to='process.revision'), ), migrations.AddField( model_name='datafile', name='corpus', - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='files', - to='documents.Corpus', - ), + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='files', to='documents.corpus'), + ), + migrations.AddField( + model_name='corpusworkerversion', + name='corpus', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='worker_version_cache', to='documents.corpus'), + ), + migrations.AddField( + model_name='corpusworkerversion', + name='worker_version', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='corpus_cache', to='process.workerversion'), + ), + migrations.AddConstraint( + model_name='workerversion', + constraint=models.CheckConstraint(check=models.Q(('docker_image_id', None), ('state', arkindex.process.models.WorkerVersionState['Available']), _negated=True), name='workerversion_available_requires_docker_image'), + ), + migrations.AlterUniqueTogether( + name='workerversion', + unique_together={('worker', 'revision')}, + ), + migrations.AlterUniqueTogether( + name='workerrun', + unique_together={('version', 'process')}, + ), + migrations.AddConstraint( + model_name='workerconfiguration', + constraint=models.CheckConstraint(check=models.Q(('configuration__typeof', 'object')), name='worker_configuration_configuration_objects'), + ), + migrations.AlterUniqueTogether( + name='workerconfiguration', + unique_together={('worker', 'name'), ('worker', 'configuration_hash')}, + ), + migrations.AddConstraint( + model_name='workeractivity', + constraint=models.UniqueConstraint(condition=models.Q(('configuration__isnull', True)), fields=('worker_version', 'element'), name='worker_activity_unique_no_configuration'), + ), + migrations.AddConstraint( + model_name='workeractivity', + constraint=models.UniqueConstraint(condition=models.Q(('configuration__isnull', False)), fields=('worker_version', 'element', 'configuration'), name='worker_activity_unique_configuration'), + ), + migrations.AddConstraint( + model_name='workeractivity', + constraint=models.CheckConstraint(check=models.Q(models.Q(('state', arkindex.process.models.WorkerActivityState['Started']), _negated=True), ('started__isnull', False), _connector='OR'), name='worker_activity_started_requires_started'), + ), + migrations.AlterUniqueTogether( + name='worker', + unique_together={('slug', 'repository')}, ), migrations.AlterUniqueTogether( name='revision', unique_together={('repo', 'hash')}, ), migrations.AlterUniqueTogether( - name='event', - unique_together={('element', 'revision')}, + name='processelement', + unique_together={('process', 'element')}, + ), + migrations.AddConstraint( + model_name='process', + constraint=models.CheckConstraint(check=models.Q(models.Q(('mode', arkindex.process.models.ProcessMode['Local']), _negated=True), ('workflow', None), _connector='OR'), name='local_process_no_workflow', violation_error_message='Local processes cannot be started.'), + ), + migrations.AddConstraint( + model_name='process', + constraint=models.CheckConstraint(check=models.Q(('mode__in', (arkindex.process.models.ProcessMode['Local'], arkindex.process.models.ProcessMode['Repository'])), models.Q(('corpus', None), _negated=True), _connector='XOR'), name='check_process_corpus', violation_error_message='Local and repository processes cannot have a corpus, and other modes must have one set.'), + ), + migrations.AddConstraint( + model_name='process', + constraint=models.UniqueConstraint(models.F('creator'), condition=models.Q(('mode', arkindex.process.models.ProcessMode['Local'])), name='unique_local_process', violation_error_message='Only one local process is allowed per user.'), ), migrations.AlterUniqueTogether( - name='datafile', - unique_together={('corpus', 'hash')}, + name='gitref', + unique_together={('name', 'repository')}, + ), + migrations.AlterUniqueTogether( + name='corpusworkerversion', + unique_together={('corpus', 'worker_version')}, + ), + pgtrigger.migrations.AddTrigger( + model_name='workeractivity', + trigger=pgtrigger.compiler.Trigger(name='update_workeractivity_updated', sql=pgtrigger.compiler.UpsertTriggerSql(func='NEW.updated = now(); RETURN NEW;', hash='1e5a8fa0718f420e6cd4f2a31434cd39a9c9bc67', operation='UPDATE', pgid='pgtrigger_update_workeractivity_updated_f2812', table='process_workeractivity', when='BEFORE')), + ), + pgtrigger.migrations.AddTrigger( + model_name='workeractivity', + trigger=pgtrigger.compiler.Trigger(name='read_only_workeractivity_updated', sql=pgtrigger.compiler.UpsertTriggerSql(condition='WHEN (OLD."updated" IS DISTINCT FROM (NEW."updated"))', func="RAISE EXCEPTION 'pgtrigger: Cannot update rows from % table', TG_TABLE_NAME;", hash='6276c6971a1d2669659e407418e2db1fa7dc6965', operation='UPDATE', pgid='pgtrigger_read_only_workeractivity_updated_a80ab', table='process_workeractivity', when='BEFORE')), ), ] diff --git a/arkindex/process/migrations/0004_remove_event.py b/arkindex/process/migrations/0004_remove_event.py deleted file mode 100644 index 913ddf1ad967c66c1b04a861b3200570c35285e0..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0004_remove_event.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 2.2.11 on 2020-04-09 12:10 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0003_initial'), - ] - - operations = [ - migrations.RemoveField( - model_name='revision', - name='elements', - ), - migrations.DeleteModel( - name='Event', - ), - ] diff --git a/arkindex/process/migrations/0005_filename_max_length.py b/arkindex/process/migrations/0005_filename_max_length.py deleted file mode 100644 index 837054dd10ab89565a3fb21dae16f8dd5a0c396a..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0005_filename_max_length.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 2.2.10 on 2020-04-21 09:04 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0004_remove_event'), - ] - - operations = [ - migrations.AlterField( - model_name='datafile', - name='name', - field=models.CharField(max_length=255), - ), - ] diff --git a/arkindex/process/migrations/0006_revision_state.py b/arkindex/process/migrations/0006_revision_state.py deleted file mode 100644 index 4db90b40e4c4009427de52de751e01b6dae0d69f..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0006_revision_state.py +++ /dev/null @@ -1,30 +0,0 @@ -# Generated by Django 2.2.11 on 2020-04-30 11:00 - -import enumfields.fields -from django.db import migrations - - -class RevisionState(enumfields.fields.Enum): - Created = 'created' - Processing = 'processing' - Available = 'available' - Error = 'error' - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0005_filename_max_length'), - ] - - operations = [ - migrations.AddField( - model_name='revision', - name='state', - field=enumfields.fields.EnumField( - default='created', - enum=RevisionState, - max_length=10 - ), - ), - ] diff --git a/arkindex/process/migrations/0007_worker_workerversion.py b/arkindex/process/migrations/0007_worker_workerversion.py deleted file mode 100644 index 98179e9e1a05facb76d6e8805fd26c12025016ce..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0007_worker_workerversion.py +++ /dev/null @@ -1,48 +0,0 @@ -# Generated by Django 2.2.11 on 2020-05-19 14:55 - -import uuid -from enum import Enum - -import django.contrib.postgres.fields.jsonb -import django.db.models.deletion -import enumfields.fields -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0006_revision_state'), - ] - - operations = [ - migrations.CreateModel( - name='Worker', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('name', models.CharField(max_length=100)), - ('slug', models.CharField(max_length=100)), - ('type', enumfields.fields.EnumField(enum=Enum('MLToolType', ''), max_length=50)), - ('repository', models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='workers', - to='process.Repository' - )), - ], - options={ - 'unique_together': {('slug', 'repository')}, - }, - ), - migrations.CreateModel( - name='WorkerVersion', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('configuration', django.contrib.postgres.fields.jsonb.JSONField()), - ('revision', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='process.Revision')), - ('worker', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='process.Worker')), - ], - options={ - 'unique_together': {('worker', 'revision')}, - }, - ), - ] diff --git a/arkindex/process/migrations/0008_add_gitref.py b/arkindex/process/migrations/0008_add_gitref.py deleted file mode 100644 index 80344263d176f92ab5c80ff286eb559731b424a9..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0008_add_gitref.py +++ /dev/null @@ -1,78 +0,0 @@ -# Generated by Django 2.2.11 on 2020-05-21 15:34 - -import uuid - -import django.db.models.deletion -import enumfields.fields -from django.db import migrations, models - -import arkindex.process.models - - -def migrate_git_refs(apps, schema_editor): - """ - Used to convert values on the ref attribute from Revision to a GitRef object. - The ref attribute on Revision only supported branch-type references, so no need to - worry about the type of the reference. - - Some references are duplicated on multiple revisions (e.g., two master branches), in - which case the GitRef object is linked to the latest version returned by the default - DB order. These values will be updated later when the GitLab webhook will be triggered. - """ - db_alias = schema_editor.connection.alias - Revision = apps.get_model('process', 'Revision') - for rev in Revision.objects.using(db_alias).filter(ref__isnull=False): - ref = rev.repo.refs.filter(name=rev.ref).first() - if ref: - ref.revision = rev - ref.save() - else: - rev.refs.create( - name=rev.ref, - type=arkindex.process.models.GitRefType('branch'), - repository=rev.repo - ) - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0007_worker_workerversion'), - ] - - operations = [ - migrations.CreateModel( - name='GitRef', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('type', enumfields.fields.EnumField(enum=arkindex.process.models.GitRefType, max_length=10)), - ('name', models.CharField(max_length=250)), - ('repository', models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='refs', - to='process.Repository' - )), - ('revision', models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='refs', - to='process.Revision' - )), - ], - options={ - 'unique_together': {('name', 'repository')}, - }, - ), - migrations.RunPython( - migrate_git_refs, - reverse_code=migrations.RunPython.noop, - ), - migrations.AddField( - model_name='repository', - name='git_ref_revisions', - field=models.ManyToManyField(through='process.GitRef', to='process.Revision'), - ), - migrations.RemoveField( - model_name='revision', - name='ref', - ), - ] diff --git a/arkindex/process/migrations/0009_remove_datafile_hash.py b/arkindex/process/migrations/0009_remove_datafile_hash.py deleted file mode 100644 index 27f06b83897ba2f17b8612aa895df543b251e6ad..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0009_remove_datafile_hash.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 2.2.13 on 2020-06-08 10:25 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0008_add_gitref'), - ] - - operations = [ - migrations.AlterUniqueTogether( - name='datafile', - unique_together=set(), - ), - migrations.RemoveField( - model_name='datafile', - name='hash', - ), - ] diff --git a/arkindex/process/migrations/0010_workerversion_docker_image.py b/arkindex/process/migrations/0010_workerversion_docker_image.py deleted file mode 100644 index 6c17f7b90cf185957ac11145eaf7527ed45cb57d..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0010_workerversion_docker_image.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 2.2.13 on 2020-06-18 12:52 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('ponos', '0015_task_has_docker_socket'), - ('process', '0009_remove_datafile_hash'), - ] - - operations = [ - migrations.AddField( - model_name='workerversion', - name='docker_image', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='ponos.Artifact'), - ), - ] diff --git a/arkindex/process/migrations/0011_refactor_payload_dataimport.py b/arkindex/process/migrations/0011_refactor_payload_dataimport.py deleted file mode 100644 index 997a9075d5ed6e3a422b540f4a019c0032a26603..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0011_refactor_payload_dataimport.py +++ /dev/null @@ -1,101 +0,0 @@ -# Generated by Django 2.2.13 on 2020-06-24 09:39 - -import django.db.models.deletion -from django.db import migrations, models -from enumfields import Enum - - -class OldDataImportMode(Enum): - Elements = 'elements' - - -def populate_new_fields(apps, schema_editor): - """ - Migrate all elements selection fields from a DataImport.payload towards new DB fields on this model - so they can be edited later on. - It also means that a DataImport can now be configured without being started immediately. - """ - db_alias = schema_editor.connection.alias - DataImport = apps.get_model('process', 'DataImport') - ElementType = apps.get_model('documents', 'ElementType') - Element = apps.get_model('documents', 'Element') - - # Switch to Enum to restore the removed Elements import mode to allow filtering on it - DataImport.mode.field.enum = OldDataImportMode - - for di in DataImport.objects.using(db_alias).filter(mode=OldDataImportMode.Elements): - # There, we retrieve the payload elements that interest us to populate the new fields. We also remove the - # attributes "ml_tools", "thumbnails" and "chunks" from the payload because they will no longer be useful. - element, name_contains, elt_type, selection, best_class, _, _, _ = map( - lambda key: di.payload.pop(key, None), - ( - 'element', - 'name_contains', - 'element_type', - 'elements', - 'best_class', - 'ml_tools', - 'thumbnails', - 'chunks' - ) - ) - - if name_contains: - di.name_contains = name_contains - if elt_type: - try: - di.element_type = ElementType.objects.using(db_alias).get(corpus=di.corpus, slug=elt_type) - except ElementType.DoesNotExist: - pass - if element: - try: - di.element = Element.objects.using(db_alias).get(id=element) - except Element.DoesNotExist: - pass - if selection: - di.use_selection = True - if best_class: - di.best_class = best_class - - # At the end of the migration, we will find, in the payload, only elements that are not related to an Elements DataImport. - di.save() - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0015_elementtype_allowed_transcription'), - ('process', '0010_workerversion_docker_image'), - ] - - operations = [ - migrations.AddField( - model_name='dataimport', - name='best_class', - field=models.CharField(blank=True, max_length=150, null=True), - ), - migrations.AddField( - model_name='dataimport', - name='element', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='documents.Element'), - ), - migrations.AddField( - model_name='dataimport', - name='element_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='documents.ElementType'), - ), - migrations.AddField( - model_name='dataimport', - name='name_contains', - field=models.CharField(blank=True, max_length=150, null=True), - ), - migrations.AddField( - model_name='dataimport', - name='use_selection', - field=models.BooleanField(default=False), - ), - migrations.RunPython( - populate_new_fields, - reverse_code=migrations.RunPython.noop, - ), - ] diff --git a/arkindex/process/migrations/0012_move_revision_state.py b/arkindex/process/migrations/0012_move_revision_state.py deleted file mode 100644 index 2962c17b1ff17fd6a5c59b0b2fb44a03aa68ad6c..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0012_move_revision_state.py +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by Django 2.2.13 on 2020-06-25 09:40 - -import django.db.models.deletion -import enumfields.fields -from django.db import migrations, models - -import arkindex.process.models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0011_refactor_payload_dataimport'), - ] - - operations = [ - migrations.RemoveField( - model_name='revision', - name='state', - ), - migrations.AddField( - model_name='workerversion', - name='state', - field=enumfields.fields.EnumField(default='created', enum=arkindex.process.models.WorkerVersionState, max_length=10), - ), - migrations.AlterField( - model_name='workerversion', - name='revision', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='versions', to='process.Revision'), - ), - ] diff --git a/arkindex/process/migrations/0013_create_model_workerrun.py b/arkindex/process/migrations/0013_create_model_workerrun.py deleted file mode 100644 index 696e558ad8bafa9c9fd4a3ce01b140bcc3013578..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0013_create_model_workerrun.py +++ /dev/null @@ -1,35 +0,0 @@ -# Generated by Django 2.2.13 on 2020-06-29 13:18 - -import uuid - -import django.db.models.deletion -from django.db import migrations, models - -import arkindex.project.fields - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0012_move_revision_state'), - ] - - operations = [ - migrations.CreateModel( - name='WorkerRun', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('parents', arkindex.project.fields.ArrayField(base_field=models.UUIDField(), size=None)), - ('dataimport', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='worker_runs', to='process.DataImport')), - ('version', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='worker_runs', to='process.WorkerVersion')), - ], - options={ - 'unique_together': {('version', 'dataimport')}, - }, - ), - migrations.AddField( - model_name='dataimport', - name='versions', - field=models.ManyToManyField(related_name='imports', through='process.WorkerRun', to='process.WorkerVersion'), - ), - ] diff --git a/arkindex/process/migrations/0014_dataimport_selection.py b/arkindex/process/migrations/0014_dataimport_selection.py deleted file mode 100644 index 924758a4d41704ca4bbf78323bbc4785dee94c2e..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0014_dataimport_selection.py +++ /dev/null @@ -1,54 +0,0 @@ -# Generated by Django 2.2.13 on 2020-07-03 13:16 - -import uuid - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0017_remove_elementtype_default_view'), - ('process', '0013_create_model_workerrun'), - ] - - operations = [ - migrations.CreateModel( - name='DataImportElement', - fields=[ - ('id', models.UUIDField( - default=uuid.uuid4, - editable=False, - primary_key=True, - serialize=False, - )), - ('dataimport', models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='dataimport_elements', - to='process.DataImport', - )), - ('element', models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='dataimport_elements', - to='documents.Element', - )), - ], - options={ - 'unique_together': {('dataimport', 'element')}, - }, - ), - migrations.AddField( - model_name='dataimport', - name='elements', - field=models.ManyToManyField( - related_name='imports', - through='process.DataImportElement', - to='documents.Element', - ), - ), - migrations.RemoveField( - model_name='dataimport', - name='use_selection', - ), - ] diff --git a/arkindex/process/migrations/0015_clear_payload.py b/arkindex/process/migrations/0015_clear_payload.py deleted file mode 100644 index 960b69bf385def557c40942ebf2c781046555f67..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0015_clear_payload.py +++ /dev/null @@ -1,98 +0,0 @@ -# Generated by Django 2.2.13 on 2020-07-07 13:49 - -import django.db.models.deletion -from django.db import migrations, models - -# Converts DataImport payloads to fields, from all the keys found in existing payloads: -# element_type → process.element_type -# elt_type → process.element_type -# folder_type → process.folder_type -# element_id → process.element -# folder_id → process.element -# Many of those were not actually carried over by process.0011. -# Ignored: corpus_id, ml_tools, pdf_engine, sha, repo_id - -PAYLOAD_TO_FIELDS = """ -UPDATE process_dataimport di - SET element_type_id = type.id - FROM documents_elementtype type - WHERE - di.payload IS NOT NULL - AND di.element_type_id IS NULL - AND type.corpus_id = di.corpus_id - AND type.slug = di.payload->>'element_type'; - -UPDATE process_dataimport di - SET element_type_id = type.id - FROM documents_elementtype type - WHERE - di.payload IS NOT NULL - AND di.element_type_id IS NULL - AND type.corpus_id = di.corpus_id - AND type.slug = di.payload->>'elt_type'; - -UPDATE process_dataimport di - SET folder_type_id = type.id - FROM documents_elementtype type - WHERE - di.payload IS NOT NULL - AND type.corpus_id = di.corpus_id - AND type.slug = di.payload->>'folder_type'; - -UPDATE process_dataimport di - SET element_id = element.id - FROM documents_element element - WHERE - di.payload IS NOT NULL - AND di.element_id IS NULL - AND element.corpus_id = di.corpus_id - AND element.id = (di.payload->>'element_id')::uuid; - -UPDATE process_dataimport di - SET element_id = element.id - FROM documents_element element - WHERE - di.payload IS NOT NULL - AND di.element_id IS NULL - AND element.corpus_id = di.corpus_id - AND element.id = (di.payload->>'folder_id')::uuid; -""" - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0017_remove_elementtype_default_view'), - ('process', '0014_dataimport_selection'), - ] - atomic = False - - operations = [ - migrations.AddField( - model_name='dataimport', - name='folder_type', - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name='folder_imports', - to='documents.ElementType', - ), - ), - migrations.AlterField( - model_name='dataimport', - name='element_type', - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name='element_imports', - to='documents.ElementType', - ), - ), - migrations.RunSQL(PAYLOAD_TO_FIELDS), - migrations.RemoveField( - model_name='dataimport', - name='payload', - ), - ] diff --git a/arkindex/process/migrations/0016_new_jsonfield.py b/arkindex/process/migrations/0016_new_jsonfield.py deleted file mode 100644 index 04e20974fb0ef8a4c54583411c33f83023657b0e..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0016_new_jsonfield.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.1 on 2020-08-10 14:47 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0015_clear_payload'), - ] - - operations = [ - migrations.AlterField( - model_name='workerversion', - name='configuration', - field=models.JSONField(), - ), - ] diff --git a/arkindex/process/migrations/0017_dataimport_collection_id.py b/arkindex/process/migrations/0017_dataimport_collection_id.py deleted file mode 100644 index 50b8514276734e2d5e72cc5d97cf00de20af35e3..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0017_dataimport_collection_id.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 2.2.13 on 2020-08-03 13:52 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0016_new_jsonfield'), - ] - - operations = [ - migrations.AddField( - model_name='dataimport', - name='collection_id', - field=models.PositiveIntegerField(blank=True, null=True), - ), - ] diff --git a/arkindex/process/migrations/0018_dataimport_build_entities.py b/arkindex/process/migrations/0018_dataimport_build_entities.py deleted file mode 100644 index 3d19d58f2e1646621b5bc73a4a27581663a5ea8b..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0018_dataimport_build_entities.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.1 on 2020-09-02 13:10 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0017_dataimport_collection_id'), - ] - - operations = [ - migrations.AddField( - model_name='dataimport', - name='build_entities', - field=models.BooleanField(default=False), - ), - ] diff --git a/arkindex/process/migrations/0019_repository_type.py b/arkindex/process/migrations/0019_repository_type.py deleted file mode 100644 index 571876d5614f45af68975ce77c7740a4a9c591ef..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0019_repository_type.py +++ /dev/null @@ -1,36 +0,0 @@ -# Generated by Django 3.1 on 2020-09-09 15:26 - -from django.db import migrations, models - -WORKER_REPO_PREFIX = 'https://gitlab.com/teklia/workers/' - - -def update_repository_types(apps, schema_editor): - Repository = apps.get_model('process', 'Repository') - # Defaults the repository to 'worker' type except if defined below - Repository.objects \ - .filter(url__startswith=WORKER_REPO_PREFIX) \ - .update(type="iiif") - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0018_dataimport_build_entities'), - ] - - operations = [ - migrations.AddField( - model_name='repository', - name='type', - field=models.CharField( - default="iiif", - max_length=10), - preserve_default=False, - ), - migrations.RunPython( - update_repository_types, - reverse_code=migrations.RunPython.noop, - elidable=True - ) - ] diff --git a/arkindex/process/migrations/0020_null_corpus_repo_dataimport.py b/arkindex/process/migrations/0020_null_corpus_repo_dataimport.py deleted file mode 100644 index f5f70e31f879c3dac8ad8e3075465711f6f8d24f..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0020_null_corpus_repo_dataimport.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 3.1.1 on 2020-09-11 14:19 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0019_corpus_repository'), - ('process', '0019_repository_type'), - ] - - operations = [ - migrations.AlterField( - model_name='dataimport', - name='corpus', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='imports', to='documents.corpus'), - ), - migrations.RemoveField( - model_name='repository', - name='corpus', - ), - ] diff --git a/arkindex/process/migrations/0021_workerversion_docker_image_iid.py b/arkindex/process/migrations/0021_workerversion_docker_image_iid.py deleted file mode 100644 index dd046817448b07c361bfec97bf7014dab2404872..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0021_workerversion_docker_image_iid.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 3.1.1 on 2020-09-22 09:09 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0020_null_corpus_repo_dataimport'), - ] - - operations = [ - migrations.AddField( - model_name='workerversion', - name='docker_image_iid', - field=models.CharField(blank=True, max_length=80, null=True), - ), - migrations.AlterField( - model_name='workerversion', - name='docker_image', - field=models.ForeignKey(blank=True, null=True, on_delete=models.deletion.SET_NULL, to='ponos.artifact'), - ), - ] diff --git a/arkindex/process/migrations/0022_dataimport_load_children.py b/arkindex/process/migrations/0022_dataimport_load_children.py deleted file mode 100644 index 56eaeaf613f61676e3cb05e536ce5066b09bff6a..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0022_dataimport_load_children.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.1.1 on 2020-09-21 07:31 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0021_workerversion_docker_image_iid'), - ] - - operations = [ - migrations.AddField( - model_name='dataimport', - name='load_children', - field=models.BooleanField(default=False), - ), - ] diff --git a/arkindex/process/migrations/0023_workerversion_constraint.py b/arkindex/process/migrations/0023_workerversion_constraint.py deleted file mode 100644 index b452fa1868de4f89dbd7940f244171a06d9ea1fe..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0023_workerversion_constraint.py +++ /dev/null @@ -1,34 +0,0 @@ -# Generated by Django 3.1.1 on 2020-09-24 10:57 - -from django.db import migrations, models - -from arkindex.process.models import WorkerVersionState - - -def update_invalid_workerversions(apps, schema_editor): - WorkerVersion = apps.get_model('process', 'WorkerVersion') - WorkerVersion.objects \ - .filter(state=WorkerVersionState.Available, docker_image__isnull=True) \ - .update(state=WorkerVersionState.Error) - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0022_dataimport_load_children'), - ] - - operations = [ - migrations.RunPython( - update_invalid_workerversions, - reverse_code=migrations.RunPython.noop, - elidable=True, - ), - migrations.AddConstraint( - model_name='workerversion', - constraint=models.CheckConstraint( - check=~models.Q(state=WorkerVersionState.Available, docker_image_id=None), - name='workerversion_available_requires_docker_image' - ), - ), - ] diff --git a/arkindex/process/migrations/0024_alter_worker_type.py b/arkindex/process/migrations/0024_alter_worker_type.py deleted file mode 100644 index 10b55b816d7eb1becdc22338860aba6cead7868e..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0024_alter_worker_type.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.1.4 on 2020-12-04 08:57 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0023_workerversion_constraint'), - ] - - operations = [ - migrations.AlterField( - model_name='worker', - name='type', - field=models.CharField(max_length=50), - ), - ] diff --git a/arkindex/process/migrations/0025_dataimport_name.py b/arkindex/process/migrations/0025_dataimport_name.py deleted file mode 100644 index 35f91a2c9aff72dd609dc5fc88aa9ec6bccbf3af..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0025_dataimport_name.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.1.3 on 2020-12-04 09:11 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0024_alter_worker_type'), - ] - - operations = [ - migrations.AddField( - model_name='dataimport', - name='name', - field=models.CharField(blank=True, max_length=100, null=True), - ), - ] diff --git a/arkindex/process/migrations/0026_larger_content_type.py b/arkindex/process/migrations/0026_larger_content_type.py deleted file mode 100644 index a3611197883e14fdc3f878215c797a1ed83e8811..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0026_larger_content_type.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.1.3 on 2021-02-05 10:02 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0025_dataimport_name'), - ] - - operations = [ - migrations.AlterField( - model_name='datafile', - name='content_type', - field=models.CharField(max_length=120), - ), - ] diff --git a/arkindex/process/migrations/0027_workers_rights.py b/arkindex/process/migrations/0027_workers_rights.py deleted file mode 100644 index 25a52060bfc12c49da0b69333aaac959069608c1..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0027_workers_rights.py +++ /dev/null @@ -1,43 +0,0 @@ -import django.db.models.deletion -from django.contrib.contenttypes.models import ContentType -from django.db import migrations, models - - -def create_repository_admin(apps, schema_editor): - Right = apps.get_model('users', 'Right') - Repository = apps.get_model('process', 'Repository') - # Define repositories admins from credentials used during the import - Right.objects.bulk_create([ - Right( - user_id=repo.credentials.user_id, - content_type_id=ContentType.objects.get_for_model(Repository).id, - content_id=repo.id, - level=100 - ) for repo in Repository.objects.exclude(credentials__isnull=True) - ]) - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0026_larger_content_type'), - ('users', '0011_corpus_rights'), - ] - - operations = [ - migrations.AddField( - model_name='worker', - name='public', - field=models.BooleanField(default=False), - ), - migrations.AlterField( - model_name='workerversion', - name='worker', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='versions', to='process.worker'), - ), - migrations.RunPython( - create_repository_admin, - reverse_code=migrations.RunPython.noop, - elidable=True - ) - ] diff --git a/arkindex/process/migrations/0028_dataimport_max_lengths.py b/arkindex/process/migrations/0028_dataimport_max_lengths.py deleted file mode 100644 index 6664e8c96513cbd384515849b84caa59948099cb..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0028_dataimport_max_lengths.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 3.1.6 on 2021-02-15 11:15 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0027_workers_rights'), - ] - - operations = [ - migrations.AlterField( - model_name='dataimport', - name='best_class', - field=models.CharField(blank=True, max_length=36, null=True), - ), - migrations.AlterField( - model_name='dataimport', - name='name_contains', - field=models.CharField(blank=True, max_length=250, null=True), - ), - ] diff --git a/arkindex/process/migrations/0029_worker_activity.py b/arkindex/process/migrations/0029_worker_activity.py deleted file mode 100644 index 30dd7888eae2ef6f00757526d3a9cb1753d4acab..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0029_worker_activity.py +++ /dev/null @@ -1,34 +0,0 @@ -# Generated by Django 3.1.5 on 2021-01-11 14:42 - -import uuid - -import django.db.models.deletion -import enumfields.fields -from django.db import migrations, models - -import arkindex.process.models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0026_metadata_worker_version'), - ('process', '0028_dataimport_max_lengths'), - ] - - operations = [ - migrations.CreateModel( - name='WorkerActivity', - fields=[ - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('state', enumfields.fields.EnumField(default='queued', enum=arkindex.process.models.WorkerActivityState, max_length=10)), - ('element', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='activities', to='documents.element')), - ('worker_version', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='activities', to='process.workerversion')), - ], - options={ - 'unique_together': {('worker_version', 'element')}, - }, - ), - ] diff --git a/arkindex/process/migrations/0030_remove_mode_elements.py b/arkindex/process/migrations/0030_remove_mode_elements.py deleted file mode 100644 index 9189c690e144daab97acd879924d74ce1490406e..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0030_remove_mode_elements.py +++ /dev/null @@ -1,34 +0,0 @@ -# Generated by Django 3.1.6 on 2021-02-24 10:38 - -from django.db import migrations -from enumfields import Enum - - -class OldDataImportMode(Enum): - Elements = 'elements' - - -def remove_mode_elements(apps, schema_editor): - DataImport = apps.get_model('process', 'DataImport') - DataImportElement = apps.get_model('process', 'DataImportElement') - - # Switch the enum to restore Elements, because the EnumField would otherwise not let us filter - DataImport.mode.field.enum = OldDataImportMode - - DataImportElement.objects.filter(dataimport__mode=OldDataImportMode.Elements).delete() - DataImport.objects.filter(mode=OldDataImportMode.Elements).delete() - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0029_worker_activity'), - ] - - operations = [ - migrations.RunPython( - remove_mode_elements, - reverse_code=migrations.RunPython.noop, - elidable=True, - ) - ] diff --git a/arkindex/process/migrations/0031_dataimport_use_cache.py b/arkindex/process/migrations/0031_dataimport_use_cache.py deleted file mode 100644 index 2dade8a420cbcb2590a7c13ed7a752f162a8042f..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0031_dataimport_use_cache.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.1.5 on 2021-03-30 08:49 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0030_remove_mode_elements'), - ] - - operations = [ - migrations.AddField( - model_name='dataimport', - name='use_cache', - field=models.BooleanField(default=False), - ), - ] diff --git a/arkindex/process/migrations/0032_dataimport_activity_state.py b/arkindex/process/migrations/0032_dataimport_activity_state.py deleted file mode 100644 index 3b7ddedea8c28efef3356a32f1a2deeae631e28c..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0032_dataimport_activity_state.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 3.1.5 on 2021-04-06 10:29 - -import enumfields.fields -from django.db import migrations - -import arkindex.process.models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0031_dataimport_use_cache'), - ] - - operations = [ - migrations.AddField( - model_name='dataimport', - name='activity_state', - field=enumfields.fields.EnumField(default='disabled', enum=arkindex.process.models.ActivityState, max_length=32), - ), - ] diff --git a/arkindex/process/migrations/0033_workeractivity_process.py b/arkindex/process/migrations/0033_workeractivity_process.py deleted file mode 100644 index 1719e987d54088cdf62e114b36ce31490b6b664b..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0033_workeractivity_process.py +++ /dev/null @@ -1,25 +0,0 @@ -# Generated by Django 3.1.5 on 2021-05-07 07:48 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0032_dataimport_activity_state'), - ] - - operations = [ - migrations.AddField( - model_name='workeractivity', - name='process', - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name='activities', - to='process.dataimport' - ), - ), - ] diff --git a/arkindex/process/migrations/0034_worker_run_config.py b/arkindex/process/migrations/0034_worker_run_config.py deleted file mode 100644 index 41cc0432e592545e1a2aa5aee7ca47e9b25a0a0f..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0034_worker_run_config.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 3.2.3 on 2021-07-09 13:01 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0033_workeractivity_process'), - ] - - operations = [ - migrations.AddField( - model_name='workerrun', - name='configuration', - field=models.JSONField(default=dict), - ), - migrations.AddConstraint( - model_name='workerrun', - constraint=models.CheckConstraint(check=models.Q(('configuration__typeof', 'object')), name='worker_run_configuration_objects'), - ), - ] diff --git a/arkindex/process/migrations/0035_corpus_version_cache.py b/arkindex/process/migrations/0035_corpus_version_cache.py deleted file mode 100644 index 931de414dfdbd3708e520301eb361d7bdcc8d64e..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0035_corpus_version_cache.py +++ /dev/null @@ -1,63 +0,0 @@ -# Generated by Django 3.2.3 on 2021-08-31 07:53 - -import uuid - -import django.db.models.deletion -from django.db import migrations, models - - -def rebuild_reminder(apps, schema_editor): - """ - Print a reminder to rebuild the cache manually if there is anything in the database. - """ - Corpus = apps.get_model('documents', 'Corpus') - if Corpus.objects.exists(): - print("Please run `arkindex cache_worker_versions` to fill the corpus worker versions cache.") - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0042_transcription_entity_confidence'), - ('process', '0034_worker_run_config'), - ] - - operations = [ - migrations.CreateModel( - name='CorpusWorkerVersion', - fields=[ - ('id', models.UUIDField( - default=uuid.uuid4, - editable=False, - primary_key=True, - serialize=False - )), - ('corpus', models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='worker_version_cache', - to='documents.corpus', - )), - ('worker_version', models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='corpus_cache', - to='process.workerversion', - )), - ], - options={ - 'unique_together': {('corpus', 'worker_version')}, - }, - ), - migrations.AddField( - model_name='workerversion', - name='corpora', - field=models.ManyToManyField( - related_name='worker_versions', - through='process.CorpusWorkerVersion', - to='documents.Corpus', - ), - ), - migrations.RunPython( - code=rebuild_reminder, - reverse_code=migrations.RunPython.noop, - ) - ] diff --git a/arkindex/process/migrations/0036_datafile_trashed.py b/arkindex/process/migrations/0036_datafile_trashed.py deleted file mode 100644 index d7e4677ae995ba81ffe42c6fe70d3cd4470bf6c6..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0036_datafile_trashed.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.2.6 on 2021-09-09 07:21 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0035_corpus_version_cache'), - ] - - operations = [ - migrations.AddField( - model_name='datafile', - name='trashed', - field=models.BooleanField(default=False), - ), - ] diff --git a/arkindex/process/migrations/0037_workerversion_gpu_usage.py b/arkindex/process/migrations/0037_workerversion_gpu_usage.py deleted file mode 100644 index 0d4850bb7af265a3d202abe55e43327c74e0aa5e..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0037_workerversion_gpu_usage.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 3.2.6 on 2021-09-16 14:05 - -import enumfields.fields -from django.db import migrations - -import arkindex.process.models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0036_datafile_trashed'), - ] - - operations = [ - migrations.AddField( - model_name='workerversion', - name='gpu_usage', - field=enumfields.fields.EnumField(default='disabled', enum=arkindex.process.models.WorkerVersionGPUUsage, max_length=10, blank=True), - ), - ] diff --git a/arkindex/process/migrations/0038_dataimport_use_gpu.py b/arkindex/process/migrations/0038_dataimport_use_gpu.py deleted file mode 100644 index 0cecc4d4443007143de6dd2b6e57f166e19add35..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0038_dataimport_use_gpu.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.2.6 on 2021-10-01 15:11 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0037_workerversion_gpu_usage'), - ] - - operations = [ - migrations.AddField( - model_name='dataimport', - name='use_gpu', - field=models.BooleanField(default=False, blank=True), - ), - ] diff --git a/arkindex/process/migrations/0039_worker_configuration.py b/arkindex/process/migrations/0039_worker_configuration.py deleted file mode 100644 index c42e7074f78941365ffee0c9cc083f6568a35eb5..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0039_worker_configuration.py +++ /dev/null @@ -1,65 +0,0 @@ -# Generated by Django 3.2.5 on 2021-11-04 09:42 - -import uuid - -import django.db.models.deletion -from django.db import migrations, models - -import arkindex.project.fields - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0038_dataimport_use_gpu'), - ] - - operations = [ - migrations.CreateModel( - name='WorkerConfiguration', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=250)), - ('configuration', models.JSONField(blank=True, default=dict)), - ('configuration_hash', arkindex.project.fields.MD5HashField(max_length=32)), - ], - ), - migrations.RemoveConstraint( - model_name='workerrun', - name='worker_run_configuration_objects', - ), - migrations.RenameField( - model_name='workerrun', - old_name='configuration', - new_name='old_configuration', - ), - migrations.AddConstraint( - model_name='workerrun', - constraint=models.CheckConstraint(check=models.Q(('old_configuration__typeof', 'object')), name='worker_run_old_configuration_objects'), - ), - migrations.AddField( - model_name='workerconfiguration', - name='worker', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='configurations', to='process.worker'), - ), - migrations.AddField( - model_name='workeractivity', - name='configuration', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='worker_activities', to='process.workerconfiguration'), - ), - migrations.AddField( - model_name='workerrun', - name='configuration', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='worker_runs', to='process.workerconfiguration'), - ), - migrations.AddConstraint( - model_name='workerconfiguration', - constraint=models.CheckConstraint(check=models.Q(('configuration__typeof', 'object')), name='worker_configuration_configuration_objects'), - ), - migrations.AlterUniqueTogether( - name='workerconfiguration', - unique_together={('worker', 'name'), ('worker', 'configuration_hash')}, - ), - ] diff --git a/arkindex/process/migrations/0040_use_worker_configuration.py b/arkindex/process/migrations/0040_use_worker_configuration.py deleted file mode 100644 index 7c9c4769e82ef60a15a0adb873ed9f43593df3f3..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0040_use_worker_configuration.py +++ /dev/null @@ -1,54 +0,0 @@ -# Generated by Django 3.2.5 on 2021-11-04 08:14 - -from collections import defaultdict - -from django.db import migrations - -from arkindex.process.utils import hash_object - - -def use_worker_configuration(apps, schema_editor): - WorkerRun = apps.get_model('process', 'WorkerRun') - WorkerConfiguration = apps.get_model('process', 'WorkerConfiguration') - - indexes = defaultdict(int) - - for worker_run in WorkerRun.objects.filter(configuration__isnull=True) \ - .exclude(old_configuration={}) \ - .select_related('version__worker'): - worker = worker_run.version.worker - worker_configuration, created = WorkerConfiguration.objects.get_or_create( - worker=worker, - configuration_hash=hash_object(worker_run.old_configuration), - defaults={ - 'name': f'config for {worker.name} n°{indexes[worker.id]+1}', - 'configuration': worker_run.old_configuration - } - ) - indexes[worker.id] += created - worker_run.configuration = worker_configuration - worker_run.save() - - -def use_old_configuration(apps, schema_editor): - WorkerRun = apps.get_model('process', 'WorkerRun') - - worker_runs = WorkerRun.objects.filter(configuration__isnull=False).select_related('configuration') - for worker_run in worker_runs: - worker_run.old_configuration = worker_run.configuration.configuration - WorkerRun.objects.bulk_update(worker_runs, ['old_configuration']) - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0039_worker_configuration'), - ] - - operations = [ - migrations.RunPython( - use_worker_configuration, - reverse_code=use_old_configuration, - elidable=True, - ), - ] diff --git a/arkindex/process/migrations/0041_remove_old_configuration.py b/arkindex/process/migrations/0041_remove_old_configuration.py deleted file mode 100644 index b04a34706a855b858b6b70876fe2e77b7c306099..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0041_remove_old_configuration.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 3.2.5 on 2021-11-04 08:14 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0040_use_worker_configuration'), - ] - - operations = [ - migrations.RemoveConstraint( - model_name='workerrun', - name='worker_run_old_configuration_objects', - ), - migrations.RemoveField( - model_name='workerrun', - name='old_configuration', - ), - ] diff --git a/arkindex/process/migrations/0042_alter_workeractivity_constraints.py b/arkindex/process/migrations/0042_alter_workeractivity_constraints.py deleted file mode 100644 index 01a9f5c8e7a0fdf5ae316ebb08617cf0c822bbef..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0042_alter_workeractivity_constraints.py +++ /dev/null @@ -1,25 +0,0 @@ -# Generated by Django 3.2.5 on 2021-11-05 13:25 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0041_remove_old_configuration'), - ] - - operations = [ - migrations.AlterUniqueTogether( - name='workeractivity', - unique_together=set(), - ), - migrations.AddConstraint( - model_name='workeractivity', - constraint=models.UniqueConstraint(condition=models.Q(('configuration__isnull', True)), fields=('worker_version', 'element'), name='worker_activity_unique_no_configuration'), - ), - migrations.AddConstraint( - model_name='workeractivity', - constraint=models.UniqueConstraint(condition=models.Q(('configuration__isnull', False)), fields=('worker_version', 'element', 'configuration'), name='worker_activity_unique_configuration'), - ), - ] diff --git a/arkindex/process/migrations/0043_dataimport_template.py b/arkindex/process/migrations/0043_dataimport_template.py deleted file mode 100644 index 0e9a3d1034470a1e00c0be73a1ae8253f9e2ddcb..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0043_dataimport_template.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 3.2.6 on 2021-11-18 12:13 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0042_alter_workeractivity_constraints'), - ] - - operations = [ - migrations.AddField( - model_name='dataimport', - name='template', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='applications', to='process.dataimport'), - ), - ] diff --git a/arkindex/process/migrations/0044_alter_workerconfiguration_configuration.py b/arkindex/process/migrations/0044_alter_workerconfiguration_configuration.py deleted file mode 100644 index 1467a86be19ce330a446f7c7e6746143c8197e86..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0044_alter_workerconfiguration_configuration.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.2.6 on 2021-11-30 16:34 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0043_dataimport_template'), - ] - - operations = [ - migrations.AlterField( - model_name='workerconfiguration', - name='configuration', - field=models.JSONField(default=dict), - ), - ] diff --git a/arkindex/process/migrations/0045_remove_dataimport_best_class.py b/arkindex/process/migrations/0045_remove_dataimport_best_class.py deleted file mode 100644 index 07d089decb67005541753d811d67c153a889bdcb..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0045_remove_dataimport_best_class.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 3.2.6 on 2021-12-14 14:32 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0044_alter_workerconfiguration_configuration'), - ] - - operations = [ - migrations.RemoveField( - model_name='dataimport', - name='best_class', - ), - ] diff --git a/arkindex/process/migrations/0046_workertype_alter_worker_type.py b/arkindex/process/migrations/0046_workertype_alter_worker_type.py deleted file mode 100644 index 19062cf5e9e9b3b2fb597b65943e2444f5416de4..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0046_workertype_alter_worker_type.py +++ /dev/null @@ -1,79 +0,0 @@ -# Generated by Django 4.0.2 on 2022-04-07 11:43 - -import uuid - -import django.db.models.deletion -from django.db import migrations, models - - -def update_worker_types(apps, schema_editor): - Worker = apps.get_model('process', 'Worker') - WorkerType = apps.get_model('process', 'WorkerType') - - # Get list of current worker types - current_types = Worker.objects.values('type').distinct() - created_types = WorkerType.objects.bulk_create( - [WorkerType(slug=type_slug['type'], display_name=type_slug['type'].capitalize()) for type_slug in current_types] - ) - for worker_type in created_types: - Worker.objects.filter(type=worker_type.slug).update(type_fk=worker_type.id) - - -def retrieve_worker_type_slugs(apps, schema_editor): - Worker = apps.get_model('process', 'Worker') - for worker in Worker.objects.all(): - worker.type = worker.type_fk.slug - worker.save() - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0045_remove_dataimport_best_class'), - ] - - operations = [ - migrations.CreateModel( - name='WorkerType', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('slug', models.CharField(max_length=100, unique=True)), - ('display_name', models.CharField(max_length=100)), - ('created', models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now)), - ('updated', models.DateTimeField(auto_now=True)) - ], - ), - migrations.AddField( - model_name='worker', - name='type_fk', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='type', to='process.workertype'), - ), - migrations.AlterField( - model_name="worker", - name="type", - field=models.CharField(max_length=50, null=True), - ), - migrations.RunPython( - update_worker_types, - reverse_code=retrieve_worker_type_slugs - ), - migrations.RemoveField( - model_name='worker', - name='type', - ), - migrations.RenameField( - model_name='worker', - old_name='type_fk', - new_name='type', - ), - migrations.AlterField( - model_name="worker", - name="type", - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='type', to='process.workertype'), - ), - migrations.AlterField( - model_name="workertype", - name="created", - field=models.DateTimeField(auto_now_add=True) - ) - ] diff --git a/arkindex/process/migrations/0047_workerversion_model_usage.py b/arkindex/process/migrations/0047_workerversion_model_usage.py deleted file mode 100644 index df9392b63bddcf1078c4e4e3d16a8f045f7e9d3e..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0047_workerversion_model_usage.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.0.2 on 2022-05-03 15:12 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0046_workertype_alter_worker_type'), - ] - - operations = [ - migrations.AddField( - model_name='workerversion', - name='model_usage', - field=models.BooleanField(default=False), - ), - ] diff --git a/arkindex/process/migrations/0048_workerrun_model_version.py b/arkindex/process/migrations/0048_workerrun_model_version.py deleted file mode 100644 index 8fc0e95c201b39886a08ba80ec9c45da124578f1..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0048_workerrun_model_version.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 4.0.2 on 2022-05-03 16:14 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('training', '0004_modelversion_archive_hash'), - ('process', '0047_workerversion_model_usage'), - ] - - operations = [ - migrations.AddField( - model_name='workerrun', - name='model_version', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='worker_runs', to='training.modelversion'), - ), - ] diff --git a/arkindex/process/migrations/0049_dataimport_s3.py b/arkindex/process/migrations/0049_dataimport_s3.py deleted file mode 100644 index 27594f2899e55a9d98f4fe3bf20fc11421114ffa..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0049_dataimport_s3.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 4.0.4 on 2022-06-14 13:52 - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0048_workerrun_model_version'), - ] - - operations = [ - migrations.AddField( - model_name='dataimport', - name='bucket_name', - field=models.CharField(blank=True, max_length=63, null=True, validators=[django.core.validators.MinLengthValidator(3)]), - ), - migrations.AddField( - model_name='dataimport', - name='prefix', - field=models.CharField(blank=True, max_length=1024, null=True), - ), - ] diff --git a/arkindex/process/migrations/0050_workerrun_summary.py b/arkindex/process/migrations/0050_workerrun_summary.py deleted file mode 100644 index f2aa8b5a56e21d28b78bbb56f03fe63d6f79a7d4..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0050_workerrun_summary.py +++ /dev/null @@ -1,72 +0,0 @@ -# Generated by Django 4.0.2 on 2022-06-13 12:40 - -from django.db import migrations, models -from django.db.models.query import Prefetch - - -def generate_worker_run_summaries(apps, schema_editor): - WorkerRun = apps.get_model('process', 'WorkerRun') - GitRef = apps.get_model('process', 'GitRef') - runs = WorkerRun.objects.select_related( - 'version__worker', - 'version__revision', - 'model_version__model', - 'configuration' - ).only( - # Required to make joins and for the bulk update - 'id', - 'version_id', - 'version__worker__name', - # Required for the prefetch_related. Using `revision_id` instead of `revision__id` causes Django to select the entire revision anyway - 'version__revision__id', - 'model_version_id', - 'model_version__model__name', - 'configuration__name' - ).prefetch_related( - Prefetch( - 'version__revision__refs', - # revision_id is required to make the link between refs and revisions - queryset=GitRef.objects.only('revision_id', 'name') - ) - ) - - for run in runs: - summary_text = f"Worker {run.version.worker.name} @ " - git_ref_names = run.version.revision.refs.values_list('name', flat=True) - if len(git_ref_names) > 0: - summary_text += ", ".join(git_ref_names) - else: - summary_text += str(run.version.id)[0:6] - - if run.model_version: - summary_text += f" with model {run.model_version.model.name} @ {str(run.model_version.id)[0:6]}" - - if run.configuration: - summary_text += f" using configuration '{run.configuration.name}'" - - run.summary = summary_text - WorkerRun.objects.bulk_update(runs, ['summary']) - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0049_dataimport_s3'), - ] - - operations = [ - migrations.AddField( - model_name='workerrun', - name='summary', - field=models.TextField(null=True), - ), - migrations.RunPython( - generate_worker_run_summaries, - reverse_code=migrations.RunPython.noop - ), - migrations.AlterField( - model_name='workerrun', - name='summary', - field=models.TextField(), - ), - ] diff --git a/arkindex/process/migrations/0051_workerconfiguration_archived.py b/arkindex/process/migrations/0051_workerconfiguration_archived.py deleted file mode 100644 index 2f5659cd6b8fc058f8d58af3c8d5c5e745563769..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0051_workerconfiguration_archived.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.0.5 on 2022-07-12 13:10 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0050_workerrun_summary'), - ] - - operations = [ - migrations.AddField( - model_name='workerconfiguration', - name='archived', - field=models.BooleanField(default=False), - ), - ] diff --git a/arkindex/process/migrations/0052_dataimport_test_and_train_folders_fks.py b/arkindex/process/migrations/0052_dataimport_test_and_train_folders_fks.py deleted file mode 100644 index 4ecbfba5e7ac6c5fbc696ecfa408f77869018998..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0052_dataimport_test_and_train_folders_fks.py +++ /dev/null @@ -1,48 +0,0 @@ -# Generated by Django 4.1a1 on 2022-07-07 14:14 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("documents", "0057_entity_list_index"), - ("process", "0051_workerconfiguration_archived"), - ] - - operations = [ - migrations.AddField( - model_name="dataimport", - name="test_folder", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name="test_folder_processes", - to="documents.element", - ), - ), - migrations.AddField( - model_name="dataimport", - name="train_folder", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name="train_folder_processes", - to="documents.element", - ), - ), - migrations.AddField( - model_name='dataimport', - name='validation_folder', - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name='validation_folder_processes', - to='documents.element' - ), - ), - ] diff --git a/arkindex/process/migrations/0053_remove_dataimport_build_entities.py b/arkindex/process/migrations/0053_remove_dataimport_build_entities.py deleted file mode 100644 index ae4a1588fbe9a235717aea452ba9037a8824c4a5..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0053_remove_dataimport_build_entities.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 4.0.2 on 2022-07-25 15:22 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0052_dataimport_test_and_train_folders_fks'), - ] - - operations = [ - migrations.RemoveField( - model_name='dataimport', - name='build_entities', - ), - ] diff --git a/arkindex/process/migrations/0054_alter_workertype_slug.py b/arkindex/process/migrations/0054_alter_workertype_slug.py deleted file mode 100644 index f409fe986234b8be72d2fa191be129dba19e6e20..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0054_alter_workertype_slug.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.0.4 on 2022-08-01 10:12 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0053_remove_dataimport_build_entities'), - ] - - operations = [ - migrations.AlterField( - model_name='workertype', - name='slug', - field=models.SlugField(max_length=100, unique=True), - ), - ] diff --git a/arkindex/process/migrations/0055_remove_repository_type_iiif.py b/arkindex/process/migrations/0055_remove_repository_type_iiif.py deleted file mode 100644 index f4958ffbe08933c7e3b5be0a9b25da3630a3af99..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0055_remove_repository_type_iiif.py +++ /dev/null @@ -1,29 +0,0 @@ -# Generated by Django 4.0.2 on 2022-07-26 14:19 - -from django.db import migrations -from enumfields import Enum - - -class OldRepositoryType(Enum): - IIIF = 'iiif' - - -def remove_git_iiif(apps, schema_editor): - Repository = apps.get_model('process', 'Repository') - Repository.type.field.enum = OldRepositoryType - Repository.objects.filter(type=OldRepositoryType.IIIF).delete() - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0054_alter_workertype_slug'), - ] - - operations = [ - migrations.RunPython( - remove_git_iiif, - reverse_code=migrations.RunPython.noop, - elidable=True - ) - ] diff --git a/arkindex/process/migrations/0056_remove_repository_type.py b/arkindex/process/migrations/0056_remove_repository_type.py deleted file mode 100644 index 904a3323b1215132772c84d11dd487b058314e7f..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0056_remove_repository_type.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 4.0.4 on 2022-08-03 16:36 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0055_remove_repository_type_iiif'), - ] - - operations = [ - migrations.RemoveField( - model_name='repository', - name='type' - ) - ] diff --git a/arkindex/process/migrations/0057_dataimport_model.py b/arkindex/process/migrations/0057_dataimport_model.py deleted file mode 100644 index f836997a5f47fc51b421215801fafc428d8889ce..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0057_dataimport_model.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 4.0.4 on 2022-08-03 15:11 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('training', '0004_modelversion_archive_hash'), - ('process', '0056_remove_repository_type'), - ] - - operations = [ - migrations.AddField( - model_name='dataimport', - name='model', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='training_processes', to='training.model'), - ), - ] diff --git a/arkindex/process/migrations/0058_merge_file_imports.py b/arkindex/process/migrations/0058_merge_file_imports.py deleted file mode 100644 index 53f4ba85d547efbc7cec6d5f14c43a8a90df981e..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0058_merge_file_imports.py +++ /dev/null @@ -1,32 +0,0 @@ -# Generated by Django 4.0.4 on 2022-08-23 15:46 - -from django.db import migrations -from enumfields import Enum - - -class OldImportModes(Enum): - Images = 'images' - PDF = 'pdf' - Files = 'files' - - -def update_process_mode(apps, schema_editor): - DataImport = apps.get_model('process', 'DataImport') - DataImport.mode.field.enum = OldImportModes - updated_processes = DataImport.objects.filter(mode__in=OldImportModes) - updated_processes.update(mode=OldImportModes.Files) - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0057_dataimport_model'), - ] - - operations = [ - migrations.RunPython( - update_process_mode, - reverse_code=migrations.RunPython.noop, - elidable=True - ) - ] diff --git a/arkindex/process/migrations/0059_rename_dataimport_to_process.py b/arkindex/process/migrations/0059_rename_dataimport_to_process.py deleted file mode 100644 index ba9b5f036247ac79890c2ecb1defe2af9f1a53aa..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0059_rename_dataimport_to_process.py +++ /dev/null @@ -1,82 +0,0 @@ -# Generated by Django 4.0.4 on 2022-08-31 09:14 - -import django.core.validators -import django.db.models.deletion -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('training', '0004_modelversion_archive_hash'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('ponos', '0032_stringify_json'), - ('documents', '0058_remove_corpus_repository'), - ('process', '0058_merge_file_imports'), - ] - - operations = [ - migrations.RenameModel( - old_name='DataImport', - new_name='Process', - ), - migrations.RenameModel( - old_name='DataImportElement', - new_name='ProcessElement', - ), - migrations.RenameField( - model_name='processelement', - old_name='dataimport', - new_name='process', - ), - migrations.RenameField( - model_name='workerrun', - old_name='dataimport', - new_name='process', - ), - migrations.AlterField( - model_name='process', - name='corpus', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='processes', to='documents.corpus'), - ), - migrations.AlterField( - model_name='process', - name='creator', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='processes', to=settings.AUTH_USER_MODEL), - ), - migrations.AlterField( - model_name='process', - name='elements', - field=models.ManyToManyField(related_name='processes', through='process.ProcessElement', to='documents.element'), - ), - migrations.AlterField( - model_name='process', - name='files', - field=models.ManyToManyField(related_name='processes', to='process.datafile'), - ), - migrations.AlterField( - model_name='process', - name='revision', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='processes', to='process.revision'), - ), - migrations.AlterField( - model_name='process', - name='versions', - field=models.ManyToManyField(related_name='processes', through='process.WorkerRun', to='process.workerversion'), - ), - migrations.AlterField( - model_name='processelement', - name='element', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='process_elements', to='documents.element'), - ), - migrations.AlterField( - model_name='processelement', - name='process', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='process_elements', to='process.process'), - ), - migrations.AlterModelOptions( - name='process', - options={'ordering': ['corpus', '-created'], 'verbose_name_plural': 'processes'}, - ), - ] diff --git a/arkindex/process/migrations/0060_remove_repository_provider_name.py b/arkindex/process/migrations/0060_remove_repository_provider_name.py deleted file mode 100644 index 9fa7c26a5353737e59278df85b1d4ef851cdcbcd..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0060_remove_repository_provider_name.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 4.0.7 on 2022-10-18 15:51 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0059_rename_dataimport_to_process'), - ] - - operations = [ - migrations.RemoveField( - model_name='repository', - name='provider_name', - ), - ] diff --git a/arkindex/process/migrations/0061_workeractivity_updated_triggers.py b/arkindex/process/migrations/0061_workeractivity_updated_triggers.py deleted file mode 100644 index 65b6dd3877cae2f1c04de85ba801f8b1ce40af07..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0061_workeractivity_updated_triggers.py +++ /dev/null @@ -1,50 +0,0 @@ -# Generated by Django 4.0.7 on 2022-10-19 16:05 - -from django.db import migrations, models - -import pgtrigger.compiler -import pgtrigger.migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0060_remove_repository_provider_name'), - ] - - operations = [ - migrations.AlterField( - model_name='workeractivity', - name='updated', - field=models.DateTimeField(auto_now_add=True), - ), - pgtrigger.migrations.AddTrigger( - model_name='workeractivity', - trigger=pgtrigger.compiler.Trigger( - name='update_workeractivity_updated', - sql=pgtrigger.compiler.UpsertTriggerSql( - func='NEW.updated = now(); RETURN NEW;', - hash='1e5a8fa0718f420e6cd4f2a31434cd39a9c9bc67', - operation='UPDATE', - pgid='pgtrigger_update_workeractivity_updated_f2812', - table='process_workeractivity', - when='BEFORE', - ) - ), - ), - pgtrigger.migrations.AddTrigger( - model_name='workeractivity', - trigger=pgtrigger.compiler.Trigger( - name='read_only_workeractivity_updated', - sql=pgtrigger.compiler.UpsertTriggerSql( - condition='WHEN (OLD."updated" IS DISTINCT FROM (NEW."updated"))', - func="RAISE EXCEPTION 'pgtrigger: Cannot update rows from % table', TG_TABLE_NAME;", - hash='6276c6971a1d2669659e407418e2db1fa7dc6965', - operation='UPDATE', - pgid='pgtrigger_read_only_workeractivity_updated_a80ab', - table='process_workeractivity', - when='BEFORE', - ) - ), - ), - ] diff --git a/arkindex/process/migrations/0062_workeractivity_started.py b/arkindex/process/migrations/0062_workeractivity_started.py deleted file mode 100644 index a07c75a07e509f6ff5f6c5477263a0e05cf7149c..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0062_workeractivity_started.py +++ /dev/null @@ -1,41 +0,0 @@ -# Generated by Django 4.0.4 on 2022-12-05 09:44 - -from django.db import migrations, models - -from arkindex.process.models import WorkerActivityState - - -def set_started_on_started(apps, schema_editor): - """ - In case this migration runs while some processes were running, some activities might be in a `started` state - and we therefore need to set their start time before we can apply the new check constraint. - We do know their start time though: their last update time will be the time where they were set to `started`. - """ - WorkerActivity = apps.get_model('process', 'WorkerActivity') - WorkerActivity.objects.filter(state=WorkerActivityState.Started).update(started=models.F('updated')) - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0061_workeractivity_updated_triggers'), - ] - - operations = [ - migrations.AddField( - model_name='workeractivity', - name='started', - field=models.DateTimeField(blank=True, null=True), - ), - migrations.RunPython( - set_started_on_started, - reverse_code=migrations.RunPython.noop, - ), - migrations.AddConstraint( - model_name='workeractivity', - constraint=models.CheckConstraint( - check=~models.Q(state=WorkerActivityState.Started) | models.Q(started__isnull=False), - name='worker_activity_started_requires_started', - ), - ), - ] diff --git a/arkindex/process/migrations/0063_workeractivity_process_not_null.py b/arkindex/process/migrations/0063_workeractivity_process_not_null.py deleted file mode 100644 index 8174e3ade5c2e4148f9c79ef05593a7fdcab9c51..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0063_workeractivity_process_not_null.py +++ /dev/null @@ -1,35 +0,0 @@ -# Generated by Django 4.1.4 on 2023-01-09 15:42 - -from django.db import migrations, models - - -def check_no_null_process_id(apps, schema_editor): - WorkerActivity = apps.get_model('process', 'WorkerActivity') - assert not WorkerActivity.objects.filter(process_id=None).exists(), ( - 'Some WorkerActivities exist without a `process_id`. ' - 'Please either link them to a process or delete them before running this migration.' - ) - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0062_workeractivity_started'), - ] - - operations = [ - migrations.RunPython( - check_no_null_process_id, - reverse_code=migrations.RunPython.noop, - elidable=True, - ), - migrations.AlterField( - model_name='workeractivity', - name='process', - field=models.ForeignKey( - on_delete=models.CASCADE, - related_name='activities', - to='process.Process', - ), - ), - ] diff --git a/arkindex/process/migrations/0064_local_process_constraints.py b/arkindex/process/migrations/0064_local_process_constraints.py deleted file mode 100644 index e17ef131cc5526e369ecf820abaa8f889ddd9ff3..0000000000000000000000000000000000000000 --- a/arkindex/process/migrations/0064_local_process_constraints.py +++ /dev/null @@ -1,55 +0,0 @@ -# Generated by Django 4.1.5 on 2023-02-14 10:16 - -from django.db import migrations, models - -from arkindex.process.models import ProcessMode - - -def remove_corpus_on_repository_processes(apps, schema_editor): - """ - Processes that were ran on IIIF repositories had a corpus linked to them. - This unsets the corpus on those as we now only support worker imports - and repository processes should no longer have a corpus. - """ - Process = apps.get_model('process', 'Process') - Process.objects.filter(mode=ProcessMode.Repository).exclude(corpus=None).update(corpus=None) - - -class Migration(migrations.Migration): - - dependencies = [ - ('process', '0063_workeractivity_process_not_null'), - ] - - operations = [ - migrations.RunPython( - remove_corpus_on_repository_processes, - reverse_code=migrations.RunPython.noop, - elidable=True, - ), - migrations.AddConstraint( - model_name='process', - constraint=models.CheckConstraint( - check=models.Q(mode__in=(ProcessMode.Local, ProcessMode.Repository)) ^ ~models.Q(corpus=None), - name='check_process_corpus', - violation_error_message='Local and repository processes cannot have a corpus, and other modes must have one set.', - ), - ), - migrations.AddConstraint( - model_name='process', - constraint=models.CheckConstraint( - check=~models.Q(mode=ProcessMode.Local) | models.Q(workflow=None), - name='local_process_no_workflow', - violation_error_message='Local processes cannot be started.', - ), - ), - migrations.AddConstraint( - model_name='process', - constraint=models.UniqueConstraint( - models.F('creator'), - condition=models.Q(mode=ProcessMode.Local), - name='unique_local_process', - violation_error_message='Only one local process is allowed per user.', - ), - ), - ] diff --git a/arkindex/training/migrations/0001_initial.py b/arkindex/training/migrations/0001_initial.py index df26b05b33600a6cdd3e40ba313901cf54561a7b..56ad1bc37d92ed6b2855979b3b2aa04f6a1c291a 100644 --- a/arkindex/training/migrations/0001_initial.py +++ b/arkindex/training/migrations/0001_initial.py @@ -1,11 +1,14 @@ -# Generated by Django 4.0.2 on 2022-03-16 09:50 +# Generated by Django 4.1.7 on 2023-05-29 11:49 import uuid +import django.contrib.postgres.fields +import django.core.validators import django.db.models.deletion import enumfields.fields from django.db import migrations, models +import arkindex.project.aws import arkindex.project.fields import arkindex.training.models @@ -15,10 +18,32 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('process', '0045_remove_dataimport_best_class'), + ('process', '0001_initial'), + ('documents', '0002_initial'), ] operations = [ + migrations.CreateModel( + name='Dataset', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('name', models.CharField(max_length=100, validators=[django.core.validators.MinLengthValidator(1)])), + ('description', models.TextField(validators=[django.core.validators.MinLengthValidator(1)])), + ('state', enumfields.fields.EnumField(default='open', enum=arkindex.training.models.DatasetState, max_length=10)), + ('sets', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=50, validators=[django.core.validators.MinLengthValidator(1)]), default=arkindex.training.models.default_sets, size=None, validators=[django.core.validators.MinLengthValidator(1), arkindex.training.models.validate_unique_set_names])), + ('corpus', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='datasets', to='documents.corpus')), + ], + ), + migrations.CreateModel( + name='MetricKey', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('name', models.CharField(max_length=100)), + ('mode', enumfields.fields.EnumField(default='series', enum=arkindex.training.models.MetricMode, max_length=10)), + ], + ), migrations.CreateModel( name='Model', fields=[ @@ -28,7 +53,7 @@ class Migration(migrations.Migration): ('name', models.CharField(max_length=100, unique=True)), ('description', models.TextField(default='')), ('public', models.BooleanField(default=False)), - ('compatible_workers', models.ManyToManyField(related_name='models', to='process.Worker')), + ('compatible_workers', models.ManyToManyField(related_name='models', to='process.worker')), ], options={ 'abstract': False, @@ -41,16 +66,39 @@ class Migration(migrations.Migration): ('created', models.DateTimeField(auto_now_add=True)), ('updated', models.DateTimeField(auto_now=True)), ('description', models.TextField(default='')), - ('tag', models.CharField(blank=True, max_length=50, null=True)), + ('tag', models.CharField(default=None, max_length=50, null=True)), ('state', enumfields.fields.EnumField(default='created', enum=arkindex.training.models.ModelVersionState, max_length=10)), - ('hash', arkindex.project.fields.MD5HashField(max_length=32)), - ('size', models.PositiveIntegerField(help_text='file size in bytes')), + ('hash', arkindex.project.fields.MD5HashField(blank=True, help_text="hash of the content of the archive which contains the model version's data", max_length=32, null=True)), + ('archive_hash', arkindex.project.fields.MD5HashField(blank=True, help_text="hash of the archive which contains the model version's data", max_length=32, null=True)), + ('size', models.PositiveIntegerField(blank=True, help_text='file size in bytes', null=True)), ('configuration', models.JSONField(default=dict)), ('model', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='versions', to='training.model')), ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='training.modelversion')), ], - options={ - 'unique_together': {('model', 'tag')}, - }, + bases=(arkindex.project.aws.S3FileMixin, models.Model), + ), + migrations.CreateModel( + name='MetricValue', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('value', models.FloatField()), + ('created', models.DateTimeField(auto_now_add=True)), + ('step', models.PositiveIntegerField(blank=True, null=True)), + ('metric', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='values', to='training.metrickey')), + ], + ), + migrations.AddField( + model_name='metrickey', + name='model_version', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='metrics', to='training.modelversion'), + ), + migrations.CreateModel( + name='DatasetElement', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('set', models.CharField(max_length=50, validators=[django.core.validators.MinLengthValidator(1)])), + ('dataset', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='dataset_elements', to='training.dataset')), + ('element', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='dataset_elements', to='documents.element')), + ], ), ] diff --git a/arkindex/training/migrations/0002_alter_modelversion_tag.py b/arkindex/training/migrations/0002_alter_modelversion_tag.py deleted file mode 100644 index 156b5506b4db00cdef06fc408b0513bf6da4807d..0000000000000000000000000000000000000000 --- a/arkindex/training/migrations/0002_alter_modelversion_tag.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.0.2 on 2022-03-23 14:06 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('training', '0001_initial'), - ] - - operations = [ - migrations.AlterField( - model_name='modelversion', - name='tag', - field=models.CharField(blank=True, default=None, max_length=50, null=True), - ), - ] diff --git a/arkindex/training/migrations/0002_initial.py b/arkindex/training/migrations/0002_initial.py new file mode 100644 index 0000000000000000000000000000000000000000..5428664be49d9827699c2c350f961371eee0f157 --- /dev/null +++ b/arkindex/training/migrations/0002_initial.py @@ -0,0 +1,63 @@ +# Generated by Django 4.1.7 on 2023-05-29 11:49 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('documents', '0003_initial'), + ('training', '0001_initial'), + ('ponos', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddField( + model_name='dataset', + name='creator', + field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='datasets', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='dataset', + name='elements', + field=models.ManyToManyField(related_name='datasets', through='training.DatasetElement', to='documents.element'), + ), + migrations.AddField( + model_name='dataset', + name='task', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='dataset', to='ponos.task'), + ), + migrations.AddConstraint( + model_name='modelversion', + constraint=models.UniqueConstraint(fields=('model', 'tag'), name='modelversion_unique_tag'), + ), + migrations.AddConstraint( + model_name='modelversion', + constraint=models.UniqueConstraint(condition=models.Q(('hash__isnull', False)), fields=('model', 'hash'), name='modelversion_unique_hash'), + ), + migrations.AddConstraint( + model_name='metricvalue', + constraint=models.UniqueConstraint(condition=models.Q(('step__isnull', False)), fields=('metric', 'step'), name='metric_unique_step'), + ), + migrations.AddConstraint( + model_name='metricvalue', + constraint=models.UniqueConstraint(condition=models.Q(('step__isnull', True)), fields=('metric', 'created'), name='metric_unique_no_step'), + ), + migrations.AlterUniqueTogether( + name='metrickey', + unique_together={('name', 'model_version')}, + ), + migrations.AddConstraint( + model_name='datasetelement', + constraint=models.UniqueConstraint(fields=('dataset', 'element', 'set'), name='unique_dataset_elements'), + ), + migrations.AddConstraint( + model_name='dataset', + constraint=models.UniqueConstraint(fields=('corpus', 'name'), name='unique_dataset_names'), + ), + ] diff --git a/arkindex/training/migrations/0003_alter_modelversion_unique_together_and_more.py b/arkindex/training/migrations/0003_alter_modelversion_unique_together_and_more.py deleted file mode 100644 index 5a8c7217265d8bbe1772736d0992667b9ba17942..0000000000000000000000000000000000000000 --- a/arkindex/training/migrations/0003_alter_modelversion_unique_together_and_more.py +++ /dev/null @@ -1,26 +0,0 @@ -# Generated by Django 4.0.2 on 2022-03-31 08:51 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('training', '0002_alter_modelversion_tag'), - ] - - operations = [ - migrations.AlterUniqueTogether( - name='modelversion', - unique_together={('model', 'tag')}, - ), - migrations.AlterField( - model_name='modelversion', - name='tag', - field=models.CharField(default=None, max_length=50, null=True), - ), - migrations.AlterUniqueTogether( - name='modelversion', - unique_together={('model', 'tag'), ('model', 'hash')}, - ), - ] diff --git a/arkindex/training/migrations/0004_modelversion_archive_hash.py b/arkindex/training/migrations/0004_modelversion_archive_hash.py deleted file mode 100644 index 32de137a13ca19d6374918072c62c1abb26fffb5..0000000000000000000000000000000000000000 --- a/arkindex/training/migrations/0004_modelversion_archive_hash.py +++ /dev/null @@ -1,26 +0,0 @@ -# Generated by Django 4.0.2 on 2022-04-14 11:02 - -from django.db import migrations - -import arkindex.project.fields - - -class Migration(migrations.Migration): - - dependencies = [ - ('training', '0003_alter_modelversion_unique_together_and_more'), - ] - - operations = [ - migrations.AddField( - model_name='modelversion', - name='archive_hash', - field=arkindex.project.fields.MD5HashField(default='00000000000000000000000000000000', help_text="hash of the archive which contains the model version's data", max_length=32), - preserve_default=False, - ), - migrations.AlterField( - model_name='modelversion', - name='hash', - field=arkindex.project.fields.MD5HashField(help_text="hash of the content of the archive which contains the model version's data", max_length=32), - ), - ] diff --git a/arkindex/training/migrations/0005_metrics_metrickey_metricvalue.py b/arkindex/training/migrations/0005_metrics_metrickey_metricvalue.py deleted file mode 100644 index d3df988424f702263b429244176735a19250a5c0..0000000000000000000000000000000000000000 --- a/arkindex/training/migrations/0005_metrics_metrickey_metricvalue.py +++ /dev/null @@ -1,50 +0,0 @@ -# Generated by Django 4.0.4 on 2022-12-09 14:59 - -import uuid - -import django.db.models.deletion -import enumfields.fields -from django.db import migrations, models - -import arkindex.training.models - - -class Migration(migrations.Migration): - - dependencies = [ - ('training', '0004_modelversion_archive_hash'), - ] - - operations = [ - migrations.CreateModel( - name='MetricKey', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('name', models.CharField(max_length=100)), - ('mode', enumfields.fields.EnumField(default='series', enum=arkindex.training.models.MetricMode, max_length=10)), - ('model_version', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='metrics', to='training.modelversion')), - ], - ), - migrations.CreateModel( - name='MetricValue', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('value', models.FloatField()), - ('created', models.DateTimeField(auto_now_add=True)), - ('step', models.PositiveIntegerField(blank=True, null=True)), - ('metric', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='values', to='training.metrickey')), - ], - ), - migrations.AddConstraint( - model_name='metricvalue', - constraint=models.UniqueConstraint(condition=models.Q(('step__isnull', False)), fields=('metric', 'step'), name='metric_unique_step'), - ), - migrations.AddConstraint( - model_name='metricvalue', - constraint=models.UniqueConstraint(condition=models.Q(('step__isnull', True)), fields=('metric', 'created'), name='metric_unique_no_step'), - ), - migrations.AlterUniqueTogether( - name='metrickey', - unique_together={('name', 'model_version')}, - ), - ] diff --git a/arkindex/training/migrations/0006_alter_modelversion_unique_together_and_more.py b/arkindex/training/migrations/0006_alter_modelversion_unique_together_and_more.py deleted file mode 100644 index bc0f3e97dc85293de869fd0d6daf1543b49239b3..0000000000000000000000000000000000000000 --- a/arkindex/training/migrations/0006_alter_modelversion_unique_together_and_more.py +++ /dev/null @@ -1,42 +0,0 @@ -# Generated by Django 4.1.4 on 2023-01-03 13:34 - -from django.db import migrations, models - -import arkindex.project.fields - - -class Migration(migrations.Migration): - - dependencies = [ - ('training', '0005_metrics_metrickey_metricvalue'), - ] - - operations = [ - migrations.AlterUniqueTogether( - name='modelversion', - unique_together=set(), - ), - migrations.AlterField( - model_name='modelversion', - name='archive_hash', - field=arkindex.project.fields.MD5HashField(blank=True, help_text="hash of the archive which contains the model version's data", max_length=32, null=True), - ), - migrations.AlterField( - model_name='modelversion', - name='hash', - field=arkindex.project.fields.MD5HashField(blank=True, help_text="hash of the content of the archive which contains the model version's data", max_length=32, null=True), - ), - migrations.AlterField( - model_name='modelversion', - name='size', - field=models.PositiveIntegerField(blank=True, help_text='file size in bytes', null=True), - ), - migrations.AddConstraint( - model_name='modelversion', - constraint=models.UniqueConstraint(fields=('model', 'tag'), name='modelversion_unique_tag'), - ), - migrations.AddConstraint( - model_name='modelversion', - constraint=models.UniqueConstraint(condition=models.Q(('hash__isnull', False)), fields=('model', 'hash'), name='modelversion_unique_hash'), - ), - ] diff --git a/arkindex/training/migrations/0007_datasets.py b/arkindex/training/migrations/0007_datasets.py deleted file mode 100644 index ba8b3da58c91790fc7fae3cc71e164de588cdeac..0000000000000000000000000000000000000000 --- a/arkindex/training/migrations/0007_datasets.py +++ /dev/null @@ -1,81 +0,0 @@ -# Generated by Django 4.1.7 on 2023-05-15 16:04 - -import uuid - -from django.conf import settings -from django.contrib.postgres.fields import ArrayField -from django.core.validators import MinLengthValidator -from django.db import migrations, models -from enumfields import EnumField - -from arkindex.training.models import DatasetState, default_sets, validate_unique_set_names - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0064_alter_entity_type_alter_entityrole_child_type_and_more'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('ponos', '0039_keep_task_gpu'), - ('training', '0006_alter_modelversion_unique_together_and_more'), - ] - - operations = [ - migrations.CreateModel( - name='Dataset', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=100, validators=[MinLengthValidator(1)])), - ('description', models.TextField(validators=[MinLengthValidator(1)])), - ('state', EnumField(default='open', enum=DatasetState, max_length=10)), - ('sets', ArrayField(base_field=models.CharField(max_length=50, validators=[MinLengthValidator(1)]), size=None, validators=[MinLengthValidator(1), validate_unique_set_names], default=default_sets)), - ('corpus', models.ForeignKey(on_delete=models.DO_NOTHING, related_name='datasets', to='documents.corpus')), - ('creator', models.ForeignKey(on_delete=models.DO_NOTHING, related_name='datasets', to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.CreateModel( - name='DatasetElement', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('set', models.CharField(max_length=50, validators=[MinLengthValidator(1)])), - ('dataset', models.ForeignKey(on_delete=models.DO_NOTHING, related_name='dataset_elements', to='training.dataset')), - ('element', models.ForeignKey(on_delete=models.DO_NOTHING, related_name='dataset_elements', to='documents.element')), - ], - ), - migrations.AddField( - model_name='dataset', - name='elements', - field=models.ManyToManyField( - related_name='datasets', - through='training.DatasetElement', - to='documents.element', - ), - ), - migrations.AddField( - model_name='dataset', - name='task', - field=models.ForeignKey( - blank=True, - null=True, - on_delete=models.SET_NULL, - related_name='dataset', - to='ponos.task', - ), - ), - migrations.AddConstraint( - model_name='datasetelement', - constraint=models.UniqueConstraint( - fields=('dataset', 'element', 'set'), - name='unique_dataset_elements', - ), - ), - migrations.AddConstraint( - model_name='dataset', - constraint=models.UniqueConstraint( - fields=('corpus', 'name'), - name='unique_dataset_names', - ), - ), - ] diff --git a/arkindex/users/migrations/0001_initial.py b/arkindex/users/migrations/0001_initial.py index f376013b9cc186767d0a97539de9f9e3414fb111..f09617397f666eddc783a58aa24b3385cf1e5eef 100644 --- a/arkindex/users/migrations/0001_initial.py +++ b/arkindex/users/migrations/0001_initial.py @@ -1,56 +1,74 @@ -# Generated by Django 2.2.9 on 2020-01-17 15:39 +# Generated by Django 4.1.7 on 2023-05-29 11:49 import uuid +import django.core.validators import django.db.models.deletion import enumfields.fields from django.conf import settings +from django.contrib.postgres.operations import CreateCollation from django.db import migrations, models import arkindex.users.models -def create_internal_group(apps, schema_editor): - """ - Create the internal group, used for permission checking - - In the event of a migrations reset, this should be kept to make deployments simpler. - """ - db_alias = schema_editor.connection.alias - Group = apps.get_model('auth', 'Group') - Group.objects.using(db_alias).create(id=settings.INTERNAL_GROUP_ID, name='Internal') - - class Migration(migrations.Migration): initial = True dependencies = [ - ('auth', '0011_update_proxy_permissions'), - ('documents', '0001_initial'), + ('documents', '0002_initial'), + ('contenttypes', '0002_remove_content_type_name'), ] operations = [ + CreateCollation( + 'case_insensitive', + provider='icu', + locale='und-u-ks-level2', + deterministic=False, + ), migrations.CreateModel( name='User', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('password', models.CharField(max_length=128, verbose_name='password')), ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), - ('email', models.EmailField(max_length=255, unique=True, verbose_name='email address')), + ('email', models.EmailField(db_collation='case_insensitive', max_length=255, verbose_name='email address')), + ('display_name', models.CharField(max_length=120)), + ('transkribus_email', models.EmailField(blank=True, max_length=255, null=True)), ('is_active', models.BooleanField(default=True)), ('is_admin', models.BooleanField(default=False)), ('verified_email', models.BooleanField(default=False)), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('selected_elements', models.ManyToManyField(related_name='selection_users', through='documents.Selection', to='documents.element')), + ], + ), + migrations.CreateModel( + name='Group', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('name', models.CharField(max_length=64)), + ('public', models.BooleanField(default=False)), + ('use_in_new_project', models.BooleanField(default=False)), + ], + ), + migrations.CreateModel( + name='Right', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('content_id', models.UUIDField(editable=False)), + ('level', models.PositiveIntegerField(help_text='Maximum privilege level.', validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100)])), + ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')), + ('group', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='rights', to='users.group')), + ('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='rights', to=settings.AUTH_USER_MODEL)), ], - options={ - 'abstract': False, - }, ), migrations.CreateModel( name='OAuthCredentials', fields=[ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('provider_name', models.CharField(choices=[('GitLabOAuthProvider', 'GitLab')], max_length=50)), ('provider_url', models.URLField()), ('status', enumfields.fields.EnumField(default='created', enum=arkindex.users.models.OAuthStatus, max_length=10)), ('token', models.CharField(blank=True, max_length=64, null=True)), @@ -59,32 +77,36 @@ class Migration(migrations.Migration): ('account_name', models.CharField(blank=True, max_length=100, null=True)), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='credentials', to=settings.AUTH_USER_MODEL)), ], + options={ + 'verbose_name': 'OAuth credentials', + 'verbose_name_plural': 'OAuth credentials', + }, ), migrations.CreateModel( - name='CorpusRight', + name='UserScope', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('can_write', models.BooleanField(default=False)), - ('can_admin', models.BooleanField(default=False)), - ('corpus', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='corpus_right', to='documents.Corpus')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='corpus_right', to=settings.AUTH_USER_MODEL)), + ('scope', enumfields.fields.EnumField(enum=arkindex.users.models.Scope, max_length=50)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user_scopes', to=settings.AUTH_USER_MODEL)), ], options={ - 'unique_together': {('user', 'corpus')}, + 'unique_together': {('user', 'scope')}, }, ), - migrations.AddField( - model_name='user', - name='corpus', - field=models.ManyToManyField(through='users.CorpusRight', to='documents.Corpus'), + migrations.AddConstraint( + model_name='right', + constraint=models.CheckConstraint(check=models.Q(models.Q(('group_id__isnull', False), ('user_id__isnull', True)), models.Q(('group_id__isnull', True), ('user_id__isnull', False)), _connector='OR'), name='user_xor_group'), + ), + migrations.AddConstraint( + model_name='right', + constraint=models.UniqueConstraint(condition=models.Q(('user__isnull', False)), fields=('user', 'content_id', 'content_type'), name='right_user_unique_target'), + ), + migrations.AddConstraint( + model_name='right', + constraint=models.UniqueConstraint(condition=models.Q(('group__isnull', False)), fields=('group', 'content_id', 'content_type'), name='right_group_unique_target'), ), - migrations.AddField( + migrations.AddConstraint( model_name='user', - name='groups', - field=models.ManyToManyField(blank=True, related_name='users', to='auth.Group'), + constraint=models.UniqueConstraint(fields=('email',), name='email_unique'), ), - migrations.RunPython( - create_internal_group, - reverse_code=migrations.RunPython.noop, - ) ] diff --git a/arkindex/users/migrations/0002_userscope.py b/arkindex/users/migrations/0002_userscope.py deleted file mode 100644 index d5cd0afdfa2b4ae7b875357954d920503ca50c36..0000000000000000000000000000000000000000 --- a/arkindex/users/migrations/0002_userscope.py +++ /dev/null @@ -1,56 +0,0 @@ -# Generated by Django 2.2.10 on 2020-04-30 10:56 - -import django.db.models.deletion -import enumfields.fields -from django.conf import settings -from django.db import migrations, models - -from arkindex.users.models import Scope - - -def add_scopes(apps, schema_editor): - db_alias = schema_editor.connection.alias - User = apps.get_model('users', 'User') - UserScope = apps.get_model('users', 'UserScope') - UserScope.objects.using(db_alias).bulk_create([ - UserScope(user=user, scope=scope) - for user in User.objects.using(db_alias).all() - for scope in (Scope.CreateIIIFImage, Scope.UploadS3Image) - ]) - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0001_initial'), - ] - - operations = [ - migrations.CreateModel( - name='UserScope', - fields=[ - ('id', models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name='ID', - )), - ('scope', enumfields.fields.EnumField( - enum=Scope, - max_length=50, - )), - ('user', models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name='user_scopes', - to=settings.AUTH_USER_MODEL, - )), - ], - options={ - 'unique_together': {('user', 'scope')}, - }, - ), - migrations.RunPython( - add_scopes, - reverse_code=migrations.RunPython.noop, - ) - ] diff --git a/arkindex/users/migrations/0003_user_selected_elements.py b/arkindex/users/migrations/0003_user_selected_elements.py deleted file mode 100644 index c24e7cd79c627a7607901124dd58f360653b0a0c..0000000000000000000000000000000000000000 --- a/arkindex/users/migrations/0003_user_selected_elements.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 2.2.13 on 2020-06-24 14:39 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('documents', '0016_selection'), - ('users', '0002_userscope'), - ] - - operations = [ - migrations.AddField( - model_name='user', - name='selected_elements', - field=models.ManyToManyField( - related_name='selection_users', - through='documents.Selection', - to='documents.Element', - ), - ), - ] diff --git a/arkindex/users/migrations/0004_internal_bool.py b/arkindex/users/migrations/0004_internal_bool.py deleted file mode 100644 index d9b9495ee72537bf14f3053c06eca65ccef4b552..0000000000000000000000000000000000000000 --- a/arkindex/users/migrations/0004_internal_bool.py +++ /dev/null @@ -1,47 +0,0 @@ -# Generated by Django 2.2.13 on 2020-07-21 08:00 - -from django.conf import settings -from django.db import migrations, models - - -def group_to_bool(apps, schema_editor): - Group = apps.get_model('auth', 'Group') - if not Group.objects.exists(): - # Empty database - return - internal_group = Group.objects.get(id=settings.INTERNAL_GROUP_ID) - internal_group.users.all().update(is_internal=True) - internal_group.delete() - - -def bool_to_group(apps, schema_editor): - Group = apps.get_model('auth', 'Group') - User = apps.get_model('users', 'User') - try: - internal_group_id = settings.INTERNAL_GROUP_ID - except AttributeError: - internal_group_id = None - - assert isinstance(internal_group_id, int), 'settings.INTERNAL_GROUP_ID must be defined to roll users.0004 back' - - internal_group, _ = Group.objects.get_or_create(id=internal_group_id, defaults={'name': 'Internal'}) - internal_group.users.set(User.objects.filter(is_internal=True)) - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0003_user_selected_elements'), - ] - - operations = [ - migrations.AddField( - model_name='user', - name='is_internal', - field=models.BooleanField(default=False), - ), - migrations.RunPython( - group_to_bool, - reverse_code=bool_to_group, - ) - ] diff --git a/arkindex/users/migrations/0005_user_transkribus_email.py b/arkindex/users/migrations/0005_user_transkribus_email.py deleted file mode 100644 index ae38739bc3f71c5162fbfb0a27756ad89ffd5057..0000000000000000000000000000000000000000 --- a/arkindex/users/migrations/0005_user_transkribus_email.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 2.2.13 on 2020-08-05 07:24 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0004_internal_bool'), - ] - - operations = [ - migrations.AddField( - model_name='user', - name='transkribus_email', - field=models.EmailField(blank=True, max_length=255, null=True), - ), - ] diff --git a/arkindex/users/migrations/0006_update_group_and_membership.py b/arkindex/users/migrations/0006_update_group_and_membership.py deleted file mode 100644 index 32e19fc087f1f1f69cfaf1e9245eb32ce4c5cefc..0000000000000000000000000000000000000000 --- a/arkindex/users/migrations/0006_update_group_and_membership.py +++ /dev/null @@ -1,43 +0,0 @@ -# Generated by Django 3.1.3 on 2020-11-16 14:40 - -import uuid - -import django.db.models.deletion -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0005_user_transkribus_email'), - ] - - operations = [ - migrations.CreateModel( - name='Group', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('name', models.CharField(max_length=64)), - ('public', models.BooleanField(default=False)), - ], - ), - migrations.RemoveField( - model_name='user', - name='groups', - ), - migrations.CreateModel( - name='Membership', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('level', models.PositiveIntegerField(default=0, help_text='User privilege level.')), - ('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='memberships', to='users.group')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='memberships', to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.AddField( - model_name='group', - name='users', - field=models.ManyToManyField(related_name='groups', through='users.Membership', to=settings.AUTH_USER_MODEL), - ), - ] diff --git a/arkindex/users/migrations/0007_user_display_name.py b/arkindex/users/migrations/0007_user_display_name.py deleted file mode 100644 index f215bd45dae091cb51ea7b462260015da73b9942..0000000000000000000000000000000000000000 --- a/arkindex/users/migrations/0007_user_display_name.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 3.1.3 on 2020-11-18 15:42 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0006_update_group_and_membership'), - ] - - operations = [ - migrations.AddField( - model_name='user', - name='display_name', - field=models.CharField(default='default name', max_length=120), - preserve_default=False, - ) - ] diff --git a/arkindex/users/migrations/0008_populate_user_display_name.py b/arkindex/users/migrations/0008_populate_user_display_name.py deleted file mode 100644 index 187cc1596c26c922fff53e1f610360ed5d042c9b..0000000000000000000000000000000000000000 --- a/arkindex/users/migrations/0008_populate_user_display_name.py +++ /dev/null @@ -1,26 +0,0 @@ -from django.db import migrations - - -def get_name_from_email(apps, schema_editor): - User = apps.get_model('users', 'User') - for user in User.objects.filter(display_name='default name'): - try: - user.display_name = user.email.split('@')[0].replace('.', ' ').title() - except Exception: - user.display_name = user.email - user.save() - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0007_user_display_name'), - ] - - operations = [ - migrations.RunPython( - get_name_from_email, - reverse_code=migrations.RunPython.noop, - elidable=True - ) - ] diff --git a/arkindex/users/migrations/0009_membership_uuid_and_validation.py b/arkindex/users/migrations/0009_membership_uuid_and_validation.py deleted file mode 100644 index a54857f9c07224f5be7b9fb1aedd743a1e5794c0..0000000000000000000000000000000000000000 --- a/arkindex/users/migrations/0009_membership_uuid_and_validation.py +++ /dev/null @@ -1,42 +0,0 @@ -# Generated by Django 3.1.3 on 2020-11-24 13:30 - -import uuid - -import django -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0008_populate_user_display_name'), - ] - - operations = [ - # Drop membership table and re-create it - migrations.DeleteModel( - name='Membership', - ), - migrations.RemoveField( - model_name='group', - name='users', - ), - migrations.CreateModel( - name='Membership', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('level', models.PositiveIntegerField(help_text='User privilege level.', validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100)])), - ('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='memberships', to='users.group')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='memberships', to=settings.AUTH_USER_MODEL)), - ], - options={ - 'unique_together': {('user', 'group')}, - }, - ), - migrations.AddField( - model_name='group', - name='users', - field=models.ManyToManyField(related_name='groups', through='users.Membership', to=settings.AUTH_USER_MODEL), - ), - ] diff --git a/arkindex/users/migrations/0010_right_gfk.py b/arkindex/users/migrations/0010_right_gfk.py deleted file mode 100644 index 956364df2142a13ff4f45d02e43c89a1858884a0..0000000000000000000000000000000000000000 --- a/arkindex/users/migrations/0010_right_gfk.py +++ /dev/null @@ -1,53 +0,0 @@ -# Generated by Django 3.1.3 on 2020-12-09 08:51 - -import uuid - -import django.core.validators -import django.db.models.deletion -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('contenttypes', '0002_remove_content_type_name'), - ('users', '0009_membership_uuid_and_validation'), - ] - - operations = [ - migrations.CreateModel( - name='Right', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('content_id', models.UUIDField(editable=False)), - ('level', models.PositiveIntegerField(help_text='Maximum privilege level.', validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100)])), - ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')), - ], - ), - migrations.RemoveField( - model_name='group', - name='users', - ), - migrations.DeleteModel( - name='Membership', - ), - migrations.AddField( - model_name='right', - name='group', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='rights', to='users.group'), - ), - migrations.AddField( - model_name='right', - name='user', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='rights', to=settings.AUTH_USER_MODEL), - ), - migrations.AddConstraint( - model_name='right', - constraint=models.UniqueConstraint(fields=('user', 'group', 'content_id', 'content_type'), name='right_unique_target'), - ), - migrations.AddConstraint( - model_name='right', - constraint=models.CheckConstraint(check=models.Q(models.Q(('group_id__isnull', False), ('user_id__isnull', True)), models.Q(('group_id__isnull', True), ('user_id__isnull', False)), _connector='OR'), name='user_xor_group'), - ), - ] diff --git a/arkindex/users/migrations/0011_corpus_rights.py b/arkindex/users/migrations/0011_corpus_rights.py deleted file mode 100644 index 81397ab3dbea77f711f293d0d6db3782fea2f052..0000000000000000000000000000000000000000 --- a/arkindex/users/migrations/0011_corpus_rights.py +++ /dev/null @@ -1,42 +0,0 @@ -from django.contrib.contenttypes.models import ContentType -from django.db import migrations - -import arkindex.users.models - - -def create_rights(apps, schema_editor): - CorpusRight = apps.get_model('users', 'CorpusRight') - Right = apps.get_model('users', 'Right') - Corpus = apps.get_model('documents', 'Corpus') - corpus_type_id = ContentType.objects.get_for_model(Corpus).id - # We should user the get_for_model method - new_rights = [] - for corpus_right in CorpusRight.objects.all(): - RoleEnum = arkindex.users.models.Role - role = RoleEnum.Guest - if corpus_right.can_write: - role = RoleEnum.Contributor - if corpus_right.can_admin: - role = RoleEnum.Admin - new_rights.append(Right( - user_id=corpus_right.user_id, - content_id=corpus_right.corpus_id, - content_type_id=corpus_type_id, - level=role.value - )) - Right.objects.bulk_create(new_rights) - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0010_right_gfk'), - ] - - operations = [ - migrations.RunPython( - create_rights, - reverse_code=migrations.RunPython.noop, - elidable=True - ) - ] diff --git a/arkindex/users/migrations/0012_drop_corpus_right.py b/arkindex/users/migrations/0012_drop_corpus_right.py deleted file mode 100644 index 383d0945b5ffa5c312a7d457d98dc30444fb071a..0000000000000000000000000000000000000000 --- a/arkindex/users/migrations/0012_drop_corpus_right.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 3.1.3 on 2020-12-18 14:58 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0011_corpus_rights'), - ] - - operations = [ - migrations.RemoveField( - model_name='user', - name='corpus', - ), - migrations.DeleteModel( - name='CorpusRight', - ), - ] diff --git a/arkindex/users/migrations/0013_user_created_updated_fields.py b/arkindex/users/migrations/0013_user_created_updated_fields.py deleted file mode 100644 index 962bd31950eda2fb307ba9dba8bb64449b4f6152..0000000000000000000000000000000000000000 --- a/arkindex/users/migrations/0013_user_created_updated_fields.py +++ /dev/null @@ -1,55 +0,0 @@ -# Generated by Django 3.1.7 on 2021-05-04 09:10 - -import django.utils.timezone -from django.contrib.contenttypes.models import ContentType -from django.db import migrations, models - -from arkindex.users.models import Role - - -def update_creation_date(apps, schema_editor): - """ - Update User creation date to his "My Project" creation date (when the project is available) - instead of default timezone.now - """ - db_alias = schema_editor.connection.alias - Corpus = apps.get_model('documents', 'Corpus') - corpus_content_type = ContentType.objects.get_for_model(Corpus) - Right = apps.get_model('users', 'Right') - User = apps.get_model('users', 'User') - - to_update = [] - corpora = Corpus.objects.using(db_alias).filter(name='My Project') - for corpus in corpora: - try: - admin = Right.objects.using(db_alias).filter(content_type=corpus_content_type.id, content_id=corpus.id).get(level__gte=Role.Admin.value, user__isnull=False).user - admin.created = corpus.created - to_update.append(admin) - except (Right.DoesNotExist, Right.MultipleObjectsReturned): - continue - User.objects.using(db_alias).bulk_update(to_update, ['created']) - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0012_drop_corpus_right'), - ] - - operations = [ - migrations.AddField( - model_name='user', - name='created', - field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now), - preserve_default=False, - ), - migrations.AddField( - model_name='user', - name='updated', - field=models.DateTimeField(auto_now=True), - ), - migrations.RunPython( - update_creation_date, - reverse_code=migrations.RunPython.noop, - ) - ] diff --git a/arkindex/users/migrations/0014_alter_oauthcredentials_options.py b/arkindex/users/migrations/0014_alter_oauthcredentials_options.py deleted file mode 100644 index 08d287b173299fce8cc89c19ce5f59b837e14059..0000000000000000000000000000000000000000 --- a/arkindex/users/migrations/0014_alter_oauthcredentials_options.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 3.2.6 on 2021-11-18 13:16 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0013_user_created_updated_fields'), - ] - - operations = [ - migrations.AlterModelOptions( - name='oauthcredentials', - options={'verbose_name': 'OAuth credentials', 'verbose_name_plural': 'OAuth credentials'}, - ), - ] diff --git a/arkindex/users/migrations/0015_oauthcredentials_provider_choices.py b/arkindex/users/migrations/0015_oauthcredentials_provider_choices.py deleted file mode 100644 index 086f36f1987045c29f80dc4a32c7115798a83e0c..0000000000000000000000000000000000000000 --- a/arkindex/users/migrations/0015_oauthcredentials_provider_choices.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.2.6 on 2021-11-26 14:47 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0014_alter_oauthcredentials_options'), - ] - - operations = [ - migrations.AlterField( - model_name='oauthcredentials', - name='provider_name', - field=models.CharField(choices=[('gitlab', 'GitLab')], max_length=50), - ), - ] diff --git a/arkindex/users/migrations/0016_alter_user_email_user_email_unique.py b/arkindex/users/migrations/0016_alter_user_email_user_email_unique.py deleted file mode 100644 index a92635ff8773b791136df9b55e88d9e4bbe22ff0..0000000000000000000000000000000000000000 --- a/arkindex/users/migrations/0016_alter_user_email_user_email_unique.py +++ /dev/null @@ -1,34 +0,0 @@ -# Generated by Django 4.0.2 on 2022-02-28 11:36 - -from django.contrib.postgres.operations import CreateCollation -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0015_oauthcredentials_provider_choices'), - ] - - operations = [ - migrations.AlterField( - model_name='user', - name='email', - field=models.EmailField(max_length=255, verbose_name='email address'), - ), - migrations.AddConstraint( - model_name='user', - constraint=models.UniqueConstraint(fields=('email',), name='email_unique'), - ), - CreateCollation( - 'case_insensitive', - provider='icu', - locale='und-u-ks-level2', - deterministic=False, - ), - migrations.AlterField( - model_name='user', - name='email', - field=models.EmailField(db_collation='case_insensitive', max_length=255, verbose_name='email address'), - ), - ] diff --git a/arkindex/users/migrations/0017_right_unique_constraints.py b/arkindex/users/migrations/0017_right_unique_constraints.py deleted file mode 100644 index 57b3276b592e77722e798c4cbe462c5740425d1e..0000000000000000000000000000000000000000 --- a/arkindex/users/migrations/0017_right_unique_constraints.py +++ /dev/null @@ -1,68 +0,0 @@ -# Generated by Django 4.0.1 on 2022-04-08 13:50 - -from django.db import migrations, models - -FORWARD_SQL = [ - """ - WITH duplicate_rights AS ( - SELECT id, ROW_NUMBER() OVER ( - PARTITION BY group_id, content_type_id, content_id - ORDER BY level DESC - ) AS number - FROM users_right - WHERE user_id IS NULL - ) - DELETE FROM users_right - USING duplicate_rights - WHERE duplicate_rights.id = users_right.id - AND duplicate_rights.number > 1 - """, - """ - WITH duplicate_rights AS ( - SELECT id, ROW_NUMBER() OVER ( - PARTITION BY user_id, content_type_id, content_id - ORDER BY level DESC - ) AS number - FROM users_right - WHERE group_id IS NULL - ) - DELETE FROM users_right - USING duplicate_rights - WHERE duplicate_rights.id = users_right.id - AND duplicate_rights.number > 1 - """ -] - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0016_alter_user_email_user_email_unique'), - ] - - operations = [ - migrations.RemoveConstraint( - model_name='right', - name='right_unique_target', - ), - migrations.RunSQL( - sql=FORWARD_SQL, - reverse_sql=migrations.RunSQL.noop, - ), - migrations.AddConstraint( - model_name='right', - constraint=models.UniqueConstraint( - condition=models.Q(user__isnull=False), - fields=('user', 'content_id', 'content_type'), - name='right_user_unique_target', - ), - ), - migrations.AddConstraint( - model_name='right', - constraint=models.UniqueConstraint( - condition=models.Q(group__isnull=False), - fields=('group', 'content_id', 'content_type'), - name='right_group_unique_target', - ), - ), - ] diff --git a/arkindex/users/migrations/0018_remove_oauthcredentials_provider_name.py b/arkindex/users/migrations/0018_remove_oauthcredentials_provider_name.py deleted file mode 100644 index d1797c60ef1890c9a3a496753a654879c390520b..0000000000000000000000000000000000000000 --- a/arkindex/users/migrations/0018_remove_oauthcredentials_provider_name.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 4.0.7 on 2022-10-18 15:51 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0017_right_unique_constraints'), - ] - - operations = [ - migrations.RemoveField( - model_name='oauthcredentials', - name='provider_name', - ), - ] diff --git a/arkindex/users/migrations/0019_group_use_in_new_project.py b/arkindex/users/migrations/0019_group_use_in_new_project.py deleted file mode 100644 index 0d923844828a43b6a67d0251537c3bd176f56ef7..0000000000000000000000000000000000000000 --- a/arkindex/users/migrations/0019_group_use_in_new_project.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.1.7 on 2023-03-13 12:48 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("users", "0018_remove_oauthcredentials_provider_name"), - ] - - operations = [ - migrations.AddField( - model_name="group", - name="use_in_new_project", - field=models.BooleanField(default=False), - ), - ] diff --git a/arkindex/users/migrations/0020_remove_user_is_internal.py b/arkindex/users/migrations/0020_remove_user_is_internal.py deleted file mode 100644 index 65573ae5960a8941275d32974f1f7fe02e097b65..0000000000000000000000000000000000000000 --- a/arkindex/users/migrations/0020_remove_user_is_internal.py +++ /dev/null @@ -1,29 +0,0 @@ -# Generated by Django 4.1.7 on 2023-03-09 15:55 - -from django.db import migrations - - -def promote_internal_to_admin(apps, schema_editor): - User = apps.get_model('users', 'User') - if User.objects.filter(is_internal=True).exists(): - print('\nThe following internal users will be promoted to admins:') - print('\n'.join(User.objects.filter(is_internal=True).values_list('email', flat=True))) - User.objects.filter(is_internal=True).update(is_admin=True) - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0019_group_use_in_new_project'), - ] - - operations = [ - migrations.RunPython( - promote_internal_to_admin, - reverse_code=migrations.RunPython.noop, - ), - migrations.RemoveField( - model_name='user', - name='is_internal', - ), - ]