Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 35 additions & 12 deletions src/sentry/seer/autofix/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -543,9 +543,13 @@ def _write_preferences_to_sentry_db(
# Create branch overrides using the created project repos.
overrides_to_create: list[SeerProjectRepositoryBranchOverride] = []
for seer_project_repo in created_project_repos:
for override in overrides_by_key.get(
(seer_project_repo.project_id, seer_project_repo.repository_id), []
):
pr = seer_project_repo.project_repository
key = (
(pr.project_id, pr.repository_id)
if pr is not None
else (seer_project_repo.project_id, seer_project_repo.repository_id)
)
for override in overrides_by_key.get(key, []):
overrides_to_create.append(
SeerProjectRepositoryBranchOverride(
seer_project_repository=seer_project_repo,
Expand Down Expand Up @@ -604,11 +608,16 @@ def clear_preference_automation_handoff(project: Project) -> None:

def build_repo_definition_from_project_repo(
seer_project_repo: SeerProjectRepository,
use_project_repository_fk: bool = False,
) -> SeerRepoDefinition | None:
"""Build a SeerRepoDefinition from a SeerProjectRepository with its joined Repository.

Returns None if Repository name is invalid."""
repo = seer_project_repo.repository
if use_project_repository_fk:
pr = seer_project_repo.project_repository
repo = pr.repository if pr is not None else seer_project_repo.repository
else:
repo = seer_project_repo.repository
repo_name_sections = repo.name.split("/")
if len(repo_name_sections) < 2:
sentry_sdk.capture_exception(ValueError(f"Invalid repository name format: {repo.name}"))
Expand Down Expand Up @@ -656,7 +665,8 @@ def build_automation_handoff(

def read_preference_from_sentry_db(project: Project) -> SeerProjectPreference:
"""Read a single project's Seer preferences from Sentry DB."""
if features.has("organizations:project-repository-fk-reads", project.organization):
use_fk = features.has("organizations:project-repository-fk-reads", project.organization)
if use_fk:
seer_project_repo_qs = (
SeerProjectRepository.objects.filter(
project_repository__project=project,
Expand All @@ -670,13 +680,18 @@ def read_preference_from_sentry_db(project: Project) -> SeerProjectPreference:
SeerProjectRepository.objects.filter(
project=project, repository__status=ObjectStatus.ACTIVE
)
.select_related("repository")
.select_related("repository", "project_repository", "project_repository__repository")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary JOINs added when feature flag is off

Low Severity

The else branches (feature flag off) now include select_related("project_repository", "project_repository__repository") in addition to "repository". When use_fk is False, neither build_repo_definition_from_project_repo nor the pid computation ever accesses project_repository. These extra select_related calls add two unnecessary LEFT OUTER JOINs to every query on the default (non-flag) path, increasing SQL complexity and data transfer for no benefit.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b65e1fa. Configure here.

.prefetch_related("branch_overrides")
)
repo_definitions = [
repo_def
for project_repo in seer_project_repo_qs
if (repo_def := build_repo_definition_from_project_repo(project_repo)) is not None
if (
repo_def := build_repo_definition_from_project_repo(
project_repo, use_project_repository_fk=use_fk
)
)
is not None
]

return SeerProjectPreference(
Expand All @@ -700,19 +715,27 @@ def bulk_read_preferences_from_sentry_db(

org = Organization.objects.get(id=organization_id)
repo_definitions_by_project: defaultdict[int, list[SeerRepoDefinition]] = defaultdict(list)
if features.has("organizations:project-repository-fk-reads", org):
use_fk = features.has("organizations:project-repository-fk-reads", org)
if use_fk:
seer_repo_qs = SeerProjectRepository.objects.filter(
project_repository__project_id__in=project_ids,
project_repository__repository__status=ObjectStatus.ACTIVE,
).select_related("project_repository", "project_repository__repository")
else:
seer_repo_qs = SeerProjectRepository.objects.filter(
project_id__in=project_ids, repository__status=ObjectStatus.ACTIVE
).select_related("repository")
for project_repo in seer_repo_qs.prefetch_related("branch_overrides"):
repo_def = build_repo_definition_from_project_repo(project_repo)
).select_related("repository", "project_repository", "project_repository__repository")
for seer_repo in seer_repo_qs.prefetch_related("branch_overrides"):
repo_def = build_repo_definition_from_project_repo(
seer_repo, use_project_repository_fk=use_fk
)
if repo_def is not None:
repo_definitions_by_project[project_repo.project_id].append(repo_def)
if use_fk:
pr = seer_repo.project_repository
pid = pr.project_id if pr is not None else seer_repo.project_id
else:
pid = seer_repo.project_id
repo_definitions_by_project[pid].append(repo_def)

# get_value_bulk_id returns None for missing options, unlike project.get_option
# which automatically falls back to the registered well-known key default.
Expand Down
4 changes: 3 additions & 1 deletion src/sentry/tasks/seer/night_shift/cron.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@ def schedule_night_shift(
),
step=1000,
):
seer_org_ids.add(spr.project.organization_id)
pr = spr.project_repository
project = pr.project if pr is not None else spr.project
seer_org_ids.add(project.organization_id)

logger.info(
"night_shift.schedule_org_ids_collected",
Expand Down
Loading