From e77f813a80a04105652b2e435376f6b10b06050f Mon Sep 17 00:00:00 2001 From: Abdkhan14 <60121741+Abdkhan14@users.noreply.github.com> Date: Tue, 25 Jul 2023 10:10:46 -0400 Subject: [PATCH] feat(dnd-worldmap-removal) Added null checks for columns and fields. (#53475) - Migration already approved here: [PR](https://github.com/getsentry/sentry/pull/53109) but it had a runtime error. - Added null checks for columns and fields in DashboardWidgetQuery. - Should fix run time error from previous migration attempt: Screenshot 2023-07-24 at 6 17 48 PM - Link to failure: https://deploy.getsentry.net/go/tab/build/detail/deploy-getsentry-backend-us/63/migrations/1/migrations - Tested it out locally with NULL columns. Co-authored-by: Abdullah Khan --- migrations_lockfile.txt | 2 +- .../0521_migrate_world_map_widgets.py | 66 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/sentry/migrations/0521_migrate_world_map_widgets.py diff --git a/migrations_lockfile.txt b/migrations_lockfile.txt index 8fa2dc43e23c6..70d84e2d2b192 100644 --- a/migrations_lockfile.txt +++ b/migrations_lockfile.txt @@ -6,5 +6,5 @@ To resolve this, rebase against latest master and regenerate your migration. Thi will then be regenerated, and you should be able to merge without conflicts. nodestore: 0002_nodestore_no_dictfield -sentry: 0520_add_flat_file_index_table +sentry: 0521_migrate_world_map_widgets social_auth: 0002_default_auto_field diff --git a/src/sentry/migrations/0521_migrate_world_map_widgets.py b/src/sentry/migrations/0521_migrate_world_map_widgets.py new file mode 100644 index 0000000000000..667769e51f1c4 --- /dev/null +++ b/src/sentry/migrations/0521_migrate_world_map_widgets.py @@ -0,0 +1,66 @@ +# Generated by Django 3.2.20 on 2023-07-25 13:35 + +from django.db import migrations + +from sentry.models import DashboardWidgetQuery +from sentry.new_migrations.migrations import CheckedMigration + + +def migrate_worldmap_widgets_to_table_widgets(apps, schema_editor): + # World map visulization has display_type 5 + widgetQueries = DashboardWidgetQuery.objects.select_related("widget").filter( + widget__display_type=5 + ) + + for widgetQuery in widgetQueries: + # Change widget display type from world_map:5 to table:4 + widgetQuery.widget.display_type = 4 + + # Ensure condition has country_code check + if "has:geo.country_code" not in widgetQuery.conditions: + widgetQuery.conditions = widgetQuery.conditions + " has:geo.country_code" + + # Add region and country_code columns + if not widgetQuery.columns: + widgetQuery.columns = [] + if "geo.region" not in widgetQuery.columns: + widgetQuery.columns.insert(0, "geo.region") + if "geo.country_code" not in widgetQuery.columns: + widgetQuery.columns.insert(0, "geo.country_code") + + # Add region and country_code as fields + if not widgetQuery.fields: + widgetQuery.fields = [] + if "geo.region" not in widgetQuery.fields: + widgetQuery.fields.insert(0, "geo.region") + if "geo.country_code" not in widgetQuery.fields: + widgetQuery.fields.insert(0, "geo.country_code") + + widgetQuery.widget.save() + widgetQuery.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", "0520_add_flat_file_index_table"), + ] + + operations = [ + migrations.RunPython( + migrate_worldmap_widgets_to_table_widgets, + migrations.RunPython.noop, + hints={"tables": ["sentry_dashboardwidgetquery", "sentry_dashboardwidget"]}, + ), + ]