Skip to content

Commit 98d770c

Browse files
Reapply "ref: convert big table GzippedDictFields to LegacyTextJSONField (#97380)" (#97493)
This reverts commit f595908. reapply after the fix in #97478 <!-- Describe your PR here. -->
1 parent 92ebdbf commit 98d770c

File tree

8 files changed

+54
-12
lines changed

8 files changed

+54
-12
lines changed

migrations_lockfile.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ preprod: 0014_commitcomparisons_fk
2727

2828
replays: 0006_add_bulk_delete_job
2929

30-
sentry: 0964_add_commitcomparison_table
30+
sentry: 0965_gzippeddict_big_tables
3131

3232
social_auth: 0003_social_auth_json_field
3333

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Generated by Django 5.2.1 on 2025-08-07 15:00
2+
3+
from django.db import migrations
4+
5+
import sentry.db.models.fields.jsonfield
6+
from sentry.new_migrations.migrations import CheckedMigration
7+
8+
9+
class Migration(CheckedMigration):
10+
# This flag is used to mark that a migration shouldn't be automatically run in production.
11+
# This should only be used for operations where it's safe to run the migration after your
12+
# code has deployed. So this should not be used for most operations that alter the schema
13+
# of a table.
14+
# Here are some things that make sense to mark as post deployment:
15+
# - Large data migrations. Typically we want these to be run manually so that they can be
16+
# monitored and not block the deploy for a long period of time while they run.
17+
# - Adding indexes to large tables. Since this can take a long time, we'd generally prefer to
18+
# run this outside deployments so that we don't block them. Note that while adding an index
19+
# is a schema change, it's completely safe to run the operation after the code has deployed.
20+
# Once deployed, run these manually via: https://develop.sentry.dev/database-migrations/#migration-deployment
21+
22+
is_post_deployment = False
23+
24+
dependencies = [
25+
("sentry", "0964_add_commitcomparison_table"),
26+
]
27+
28+
operations = [
29+
migrations.AlterField(
30+
model_name="activity",
31+
name="data",
32+
field=sentry.db.models.fields.jsonfield.LegacyTextJSONField(default=dict, null=True),
33+
),
34+
migrations.AlterField(
35+
model_name="group",
36+
name="data",
37+
field=sentry.db.models.fields.jsonfield.LegacyTextJSONField(null=True),
38+
),
39+
migrations.AlterField(
40+
model_name="rule",
41+
name="data",
42+
field=sentry.db.models.fields.jsonfield.LegacyTextJSONField(default=dict),
43+
),
44+
]

src/sentry/models/activity.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
from sentry.db.models import (
1717
BoundedPositiveIntegerField,
1818
FlexibleForeignKey,
19-
GzippedDictField,
2019
Model,
2120
region_silo_model,
2221
sane_repr,
2322
)
2423
from sentry.db.models.fields.hybrid_cloud_foreign_key import HybridCloudForeignKey
24+
from sentry.db.models.fields.jsonfield import LegacyTextJSONField
2525
from sentry.db.models.manager.base import BaseManager
2626
from sentry.integrations.types import IntegrationProviderSlug
2727
from sentry.issues.grouptype import get_group_type_by_type_id
@@ -118,7 +118,7 @@ class Activity(Model):
118118
# if the user is not set, it's assumed to be the system
119119
user_id = HybridCloudForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete="SET_NULL")
120120
datetime = models.DateTimeField(default=timezone.now)
121-
data: models.Field[dict[str, Any] | None, dict[str, Any]] = GzippedDictField(null=True)
121+
data = LegacyTextJSONField(default=dict, null=True)
122122

123123
objects: ClassVar[ActivityManager] = ActivityManager()
124124

src/sentry/models/group.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@
2929
BoundedIntegerField,
3030
BoundedPositiveIntegerField,
3131
FlexibleForeignKey,
32-
GzippedDictField,
3332
Model,
3433
region_silo_model,
3534
sane_repr,
3635
)
36+
from sentry.db.models.fields.jsonfield import LegacyTextJSONField
3737
from sentry.db.models.manager.base import BaseManager
3838
from sentry.eventstore.models import GroupEvent
3939
from sentry.issues.grouptype import GroupCategory, get_group_type_by_type_id
@@ -612,9 +612,7 @@ class Group(Model):
612612
time_spent_count = BoundedIntegerField(default=0)
613613
# deprecated, do not use. GroupShare has superseded
614614
is_public = models.BooleanField(default=False, null=True)
615-
data: models.Field[dict[str, Any] | None, dict[str, Any]] = GzippedDictField(
616-
blank=True, null=True
617-
)
615+
data = LegacyTextJSONField(null=True)
618616
short_id = BoundedBigIntegerField(null=True)
619617
type = BoundedPositiveIntegerField(
620618
default=DEFAULT_TYPE_ID, db_default=DEFAULT_TYPE_ID, db_index=True

src/sentry/models/rule.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313
from sentry.db.models import (
1414
BoundedPositiveIntegerField,
1515
FlexibleForeignKey,
16-
GzippedDictField,
1716
Model,
1817
region_silo_model,
1918
sane_repr,
2019
)
2120
from sentry.db.models.fields.hybrid_cloud_foreign_key import HybridCloudForeignKey
21+
from sentry.db.models.fields.jsonfield import LegacyTextJSONField
2222
from sentry.db.models.manager.base import BaseManager
2323
from sentry.types.actor import Actor
2424
from sentry.utils.cache import cache
@@ -48,7 +48,7 @@ class Rule(Model):
4848
environment_id = BoundedPositiveIntegerField(null=True)
4949
label = models.CharField(max_length=256)
5050
# `data` contain all the specifics of the rule - conditions, actions, frequency, etc.
51-
data: models.Field[dict[str, Any], dict[str, Any]] = GzippedDictField()
51+
data = LegacyTextJSONField(default=dict)
5252
status = BoundedPositiveIntegerField(
5353
default=ObjectStatus.ACTIVE,
5454
choices=((ObjectStatus.ACTIVE, "Active"), (ObjectStatus.DISABLED, "Disabled")),

src/sentry/rules/conditions/reappeared_event.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def get_activity(
3636
group_id=group_id,
3737
type=ConditionActivityType.REAPPEARED,
3838
timestamp=timestamp,
39-
data=data,
39+
data=data or {},
4040
)
4141
for group_id, timestamp, data in activities
4242
if group_id is not None

src/sentry/rules/conditions/regression_event.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def get_activity(
3535
group_id=group_id,
3636
type=ConditionActivityType.REGRESSION,
3737
timestamp=timestamp,
38-
data=data,
38+
data=data or {},
3939
)
4040
for group_id, timestamp, data in activities
4141
if group_id is not None

src/sentry/seer/fetch_issues/fetch_issues_given_exception_type.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ def get_issues_related_to_exception_type(
117117
date_threshold = datetime.now(tz=UTC) - timedelta(days=num_days_ago)
118118

119119
# Fetch issues where the exception type is the given exception type
120-
# Using a bit ofraw SQL since data is GzippedDictField which can't be filtered with Django ORM
120+
# Using a bit ofraw SQL since data is LegacyTextJSONField which can't be filtered with Django ORM
121121
query_set = (
122122
Group.objects.annotate(metadata_type=RawSQL("(data::json -> 'metadata' ->> 'type')", []))
123123
.filter(

0 commit comments

Comments
 (0)