Skip to content

Commit 7ee9621

Browse files
authored
feat(dashboards): loosen unique title db constraint on dashboards (#104046)
This updates the unique title constraint to only apply for non-prebuilt dashboards. This allows us to built prebuilt ones with the same title as an existing user created on. The UI will distinguish the two by the author field
1 parent a1472e4 commit 7ee9621

File tree

3 files changed

+47
-2
lines changed

3 files changed

+47
-2
lines changed

migrations_lockfile.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ releases: 0004_cleanup_failed_safe_deletes
3131

3232
replays: 0006_add_bulk_delete_job
3333

34-
sentry: 1007_cleanup_failed_safe_deletes
34+
sentry: 1008_loosen_unique_title_contraint
3535

3636
social_auth: 0003_social_auth_json_field
3737

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

src/sentry/models/dashboard.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,13 @@ class Dashboard(Model):
237237
class Meta:
238238
app_label = "sentry"
239239
db_table = "sentry_dashboard"
240-
unique_together = (("organization", "title"),)
241240
constraints = [
241+
# User-created dashboards must have unique titles within an organization, but a prebuilt one can exist with the same title
242+
UniqueConstraint(
243+
fields=["organization", "title"],
244+
condition=Q(prebuilt_id__isnull=True),
245+
name="sentry_dashboard_organization_title_uniq",
246+
),
242247
UniqueConstraint(
243248
fields=["organization", "prebuilt_id"],
244249
condition=Q(prebuilt_id__isnull=False),

0 commit comments

Comments
 (0)