From 256bc2e2752d68435379eeffa6deb492396d2d34 Mon Sep 17 00:00:00 2001 From: Dominik Buszowiecki Date: Fri, 26 Jun 2026 10:48:27 -0400 Subject: [PATCH] ref(explore): Remove last_received from attribute context tables last_seen will be computed in ClickHouse (getsentry/snuba#7801), so there's no need to store last_received on the attribute context tables. --- migrations_lockfile.txt | 2 +- ...ve_last_received_from_attribute_context.py | 38 +++++++++++++++++++ src/sentry/explore/models.py | 4 -- tests/sentry/explore/test_models.py | 2 - 4 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 src/sentry/explore/migrations/0010_remove_last_received_from_attribute_context.py diff --git a/migrations_lockfile.txt b/migrations_lockfile.txt index 5d1a4351fa93..54929d9ed945 100644 --- a/migrations_lockfile.txt +++ b/migrations_lockfile.txt @@ -7,7 +7,7 @@ will then be regenerated, and you should be able to merge without conflicts. discover: 0003_discover_json_field -explore: 0009_add_trace_item_attribute_value_context +explore: 0010_remove_last_received_from_attribute_context feedback: 0007_cleanup_failed_safe_deletes diff --git a/src/sentry/explore/migrations/0010_remove_last_received_from_attribute_context.py b/src/sentry/explore/migrations/0010_remove_last_received_from_attribute_context.py new file mode 100644 index 000000000000..d9086f0d0bb1 --- /dev/null +++ b/src/sentry/explore/migrations/0010_remove_last_received_from_attribute_context.py @@ -0,0 +1,38 @@ +# Generated by Django 5.2.14 on 2026-06-26 14:35 + +from sentry.new_migrations.migrations import CheckedMigration +from sentry.new_migrations.monkey.fields import SafeRemoveField +from sentry.new_migrations.monkey.state import DeletionAction + + +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 = [ + ("explore", "0009_add_trace_item_attribute_value_context"), + ] + + operations = [ + SafeRemoveField( + model_name="traceitemattributecontext", + name="last_received", + deletion_action=DeletionAction.MOVE_TO_PENDING, + ), + SafeRemoveField( + model_name="traceitemattributevaluecontext", + name="last_received", + deletion_action=DeletionAction.MOVE_TO_PENDING, + ), + ] diff --git a/src/sentry/explore/models.py b/src/sentry/explore/models.py index e5c6cd46284c..e3affc92060e 100644 --- a/src/sentry/explore/models.py +++ b/src/sentry/explore/models.py @@ -451,8 +451,6 @@ class TraceItemAttributeContext(DefaultFieldsModel): created_by_id = HybridCloudForeignKey("sentry.User", null=True, on_delete="SET_NULL") updated_by_id = HybridCloudForeignKey("sentry.User", null=True, on_delete="SET_NULL") - # When the attribute was last seen in storage. Used to prune stale attributes. - last_received = models.DateTimeField(null=True) class Meta: app_label = "explore" @@ -512,8 +510,6 @@ class TraceItemAttributeValueContext(DefaultFieldsModel): created_by_id = HybridCloudForeignKey("sentry.User", null=True, on_delete="SET_NULL") updated_by_id = HybridCloudForeignKey("sentry.User", null=True, on_delete="SET_NULL") - # When the value was last seen in storage. Used to prune stale entries. - last_received = models.DateTimeField(null=True) class Meta: app_label = "explore" diff --git a/tests/sentry/explore/test_models.py b/tests/sentry/explore/test_models.py index 45c6450125f9..fe783da4c259 100644 --- a/tests/sentry/explore/test_models.py +++ b/tests/sentry/explore/test_models.py @@ -46,7 +46,6 @@ def test_create_project_scoped(self) -> None: assert description.id is not None assert description.examples == ["GET", "POST"] assert description.additional_context is None - assert description.last_received is None def test_create_org_wide(self) -> None: description = TraceItemAttributeContext.objects.create( @@ -156,7 +155,6 @@ def test_create_project_scoped(self) -> None: ) assert context.id is not None assert context.additional_context is None - assert context.last_received is None def test_create_org_wide(self) -> None: context = TraceItemAttributeValueContext.objects.create(