Browse Source

ref(hc): Migration to actively backfill ExternalActor columns (#55302)

Zach Collins 1 year ago
parent
commit
80643ff718

+ 1 - 1
migrations_lockfile.txt

@@ -7,5 +7,5 @@ will then be regenerated, and you should be able to merge without conflicts.
 
 nodestore: 0002_nodestore_no_dictfield
 replays: 0003_add_size_to_recording_segment
-sentry: 0536_backfill_tombstones
+sentry: 0537_backfill_xactor_team_and_user_ids
 social_auth: 0002_default_auto_field

+ 47 - 0
src/sentry/migrations/0537_backfill_xactor_team_and_user_ids.py

@@ -0,0 +1,47 @@
+# Generated by Django 3.2.20 on 2023-08-01 20:51
+
+from django.db import migrations
+
+from sentry.new_migrations.migrations import CheckedMigration
+from sentry.utils.query import RangeQuerySetWrapperWithProgressBar
+
+
+def backfill_xactor(apps, schema_editor):
+    ExternalActor = apps.get_model("sentry", "ExternalActor")
+
+    for xa in RangeQuerySetWrapperWithProgressBar(
+        ExternalActor.objects.filter(team_id__isnull=True, user_id__isnull=True)
+    ):
+        actor = xa.actor
+        if actor.type == 1:
+            xa.user_id = actor.user_id
+            xa.save()
+        else:
+            xa.team_id = actor.team_id
+            xa.save()
+
+
+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", "0536_backfill_tombstones"),
+    ]
+
+    operations = [
+        migrations.RunPython(
+            backfill_xactor,
+            migrations.RunPython.noop,
+            hints={"tables": ["sentry_externalactor", "sentry_actor"]},
+        ),
+    ]

+ 19 - 0
tests/sentry/migrations/test_0537_backfill_xactor_team_and_user_ids.py

@@ -0,0 +1,19 @@
+from sentry.testutils.cases import TestMigrations
+
+
+class BackfillTombstones(TestMigrations):
+    migrate_from = "0536_backfill_tombstones"
+    migrate_to = "0537_backfill_xactor_team_and_user_ids"
+
+    def setup_initial_state(self):
+        self.xu = xu = self.create_external_user()
+        self.xt = xt = self.create_external_team()
+
+        assert xu.user_id is None
+        assert xt.team_id is None
+
+    def test_duplicated_all_tombstones(self):
+        self.xu.refresh_from_db()
+        self.xt.refresh_from_db()
+        assert self.xu.user_id == self.xu.actor.user_id
+        assert self.xt.team_id == self.xt.actor.team_id