ref(db): Migrate create_or_update to update_or_create#111510
Merged
vgrozdanic merged 2 commits intomasterfrom Mar 25, 2026
Merged
ref(db): Migrate create_or_update to update_or_create#111510vgrozdanic merged 2 commits intomasterfrom
vgrozdanic merged 2 commits intomasterfrom
Conversation
Migrate the four remaining phase-1d call sites from the legacy Sentry create_or_update helper to Django's update_or_create: - tasks/commits.py: LatestRepoReleaseEnvironment lookup - tasks/assemble.py: ReleaseArtifactBundle and ProjectArtifactBundle (values= and defaults= pointed at the same dict; collapsed to defaults=) - audit_log/services/log/impl.py: UserIP record - core/endpoints/organization_details.py: ProjectOption target_sample_rate Removes these four files from the create_or_update allowlist in tests/sentry/test_no_create_or_update_usage.py. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: No unique constraint causes
MultipleObjectsReturnederror- Added try-except blocks to catch MultipleObjectsReturned and fall back to filter().update() for backward compatibility with existing duplicate rows.
Or push these changes by commenting:
@cursor push 62de5983df
Preview (62de5983df)
diff --git a/src/sentry/tasks/assemble.py b/src/sentry/tasks/assemble.py
--- a/src/sentry/tasks/assemble.py
+++ b/src/sentry/tasks/assemble.py
@@ -426,23 +426,38 @@
# If a release version is passed, we want to create the weak association between a bundle and a release.
if self.release:
- ReleaseArtifactBundle.objects.update_or_create(
- organization_id=self.organization.id,
- release_name=self.release,
- # In case no dist is provided, we will fall back to "" which is the NULL equivalent for our
- # tables.
- dist_name=self.dist or NULL_STRING,
- artifact_bundle=artifact_bundle,
- defaults=new_date_added,
- )
+ try:
+ ReleaseArtifactBundle.objects.update_or_create(
+ organization_id=self.organization.id,
+ release_name=self.release,
+ # In case no dist is provided, we will fall back to "" which is the NULL equivalent for our
+ # tables.
+ dist_name=self.dist or NULL_STRING,
+ artifact_bundle=artifact_bundle,
+ defaults=new_date_added,
+ )
+ except ReleaseArtifactBundle.MultipleObjectsReturned:
+ ReleaseArtifactBundle.objects.filter(
+ organization_id=self.organization.id,
+ release_name=self.release,
+ dist_name=self.dist or NULL_STRING,
+ artifact_bundle=artifact_bundle,
+ ).update(**new_date_added)
for project_id in self.project_ids:
- ProjectArtifactBundle.objects.update_or_create(
- organization_id=self.organization.id,
- project_id=project_id,
- artifact_bundle=artifact_bundle,
- defaults=new_date_added,
- )
+ try:
+ ProjectArtifactBundle.objects.update_or_create(
+ organization_id=self.organization.id,
+ project_id=project_id,
+ artifact_bundle=artifact_bundle,
+ defaults=new_date_added,
+ )
+ except ProjectArtifactBundle.MultipleObjectsReturned:
+ ProjectArtifactBundle.objects.filter(
+ organization_id=self.organization.id,
+ project_id=project_id,
+ artifact_bundle=artifact_bundle,
+ ).update(**new_date_added)
# Instead of doing a `create_or_update` one-by-one, we will instead:
# - Use a `bulk_create` with `ignore_conflicts` to insert new rows efficientlyThis Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.
ReleaseArtifactBundle and ProjectArtifactBundle lack unique constraints, so update_or_create would raise MultipleObjectsReturned on duplicate rows. Restore create_or_update (filter+update semantics) and keep assemble.py in the allowlist until unique constraints are added. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
jjbayer
approved these changes
Mar 25, 2026
Member
jjbayer
left a comment
There was a problem hiding this comment.
PR description still mentions "four".
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Continues the migration away from Sentry's legacy
create_or_updatehelper toward Django's built-inupdate_or_create.All three files removed from the allowlist in
tests/sentry/test_no_create_or_update_usage.py.Return values were ignored at all sites, so no caller changes are needed.