|
@@ -0,0 +1,70 @@
|
|
|
+# -*- coding: utf-8 -*-
|
|
|
+# Generated by Django 1.11.28 on 2020-03-12 21:02
|
|
|
+from __future__ import unicode_literals
|
|
|
+
|
|
|
+
|
|
|
+from datetime import datetime
|
|
|
+from django.db import migrations
|
|
|
+from django.db.models import OuterRef, Exists
|
|
|
+
|
|
|
+
|
|
|
+def mark_all_projects_completed_alert_rule_onboarding(apps, schema_editor):
|
|
|
+ from sentry.utils.query import RangeQuerySetWrapperWithProgressBar
|
|
|
+ from sentry.models import OnboardingTaskStatus, OnboardingTask
|
|
|
+
|
|
|
+ Organization = apps.get_model("sentry", "organization")
|
|
|
+ OrganizationOnboardingTask = apps.get_model("sentry", "organizationonboardingtask")
|
|
|
+
|
|
|
+ # Locate all organizations, annotated which have not completed alert
|
|
|
+ # onboarding tasks.
|
|
|
+ #
|
|
|
+ # Queryplan:
|
|
|
+ #
|
|
|
+ # Seq Scan on sentry_organization (cost=0.00..1310384.71 rows=293362 width=57)
|
|
|
+ # SubPlan 1
|
|
|
+ # -> Index Only Scan using sentry_organizationonboar_organization_id_47e98e05cae29cf3_uniq on sentry_organizationonboardingtask u0 (cost=0.42..4.44 rows=1 width=0)
|
|
|
+ # Index Cond: ((organization_id = sentry_organization.id) AND (task = 10))
|
|
|
+ # SubPlan 2
|
|
|
+ # -> Index Only Scan using sentry_organizationonboar_organization_id_47e98e05cae29cf3_uniq on sentry_organizationonboardingtask u0_1 (cost=0.42..15696.40 rows=22913 width=8)
|
|
|
+ # Index Cond: (task = 10)
|
|
|
+ #
|
|
|
+ target_organizations = Organization.objects.annotate(
|
|
|
+ alert_task_complete=Exists(
|
|
|
+ OrganizationOnboardingTask.objects.filter(
|
|
|
+ organization_id=OuterRef("id"), task=OnboardingTask.ALERT_RULE
|
|
|
+ )
|
|
|
+ )
|
|
|
+ )
|
|
|
+
|
|
|
+ for org in RangeQuerySetWrapperWithProgressBar(target_organizations):
|
|
|
+ if org.alert_task_complete:
|
|
|
+ continue
|
|
|
+
|
|
|
+ OrganizationOnboardingTask.objects.update_or_create(
|
|
|
+ organization_id=org.id,
|
|
|
+ task=OnboardingTask.ALERT_RULE,
|
|
|
+ defaults={"status": OnboardingTaskStatus.COMPLETE},
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+class Migration(migrations.Migration):
|
|
|
+ # This flag is used to mark that a migration shouldn't be automatically run in
|
|
|
+ # production. We set this to True for operations that we think are risky and want
|
|
|
+ # someone from ops to run manually and monitor.
|
|
|
+ # General advice is that if in doubt, mark your migration as `is_dangerous`.
|
|
|
+ # Some things you should always mark as dangerous:
|
|
|
+ # - Large data migrations. Typically we want these to be run manually by ops so that
|
|
|
+ # they can be monitored. Since data migrations will now hold a transaction open
|
|
|
+ # this is even more important.
|
|
|
+ # - Adding columns to highly active tables, even ones that are NULL.
|
|
|
+ is_dangerous = True
|
|
|
+
|
|
|
+ # This flag is used to decide whether to run this migration in a transaction or not.
|
|
|
+ # By default we prefer to run in a transaction, but for migrations where you want
|
|
|
+ # to `CREATE INDEX CONCURRENTLY` this needs to be set to False. Typically you'll
|
|
|
+ # want to create an index concurrently when adding one to an existing table.
|
|
|
+ atomic = False
|
|
|
+
|
|
|
+ dependencies = [("sentry", "0052_organizationonboardingtask_completion_seen")]
|
|
|
+
|
|
|
+ operations = [migrations.RunPython(mark_all_projects_completed_alert_rule_onboarding)]
|