Browse Source

feat(dashboards): Rename widget issues queries orderby from `priority` to `trends` (#66896)

Priority sort was renamed to `trends` here:
https://github.com/getsentry/sentry/pull/65752

There was a migration run for saved searches
([here](https://github.com/getsentry/sentry/pull/65311)), but not for
dashboard widgets.

This will fix the issue where existing dashboard widgets with the priority
sort display an error.
Malachi Willey 1 year ago
parent
commit
996e47bc7f

+ 1 - 1
migrations_lockfile.txt

@@ -9,5 +9,5 @@ feedback: 0004_index_together
 hybridcloud: 0014_apitokenreplica_add_hashed_token
 nodestore: 0002_nodestore_no_dictfield
 replays: 0004_index_together
-sentry: 0674_monitor_clear_missed_timeout_as_error
+sentry: 0675_dashboard_widget_query_rename_priority_sort_to_trends
 social_auth: 0002_default_auto_field

+ 40 - 0
src/sentry/migrations/0675_dashboard_widget_query_rename_priority_sort_to_trends.py

@@ -0,0 +1,40 @@
+# Generated by Django 5.0.2 on 2024-03-13 17:00
+
+from django.db import migrations
+
+from sentry.new_migrations.migrations import CheckedMigration
+from sentry.utils.query import RangeQuerySetWrapperWithProgressBarApprox
+
+
+def rename_dashboard_widget_query_orderby_priority_to_trends(apps, schema_editor):
+    DashboardWidgetQuery = apps.get_model("sentry", "DashboardWidgetQuery")
+    for query in RangeQuerySetWrapperWithProgressBarApprox(DashboardWidgetQuery.objects.all()):
+        if query.orderby == "priority":
+            query.orderby = "trends"
+            query.save(update_fields=["orderby"])
+
+
+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", "0674_monitor_clear_missed_timeout_as_error"),
+    ]
+
+    operations = [
+        migrations.RunPython(
+            rename_dashboard_widget_query_orderby_priority_to_trends,
+            migrations.RunPython.noop,
+            hints={"tables": ["sentry_dashboardwidgetquery"]},
+        ),
+    ]

+ 62 - 0
tests/sentry/migrations/test_0675_dashboard_widget_query_rename_priority_sort_to_trends.py

@@ -0,0 +1,62 @@
+from sentry.models.dashboard_widget import DashboardWidgetDisplayTypes
+from sentry.testutils.cases import TestMigrations
+
+
+class RenamePrioritySortToTrendsTest(TestMigrations):
+    migrate_from = "0674_monitor_clear_missed_timeout_as_error"
+    migrate_to = "0675_dashboard_widget_query_rename_priority_sort_to_trends"
+
+    def setup_before_migration(self, apps):
+        Dashboard = apps.get_model("sentry", "Dashboard")
+        DashboardWidget = apps.get_model("sentry", "DashboardWidget")
+        DashboardWidgetQuery = apps.get_model("sentry", "DashboardWidgetQuery")
+
+        self.dashboard = Dashboard.objects.create(
+            organization_id=self.organization.id,
+            title="Dashboard",
+            created_by_id=self.user.id,
+        )
+
+        self.queries_with_priority_sort = []
+        self.other_queries = []
+
+        for i, title in enumerate(["Widget 1", "Widget 2", "Widget 3"]):
+            widget = DashboardWidget.objects.create(
+                dashboard=self.dashboard,
+                order=i,
+                title=title,
+                display_type=DashboardWidgetDisplayTypes.TABLE,
+            )
+            widget_query = DashboardWidgetQuery.objects.create(
+                widget=widget,
+                name="query",
+                fields=["assignee", "issue", "title"],
+                order=1,
+                orderby="priority",
+            )
+            self.queries_with_priority_sort.append(widget_query)
+
+        for i, title in enumerate(["Widget 1", "Widget 2", "Widget 3"]):
+            widget = DashboardWidget.objects.create(
+                dashboard=self.dashboard,
+                order=i + 3,
+                title=title,
+                display_type=DashboardWidgetDisplayTypes.TABLE,
+            )
+            widget_query = DashboardWidgetQuery.objects.create(
+                widget=widget,
+                name="query",
+                fields=["assignee", "issue", "title"],
+                order=1,
+                orderby="last_seen",
+            )
+            self.other_queries.append(widget_query)
+
+    def test(self):
+        for query in self.queries_with_priority_sort:
+            query.refresh_from_db()
+            assert query.orderby == "trends"
+
+        for query in self.other_queries:
+            query.refresh_from_db()
+            assert query.orderby == "last_seen"