diff --git a/openslides/motions/migrations/0011_motion_version.py b/openslides/motions/migrations/0011_motion_version.py deleted file mode 100644 index f07fd9404..000000000 --- a/openslides/motions/migrations/0011_motion_version.py +++ /dev/null @@ -1,107 +0,0 @@ -# Generated by Django 2.1 on 2018-08-31 13:17 - -import django.db.models.deletion -import jsonfield.encoder -import jsonfield.fields -from django.db import migrations, models - - -def copy_motion_version_content_to_motion(apps, schema_editor): - """ - Move all motion version content of the active version to the motion. - """ - Motion = apps.get_model("motions", "Motion") - - for motion in Motion.objects.all(): - motion.title = motion.active_version.title - motion.text = motion.active_version.text - motion.reason = motion.active_version.reason - motion.modified_final_version = motion.active_version.modified_final_version - motion.amendment_paragraphs = motion.active_version.amendment_paragraphs - motion.save(skip_autoupdate=True) - - -def migrate_active_change_recommendations(apps, schema_editor): - """ - Delete all change recommendation of motion versions, that are not active. For active - change recommendations the motion id will be set. - """ - MotionChangeRecommendation = apps.get_model("motions", "MotionChangeRecommendation") - to_delete = [] - for cr in MotionChangeRecommendation.objects.all(): - # chack if version id matches the active version of the motion - if cr.motion_version.id == cr.motion_version.motion.active_version.id: - cr.motion = cr.motion_version.motion - cr.save(skip_autoupdate=True) - else: - to_delete.append(cr) - - # delete non active change recommendations - for cr in to_delete: - cr.delete(skip_autoupdate=True) - - -class Migration(migrations.Migration): - - dependencies = [("motions", "0010_auto_20180822_1042")] - - operations = [ - # Create new fields. Title and Text have empty defaults, but the values - # should be overwritten by copy_motion_version_content_to_motion. In the next - # migration file these defaults are removed. - migrations.AddField( - model_name="motion", - name="title", - field=models.CharField(max_length=255, default=""), - ), - migrations.AddField( - model_name="motion", name="text", field=models.TextField(default="") - ), - migrations.AddField( - model_name="motion", - name="reason", - field=models.TextField(blank=True, null=True), - ), - migrations.AddField( - model_name="motion", - name="modified_final_version", - field=models.TextField(blank=True, null=True), - ), - migrations.AddField( - model_name="motion", - name="amendment_paragraphs", - field=jsonfield.fields.JSONField( - dump_kwargs={ - "cls": jsonfield.encoder.JSONEncoder, - "separators": (",", ":"), - }, - load_kwargs={}, - null=True, - ), - ), - # Copy old motion version data - migrations.RunPython(copy_motion_version_content_to_motion), - # Change recommendations - migrations.AddField( - model_name="motionchangerecommendation", - name="motion", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - null=True, # This is reverted in the next migration - related_name="change_recommendations", - to="motions.Motion", - ), - ), - migrations.RunPython(migrate_active_change_recommendations), - migrations.RemoveField( - model_name="motionchangerecommendation", name="motion_version" - ), - # remove motion version references from motion and state. - migrations.RemoveField(model_name="motion", name="active_version"), - migrations.AlterUniqueTogether(name="motionversion", unique_together=set()), - migrations.RemoveField(model_name="motionversion", name="motion"), - migrations.RemoveField(model_name="state", name="leave_old_version_active"), - migrations.RemoveField(model_name="state", name="versioning"), - # Delete motion version. - migrations.DeleteModel(name="MotionVersion"), - ] diff --git a/openslides/motions/migrations/0011_motion_version_1.py b/openslides/motions/migrations/0011_motion_version_1.py new file mode 100644 index 000000000..6919cfd70 --- /dev/null +++ b/openslides/motions/migrations/0011_motion_version_1.py @@ -0,0 +1,83 @@ +# Generated by Django 2.1 on 2018-08-31 13:17 + +import django.db.models.deletion +import jsonfield.encoder +import jsonfield.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + """ + This is a series of logically connected migrations that needs to be in separate + files. See issue #4266 and https://docs.djangoproject.com/en/2.1/ref/migration-operations/ + + `On databases that do support DDL transactions (SQLite and PostgreSQL), RunPython operations + do not have any transactions automatically added besides the transactions created for + each migration. Thus, on PostgreSQL, for example, you should avoid combining schema + changes and RunPython operations in the same migration or you may hit errors like + OperationalError: cannot ALTER TABLE "mytable" because it has pending trigger events.` + + Because we need some scheam changes, copy data, schema changes, copy data, ..., we need + to split this up. + + Goal: Remove the motion_version. Move all fields to the motion model and keep all data. + This also affects change recommendations, that are linked to versions, not motions. All + change recommendations that are connected to active motions versions must be kept, too. + + + What is done (migration file): + - Create Title, Text, ... fields and new foreign key from CRs to motion (1) + - Copy data from active version to the motion model (2) + - Migrate change recommendations (2) + - Cleanup1: remove all unnecessary fields and delete motion version model (3) + - Cleanup2: alter some other fields that must be in a seperate migration file (Idk why..) (4) + """ + + dependencies = [("motions", "0010_auto_20180822_1042")] + + operations = [ + # Create new fields. Title and Text have empty defaults, but the values + # should be overwritten by copy_motion_version_content_to_motion in migration step (2). + # In the last migration step these defaults are removed. + migrations.AddField( + model_name="motion", + name="title", + field=models.CharField(max_length=255, default=""), + ), + migrations.AddField( + model_name="motion", name="text", field=models.TextField(default="") + ), + migrations.AddField( + model_name="motion", + name="reason", + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name="motion", + name="modified_final_version", + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name="motion", + name="amendment_paragraphs", + field=jsonfield.fields.JSONField( + dump_kwargs={ + "cls": jsonfield.encoder.JSONEncoder, + "separators": (",", ":"), + }, + load_kwargs={}, + null=True, + ), + ), + # Link change recommendations to motions directly + migrations.AddField( + model_name="motionchangerecommendation", + name="motion", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + null=True, # This is reverted in the next migration + related_name="change_recommendations", + to="motions.Motion", + ), + ), + ] diff --git a/openslides/motions/migrations/0011_motion_version_2.py b/openslides/motions/migrations/0011_motion_version_2.py new file mode 100644 index 000000000..1026e2308 --- /dev/null +++ b/openslides/motions/migrations/0011_motion_version_2.py @@ -0,0 +1,49 @@ +# Generated by Django 2.1 on 2018-08-31 13:17 + +from django.db import migrations + + +def copy_motion_version_content_to_motion(apps, schema_editor): + """ + Move all motion version content of the active version to the motion. + """ + Motion = apps.get_model("motions", "Motion") + + for motion in Motion.objects.all(): + motion.title = motion.active_version.title + motion.text = motion.active_version.text + motion.reason = motion.active_version.reason + motion.modified_final_version = motion.active_version.modified_final_version + motion.amendment_paragraphs = motion.active_version.amendment_paragraphs + motion.save(skip_autoupdate=True) + + +def migrate_active_change_recommendations(apps, schema_editor): + """ + Delete all change recommendation of motion versions, that are not active. For active + change recommendations the motion id will be set. + """ + MotionChangeRecommendation = apps.get_model("motions", "MotionChangeRecommendation") + to_delete = [] + for cr in MotionChangeRecommendation.objects.all(): + # chack if version id matches the active version of the motion + if cr.motion_version.id == cr.motion_version.motion.active_version.id: + cr.motion = cr.motion_version.motion + cr.save(skip_autoupdate=True) + else: + to_delete.append(cr) + + # delete non active change recommendations + for cr in to_delete: + cr.delete(skip_autoupdate=True) + + +class Migration(migrations.Migration): + + dependencies = [("motions", "0011_motion_version_1")] + + operations = [ + # Copy old motion version data + migrations.RunPython(copy_motion_version_content_to_motion), + migrations.RunPython(migrate_active_change_recommendations), + ] diff --git a/openslides/motions/migrations/0011_motion_version_3.py b/openslides/motions/migrations/0011_motion_version_3.py new file mode 100644 index 000000000..fb803ad3d --- /dev/null +++ b/openslides/motions/migrations/0011_motion_version_3.py @@ -0,0 +1,23 @@ +# Generated by Django 2.1 on 2018-08-31 13:17 + +from django.db import migrations + + +class Migration(migrations.Migration): + """ Cleanup 1 """ + + dependencies = [("motions", "0011_motion_version_2")] + + operations = [ + migrations.RemoveField( + model_name="motionchangerecommendation", name="motion_version" + ), + # remove motion version references from motion and state. + migrations.RemoveField(model_name="motion", name="active_version"), + migrations.AlterUniqueTogether(name="motionversion", unique_together=set()), + migrations.RemoveField(model_name="motionversion", name="motion"), + migrations.RemoveField(model_name="state", name="leave_old_version_active"), + migrations.RemoveField(model_name="state", name="versioning"), + # Delete motion version. + migrations.DeleteModel(name="MotionVersion"), + ] diff --git a/openslides/motions/migrations/0011_motion_version_4.py b/openslides/motions/migrations/0011_motion_version_4.py new file mode 100644 index 000000000..9855ac4d3 --- /dev/null +++ b/openslides/motions/migrations/0011_motion_version_4.py @@ -0,0 +1,29 @@ +# Generated by Django 2.1 on 2018-08-31 13:17 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + """ Cleanup 2 """ + + dependencies = [("motions", "0011_motion_version_3")] + + operations = [ + # Cleanup from last migration. Somehow cannot be done there. + migrations.AlterField( # remove default='' + model_name="motion", name="text", field=models.TextField() + ), + migrations.AlterField( # remove default='' + model_name="motion", name="title", field=models.CharField(max_length=255) + ), + migrations.AlterField( # remove null=True + model_name="motionchangerecommendation", + name="motion", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="change_recommendations", + to="motions.Motion", + ), + ), + ] diff --git a/openslides/motions/migrations/0012_motion_comments.py b/openslides/motions/migrations/0012_motion_comments.py index 761f3c8e4..11e7291bb 100644 --- a/openslides/motions/migrations/0012_motion_comments.py +++ b/openslides/motions/migrations/0012_motion_comments.py @@ -93,25 +93,9 @@ def create_comment_sections_from_config_and_move_comments_to_own_model( class Migration(migrations.Migration): - dependencies = [("users", "0006_user_email"), ("motions", "0011_motion_version")] + dependencies = [("users", "0006_user_email"), ("motions", "0011_motion_version_4")] operations = [ - # Cleanup from last migration. Somehow cannot be done there. - migrations.AlterField( # remove default='' - model_name="motion", name="text", field=models.TextField() - ), - migrations.AlterField( # remove default='' - model_name="motion", name="title", field=models.CharField(max_length=255) - ), - migrations.AlterField( # remove null=True - model_name="motionchangerecommendation", - name="motion", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="change_recommendations", - to="motions.Motion", - ), - ), # Add extension fields for former "special comments". No hack anymore.. migrations.AddField( model_name="motion",