From 55ba6aae197323727dad96bf7259a98e6237e98c Mon Sep 17 00:00:00 2001 From: Richard Roggenkemper Date: Thu, 7 Sep 2023 14:15:47 -0700 Subject: [PATCH 1/9] re introduce migratio n --- .../backup/model_dependencies/detailed.json | 4 ++ fixtures/backup/model_dependencies/flat.json | 1 + migrations_lockfile.txt | 2 +- .../0546_re_add_team_to_groupsubscription.py | 50 +++++++++++++++++++ src/sentry/models/groupsubscription.py | 10 +++- 5 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 src/sentry/migrations/0546_re_add_team_to_groupsubscription.py diff --git a/fixtures/backup/model_dependencies/detailed.json b/fixtures/backup/model_dependencies/detailed.json index 54d592c12a3e98..c8f3f0dfcc5820 100644 --- a/fixtures/backup/model_dependencies/detailed.json +++ b/fixtures/backup/model_dependencies/detailed.json @@ -1471,6 +1471,10 @@ "kind": "FlexibleForeignKey", "model": "sentry.Project" }, + "team": { + "kind": "FlexibleForeignKey", + "model": "sentry.Team" + }, "user_id": { "kind": "HybridCloudForeignKey", "model": "sentry.User" diff --git a/fixtures/backup/model_dependencies/flat.json b/fixtures/backup/model_dependencies/flat.json index 43e164ce584fb9..9ddb3ed5119689 100644 --- a/fixtures/backup/model_dependencies/flat.json +++ b/fixtures/backup/model_dependencies/flat.json @@ -333,6 +333,7 @@ "sentry.GroupSubscription": [ "sentry.Group", "sentry.Project", + "sentry.Team", "sentry.User" ], "sentry.GroupTombstone": [ diff --git a/migrations_lockfile.txt b/migrations_lockfile.txt index 6104ff0fb36c69..ecffd9a191b159 100644 --- a/migrations_lockfile.txt +++ b/migrations_lockfile.txt @@ -8,5 +8,5 @@ will then be regenerated, and you should be able to merge without conflicts. feedback: 0001_feedback nodestore: 0002_nodestore_no_dictfield replays: 0003_add_size_to_recording_segment -sentry: 0545_remove_groupsubscription_columns +sentry: 0546_re_add_team_to_groupsubscription social_auth: 0002_default_auto_field diff --git a/src/sentry/migrations/0546_re_add_team_to_groupsubscription.py b/src/sentry/migrations/0546_re_add_team_to_groupsubscription.py new file mode 100644 index 00000000000000..1c967d4a36da62 --- /dev/null +++ b/src/sentry/migrations/0546_re_add_team_to_groupsubscription.py @@ -0,0 +1,50 @@ +# Generated by Django 3.2.20 on 2023-09-07 21:15 + +import django.db.models.deletion +from django.db import migrations, models + +import sentry.db.models.fields.foreignkey +from sentry.new_migrations.migrations import CheckedMigration + + +class Migration(CheckedMigration): + # This flag is used to mark that a migration shouldn't be automatically run in production. For + # the most part, this should only be used for operations where it's safe to run the migration + # after your code has deployed. So this should not be used for most operations that alter the + # schema of a table. + # Here are some things that make sense to mark as dangerous: + # - Large data migrations. Typically we want these to be run manually by ops so that they can + # be monitored and not block the deploy for a long period of time while they run. + # - Adding indexes to large tables. Since this can take a long time, we'd generally prefer to + # have ops run this and not block the deploy. Note that while adding an index is a schema + # change, it's completely safe to run the operation after the code has deployed. + is_dangerous = False + + dependencies = [ + ("sentry", "0545_remove_groupsubscription_columns"), + ] + + operations = [ + migrations.AddField( + model_name="groupsubscription", + name="team", + field=sentry.db.models.fields.foreignkey.FlexibleForeignKey( + null=True, on_delete=django.db.models.deletion.CASCADE, to="sentry.team" + ), + ), + migrations.AlterUniqueTogether( + name="groupsubscription", + unique_together={("group", "team"), ("group", "user_id")}, + ), + migrations.AddConstraint( + model_name="groupsubscription", + constraint=models.CheckConstraint( + check=models.Q( + models.Q(("team_id__isnull", False), ("user_id__isnull", True)), + models.Q(("team_id__isnull", True), ("user_id__isnull", False)), + _connector="OR", + ), + name="subscription_team_or_user_check", + ), + ), + ] diff --git a/src/sentry/models/groupsubscription.py b/src/sentry/models/groupsubscription.py index 336cb6d6a76f4e..08f355707e7dce 100644 --- a/src/sentry/models/groupsubscription.py +++ b/src/sentry/models/groupsubscription.py @@ -179,6 +179,7 @@ class GroupSubscription(Model): project = FlexibleForeignKey("sentry.Project", related_name="subscription_set") group = FlexibleForeignKey("sentry.Group", related_name="subscription_set") user_id = HybridCloudForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete="CASCADE") + team = FlexibleForeignKey("sentry.Team", null=True, db_index=True, on_delete=models.CASCADE) is_active = models.BooleanField(default=True) reason = BoundedPositiveIntegerField(default=GroupSubscriptionReason.unknown) date_added = models.DateTimeField(default=timezone.now, null=True) @@ -188,6 +189,13 @@ class GroupSubscription(Model): class Meta: app_label = "sentry" db_table = "sentry_groupsubscription" - unique_together = (("group", "user_id"),) + unique_together = (("group", "user_id"), ("group", "team")) + constraints = [ + models.CheckConstraint( + check=models.Q(team_id__isnull=False, user_id__isnull=True) + | models.Q(team_id__isnull=True, user_id__isnull=False), + name="subscription_team_or_user_check", + ) + ] __repr__ = sane_repr("project_id", "group_id", "user_id") From 52beddb0cad5c1ec06ac1373c9de0d46a1558d90 Mon Sep 17 00:00:00 2001 From: Richard Roggenkemper Date: Thu, 7 Sep 2023 14:22:46 -0700 Subject: [PATCH 2/9] make dangerous --- src/sentry/migrations/0546_re_add_team_to_groupsubscription.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sentry/migrations/0546_re_add_team_to_groupsubscription.py b/src/sentry/migrations/0546_re_add_team_to_groupsubscription.py index 1c967d4a36da62..e3bce471127e58 100644 --- a/src/sentry/migrations/0546_re_add_team_to_groupsubscription.py +++ b/src/sentry/migrations/0546_re_add_team_to_groupsubscription.py @@ -18,7 +18,7 @@ class Migration(CheckedMigration): # - Adding indexes to large tables. Since this can take a long time, we'd generally prefer to # have ops run this and not block the deploy. Note that while adding an index is a schema # change, it's completely safe to run the operation after the code has deployed. - is_dangerous = False + is_dangerous = True dependencies = [ ("sentry", "0545_remove_groupsubscription_columns"), From aa6e2a20f49e33b0f667be90a3d0a1c1ec058cf1 Mon Sep 17 00:00:00 2001 From: Richard Roggenkemper Date: Thu, 7 Sep 2023 15:33:33 -0700 Subject: [PATCH 3/9] make user nullable --- .../migrations/0546_re_add_team_to_groupsubscription.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/sentry/migrations/0546_re_add_team_to_groupsubscription.py b/src/sentry/migrations/0546_re_add_team_to_groupsubscription.py index e3bce471127e58..9180fe47f142a1 100644 --- a/src/sentry/migrations/0546_re_add_team_to_groupsubscription.py +++ b/src/sentry/migrations/0546_re_add_team_to_groupsubscription.py @@ -36,6 +36,13 @@ class Migration(CheckedMigration): name="groupsubscription", unique_together={("group", "team"), ("group", "user_id")}, ), + migrations.AlterField( + model_name="groupsubscription", + name="user_id", + field=sentry.db.models.fields.hybrid_cloud_foreign_key.HybridCloudForeignKey( + "sentry.User", db_index=True, null=True, on_delete="CASCADE" + ), + ), migrations.AddConstraint( model_name="groupsubscription", constraint=models.CheckConstraint( From d2eda09ad814a33e16b0c67e629d079e9c810087 Mon Sep 17 00:00:00 2001 From: Richard Roggenkemper Date: Fri, 8 Sep 2023 09:38:42 -0700 Subject: [PATCH 4/9] add user check --- migrations_lockfile.txt | 2 +- .../0546_re_add_team_to_groupsubscription.py | 57 ------------------- 2 files changed, 1 insertion(+), 58 deletions(-) delete mode 100644 src/sentry/migrations/0546_re_add_team_to_groupsubscription.py diff --git a/migrations_lockfile.txt b/migrations_lockfile.txt index 1840af85c8b8b9..3e5b8069934588 100644 --- a/migrations_lockfile.txt +++ b/migrations_lockfile.txt @@ -8,5 +8,5 @@ will then be regenerated, and you should be able to merge without conflicts. feedback: 0001_feedback nodestore: 0002_nodestore_no_dictfield replays: 0003_add_size_to_recording_segment -sentry: 0544_remove_groupsubscription_columns +sentry: 0545_re_add_groupsubscription_columns social_auth: 0002_default_auto_field diff --git a/src/sentry/migrations/0546_re_add_team_to_groupsubscription.py b/src/sentry/migrations/0546_re_add_team_to_groupsubscription.py deleted file mode 100644 index 9180fe47f142a1..00000000000000 --- a/src/sentry/migrations/0546_re_add_team_to_groupsubscription.py +++ /dev/null @@ -1,57 +0,0 @@ -# Generated by Django 3.2.20 on 2023-09-07 21:15 - -import django.db.models.deletion -from django.db import migrations, models - -import sentry.db.models.fields.foreignkey -from sentry.new_migrations.migrations import CheckedMigration - - -class Migration(CheckedMigration): - # This flag is used to mark that a migration shouldn't be automatically run in production. For - # the most part, this should only be used for operations where it's safe to run the migration - # after your code has deployed. So this should not be used for most operations that alter the - # schema of a table. - # Here are some things that make sense to mark as dangerous: - # - Large data migrations. Typically we want these to be run manually by ops so that they can - # be monitored and not block the deploy for a long period of time while they run. - # - Adding indexes to large tables. Since this can take a long time, we'd generally prefer to - # have ops run this and not block the deploy. Note that while adding an index is a schema - # change, it's completely safe to run the operation after the code has deployed. - is_dangerous = True - - dependencies = [ - ("sentry", "0545_remove_groupsubscription_columns"), - ] - - operations = [ - migrations.AddField( - model_name="groupsubscription", - name="team", - field=sentry.db.models.fields.foreignkey.FlexibleForeignKey( - null=True, on_delete=django.db.models.deletion.CASCADE, to="sentry.team" - ), - ), - migrations.AlterUniqueTogether( - name="groupsubscription", - unique_together={("group", "team"), ("group", "user_id")}, - ), - migrations.AlterField( - model_name="groupsubscription", - name="user_id", - field=sentry.db.models.fields.hybrid_cloud_foreign_key.HybridCloudForeignKey( - "sentry.User", db_index=True, null=True, on_delete="CASCADE" - ), - ), - migrations.AddConstraint( - model_name="groupsubscription", - constraint=models.CheckConstraint( - check=models.Q( - models.Q(("team_id__isnull", False), ("user_id__isnull", True)), - models.Q(("team_id__isnull", True), ("user_id__isnull", False)), - _connector="OR", - ), - name="subscription_team_or_user_check", - ), - ), - ] From b93f41c429216648d4a62c805eb38a2b0d633c17 Mon Sep 17 00:00:00 2001 From: Richard Roggenkemper Date: Fri, 8 Sep 2023 09:38:57 -0700 Subject: [PATCH 5/9] updated migration --- .../0545_re_add_groupsubscription_columns.py | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/sentry/migrations/0545_re_add_groupsubscription_columns.py diff --git a/src/sentry/migrations/0545_re_add_groupsubscription_columns.py b/src/sentry/migrations/0545_re_add_groupsubscription_columns.py new file mode 100644 index 00000000000000..d2e702570700c3 --- /dev/null +++ b/src/sentry/migrations/0545_re_add_groupsubscription_columns.py @@ -0,0 +1,57 @@ +# Generated by Django 3.2.20 on 2023-09-08 16:19 + +import django.db.models.deletion +from django.db import migrations, models + +import sentry.db.models.fields.foreignkey +from sentry.new_migrations.migrations import CheckedMigration + + +class Migration(CheckedMigration): + # This flag is used to mark that a migration shouldn't be automatically run in production. For + # the most part, this should only be used for operations where it's safe to run the migration + # after your code has deployed. So this should not be used for most operations that alter the + # schema of a table. + # Here are some things that make sense to mark as dangerous: + # - Large data migrations. Typically we want these to be run manually by ops so that they can + # be monitored and not block the deploy for a long period of time while they run. + # - Adding indexes to large tables. Since this can take a long time, we'd generally prefer to + # have ops run this and not block the deploy. Note that while adding an index is a schema + # change, it's completely safe to run the operation after the code has deployed. + is_dangerous = True + + dependencies = [ + ("sentry", "0544_remove_groupsubscription_columns"), + ] + + operations = [ + migrations.AddField( + model_name="groupsubscription", + name="team", + field=sentry.db.models.fields.foreignkey.FlexibleForeignKey( + null=True, on_delete=django.db.models.deletion.CASCADE, to="sentry.team" + ), + ), + migrations.AlterField( + model_name="groupsubscription", + name="user_id", + field=sentry.db.models.fields.hybrid_cloud_foreign_key.HybridCloudForeignKey( + "sentry.User", db_index=True, null=True, on_delete="CASCADE" + ), + ), + migrations.AlterUniqueTogether( + name="groupsubscription", + unique_together={("group", "team"), ("group", "user_id")}, + ), + migrations.AddConstraint( + model_name="groupsubscription", + constraint=models.CheckConstraint( + check=models.Q( + models.Q(("team_id__isnull", False), ("user_id__isnull", True)), + models.Q(("team_id__isnull", True), ("user_id__isnull", False)), + _connector="OR", + ), + name="subscription_team_or_user_check", + ), + ), + ] From 6a8ebf9342654cbb74f1e4ab26edf10e631f8bdb Mon Sep 17 00:00:00 2001 From: Richard Roggenkemper Date: Fri, 8 Sep 2023 11:33:21 -0700 Subject: [PATCH 6/9] update user null --- .../0545_re_add_groupsubscription_columns.py | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/sentry/migrations/0545_re_add_groupsubscription_columns.py b/src/sentry/migrations/0545_re_add_groupsubscription_columns.py index d2e702570700c3..ee4fdb152bba6e 100644 --- a/src/sentry/migrations/0545_re_add_groupsubscription_columns.py +++ b/src/sentry/migrations/0545_re_add_groupsubscription_columns.py @@ -32,12 +32,27 @@ class Migration(CheckedMigration): null=True, on_delete=django.db.models.deletion.CASCADE, to="sentry.team" ), ), - migrations.AlterField( - model_name="groupsubscription", - name="user_id", - field=sentry.db.models.fields.hybrid_cloud_foreign_key.HybridCloudForeignKey( - "sentry.User", db_index=True, null=True, on_delete="CASCADE" - ), + migrations.SeparateDatabaseAndState( + state_operations=[ + migrations.AlterField( + model_name="groupsubscription", + name="user_id", + field=sentry.db.models.fields.hybrid_cloud_foreign_key.HybridCloudForeignKey( + "sentry.User", db_index=True, null=True, on_delete="CASCADE" + ), + ), + ], + database_operations=[ + migrations.RunSQL( + reverse_sql=""" + ALTER TABLE "sentry_groupsubscription" ALTER COLUMN "user_id" SET NOT NULL; + """, + sql=""" + ALTER TABLE "sentry_groupsubscription" ALTER COLUMN "user_id" DROP NOT NULL; + """, + hints={"tables": ["sentry_groupsubscription"]}, + ) + ], ), migrations.AlterUniqueTogether( name="groupsubscription", From 58dc285ac52563b4893f0593785303e35645d6a5 Mon Sep 17 00:00:00 2001 From: Richard Roggenkemper Date: Fri, 8 Sep 2023 11:37:24 -0700 Subject: [PATCH 7/9] update migration --- migrations_lockfile.txt | 2 +- ..._columns.py => 0546_re_add_groupsubscription_columns.py} | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/sentry/migrations/{0545_re_add_groupsubscription_columns.py => 0546_re_add_groupsubscription_columns.py} (95%) diff --git a/migrations_lockfile.txt b/migrations_lockfile.txt index c44d6fbe173bc0..7e2948b25514b0 100644 --- a/migrations_lockfile.txt +++ b/migrations_lockfile.txt @@ -8,5 +8,5 @@ will then be regenerated, and you should be able to merge without conflicts. feedback: 0001_feedback nodestore: 0002_nodestore_no_dictfield replays: 0003_add_size_to_recording_segment -sentry: 0545_add_last_verified_auth_ident_replica +sentry: 0546_re_add_groupsubscription_columns social_auth: 0002_default_auto_field diff --git a/src/sentry/migrations/0545_re_add_groupsubscription_columns.py b/src/sentry/migrations/0546_re_add_groupsubscription_columns.py similarity index 95% rename from src/sentry/migrations/0545_re_add_groupsubscription_columns.py rename to src/sentry/migrations/0546_re_add_groupsubscription_columns.py index ee4fdb152bba6e..b950558f548f64 100644 --- a/src/sentry/migrations/0545_re_add_groupsubscription_columns.py +++ b/src/sentry/migrations/0546_re_add_groupsubscription_columns.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.20 on 2023-09-08 16:19 +# Generated by Django 3.2.20 on 2023-09-08 18:36 import django.db.models.deletion from django.db import migrations, models @@ -18,10 +18,10 @@ class Migration(CheckedMigration): # - Adding indexes to large tables. Since this can take a long time, we'd generally prefer to # have ops run this and not block the deploy. Note that while adding an index is a schema # change, it's completely safe to run the operation after the code has deployed. - is_dangerous = True + is_dangerous = False dependencies = [ - ("sentry", "0544_remove_groupsubscription_columns"), + ("sentry", "0545_add_last_verified_auth_ident_replica"), ] operations = [ From debfdf2515990c5b410ea92193b510df3931d2af Mon Sep 17 00:00:00 2001 From: Richard Roggenkemper Date: Tue, 12 Sep 2023 09:51:42 -0700 Subject: [PATCH 8/9] new migration --- migrations_lockfile.txt | 2 +- ...tion_columns.py => 0549_re_add_groupsubscription_columns.py} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/sentry/migrations/{0546_re_add_groupsubscription_columns.py => 0549_re_add_groupsubscription_columns.py} (98%) diff --git a/migrations_lockfile.txt b/migrations_lockfile.txt index 75e770e826d6ab..279bd42b9a278a 100644 --- a/migrations_lockfile.txt +++ b/migrations_lockfile.txt @@ -8,5 +8,5 @@ will then be regenerated, and you should be able to merge without conflicts. feedback: 0001_feedback nodestore: 0002_nodestore_no_dictfield replays: 0003_add_size_to_recording_segment -sentry: 0548_add_is_unclaimed_boolean_to_user +sentry: 0549_re_add_groupsubscription_columns social_auth: 0002_default_auto_field diff --git a/src/sentry/migrations/0546_re_add_groupsubscription_columns.py b/src/sentry/migrations/0549_re_add_groupsubscription_columns.py similarity index 98% rename from src/sentry/migrations/0546_re_add_groupsubscription_columns.py rename to src/sentry/migrations/0549_re_add_groupsubscription_columns.py index b950558f548f64..5599726ce6ebec 100644 --- a/src/sentry/migrations/0546_re_add_groupsubscription_columns.py +++ b/src/sentry/migrations/0549_re_add_groupsubscription_columns.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.20 on 2023-09-08 18:36 +# Generated by Django 3.2.20 on 2023-09-12 16:50 import django.db.models.deletion from django.db import migrations, models From 2a3b4d7770ed07e305441985e2c8836bc765eb94 Mon Sep 17 00:00:00 2001 From: Richard Roggenkemper Date: Tue, 12 Sep 2023 09:52:32 -0700 Subject: [PATCH 9/9] update --- src/sentry/migrations/0549_re_add_groupsubscription_columns.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sentry/migrations/0549_re_add_groupsubscription_columns.py b/src/sentry/migrations/0549_re_add_groupsubscription_columns.py index 5599726ce6ebec..a597078f9b5bf0 100644 --- a/src/sentry/migrations/0549_re_add_groupsubscription_columns.py +++ b/src/sentry/migrations/0549_re_add_groupsubscription_columns.py @@ -21,7 +21,7 @@ class Migration(CheckedMigration): is_dangerous = False dependencies = [ - ("sentry", "0545_add_last_verified_auth_ident_replica"), + ("sentry", "0548_add_is_unclaimed_boolean_to_user"), ] operations = [