Browse Source

feat(dashboards): Add dataset source field to widget model (#74671)

Adds a `dataset_source` field to the dashboard widget model. This is
going to be used with the discover split so we can tell apart if we've
automatically split discover for them, or if they've created a widget
with the dataset explicitly.
Nar Saynorath 7 months ago
parent
commit
bec7c1bed0

+ 1 - 1
migrations_lockfile.txt

@@ -10,6 +10,6 @@ hybridcloud: 0016_add_control_cacheversion
 nodestore: 0002_nodestore_no_dictfield
 remote_subscriptions: 0003_drop_remote_subscription
 replays: 0004_index_together
-sentry: 0743_backfill_broken_monitor_notification_setting_option
+sentry: 0744_add_dataset_source_field_to_dashboards
 social_auth: 0002_default_auto_field
 uptime: 0006_projectuptimesubscription_name_owner

+ 49 - 0
src/sentry/migrations/0744_add_dataset_source_field_to_dashboards.py

@@ -0,0 +1,49 @@
+# Generated by Django 5.0.6 on 2024-07-22 17:48
+
+from django.db import migrations
+
+import sentry.db.models.fields.bounded
+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.
+    # 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 post deployment:
+    # - Large data migrations. Typically we want these to be run manually 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
+    #   run this outside deployments so that we don't block them. Note that while adding an index
+    #   is a schema change, it's completely safe to run the operation after the code has deployed.
+    # Once deployed, run these manually via: https://develop.sentry.dev/database-migrations/#migration-deployment
+
+    is_post_deployment = False
+
+    dependencies = [
+        ("sentry", "0743_backfill_broken_monitor_notification_setting_option"),
+    ]
+
+    operations = [
+        migrations.SeparateDatabaseAndState(
+            database_operations=[
+                migrations.RunSQL(
+                    """
+                    ALTER TABLE "sentry_dashboardwidget" ADD COLUMN "dataset_source" integer NOT NULL DEFAULT 0;
+                    """,
+                    reverse_sql="""
+                    ALTER TABLE "sentry_dashboardwidget" DROP COLUMN "dataset_source";
+                    """,
+                    hints={"tables": ["sentry_dashboardwidget"]},
+                ),
+            ],
+            state_operations=[
+                migrations.AddField(
+                    model_name="dashboardwidget",
+                    name="dataset_source",
+                    field=sentry.db.models.fields.bounded.BoundedPositiveIntegerField(default=0),
+                ),
+            ],
+        )
+    ]

+ 31 - 0
src/sentry/models/dashboard_widget.py

@@ -1,5 +1,6 @@
 from __future__ import annotations
 
+from enum import Enum
 from typing import Any
 
 from django.contrib.postgres.fields import ArrayField as DjangoArrayField
@@ -76,6 +77,31 @@ class DashboardWidgetTypes(TypesClass):
     TYPE_NAMES = [t[1] for t in TYPES]
 
 
+class DatasetSourcesTypes(Enum):
+    """
+    Ambiguous queries that haven't been or couldn't be categorized into a
+    specific dataset.
+    """
+
+    UNKNOWN = 0
+    """
+     Dataset inferred by either running the query or using heuristics.
+    """
+    INFERRED = 1
+    """
+     Canonical dataset, user explicitly selected it.
+    """
+    USER = 2
+    """
+     Was an ambiguous dataset forced to split (i.e. we picked a default)
+    """
+    FORCED = 3
+
+    @classmethod
+    def as_choices(cls):
+        return tuple((source.value, source.name.lower()) for source in cls)
+
+
 # TODO: Can eventually be replaced solely with TRANSACTION_MULTI once no more dashboards use Discover.
 TransactionWidgetType = [DashboardWidgetTypes.DISCOVER, DashboardWidgetTypes.TRANSACTION_LIKE]
 # TODO: Can be replaced once conditions are replaced at all callsite to split transaction and error behaviour, and once dashboard no longer have saved Discover dataset.
@@ -235,6 +261,11 @@ class DashboardWidget(Model):
         choices=DashboardWidgetTypes.as_choices(), null=True
     )
 
+    # The method of which the discover split datasets was decided
+    dataset_source = BoundedPositiveIntegerField(
+        choices=DatasetSourcesTypes.as_choices(), default=DatasetSourcesTypes.UNKNOWN.value
+    )
+
     class Meta:
         app_label = "sentry"
         db_table = "sentry_dashboardwidget"

File diff suppressed because it is too large
+ 194 - 194
tests/sentry/backup/snapshots/ReleaseTests/test_at_head.pysnap


Some files were not shown because too many files changed in this diff