diff --git a/src/sentry/sentry_apps/services/app/impl.py b/src/sentry/sentry_apps/services/app/impl.py index 6c71a1d5517ee3..d54619f5ced405 100644 --- a/src/sentry/sentry_apps/services/app/impl.py +++ b/src/sentry/sentry_apps/services/app/impl.py @@ -61,20 +61,22 @@ def get_many( def find_app_components(self, *, app_id: int) -> list[RpcSentryAppComponent]: return [ serialize_sentry_app_component(c) - for c in SentryAppComponent.objects.filter(sentry_app_id=app_id) + for c in SentryAppComponent.objects.using_replica().filter(sentry_app_id=app_id) ] def get_sentry_app_by_id(self, *, id: int) -> RpcSentryApp | None: try: - sentry_app = SentryApp.objects.get(id=id) + sentry_app = SentryApp.objects.using_replica().get(id=id) except SentryApp.DoesNotExist: return None return serialize_sentry_app(sentry_app) def get_installation_by_id(self, *, id: int) -> RpcSentryAppInstallation | None: try: - install = SentryAppInstallation.objects.select_related("sentry_app").get( - id=id, status=SentryAppInstallationStatus.INSTALLED + install = ( + SentryAppInstallation.objects.using_replica() + .select_related("sentry_app") + .get(id=id, status=SentryAppInstallationStatus.INSTALLED) ) return serialize_sentry_app_installation(install) except SentryAppInstallation.DoesNotExist: @@ -85,7 +87,10 @@ def get_installation_org_id_by_token_id(self, token_id: int) -> int | None: "status": SentryAppInstallationStatus.INSTALLED, "api_installation_token_id": str(token_id), } - queryset = self._FQ.apply_filters(SentryAppInstallation.objects.all(), filters) + queryset = self._FQ.apply_filters( + SentryAppInstallation.objects.using_replica().all(), + filters, + ) install = queryset.first() if not install: return None @@ -93,7 +98,7 @@ def get_installation_org_id_by_token_id(self, token_id: int) -> int | None: def get_sentry_app_by_slug(self, *, slug: str) -> RpcSentryApp | None: try: - sentry_app = SentryApp.objects.get(slug=slug) + sentry_app = SentryApp.objects.using_replica().get(slug=slug) return serialize_sentry_app(sentry_app) except SentryApp.DoesNotExist: return None @@ -101,23 +106,31 @@ def get_sentry_app_by_slug(self, *, slug: str) -> RpcSentryApp | None: def get_installations_for_organization( self, *, organization_id: int ) -> list[RpcSentryAppInstallation]: - installations = SentryAppInstallation.objects.get_installed_for_organization( - organization_id - ).select_related("sentry_app", "api_token") + installations = ( + SentryAppInstallation.objects.get_installed_for_organization(organization_id) + .using_replica() + .select_related("sentry_app", "api_token") + ) fq = self._AppServiceFilterQuery() return [fq.serialize_rpc(i) for i in installations] def find_alertable_services(self, *, organization_id: int) -> list[RpcSentryAppService]: result: list[RpcSentryAppService] = [] - for app in SentryApp.objects.filter( - installations__organization_id=organization_id, - is_alertable=True, - installations__status=SentryAppInstallationStatus.INSTALLED, - installations__date_deleted=None, - ).distinct("id"): - if SentryAppComponent.objects.filter( - sentry_app_id=app.id, type="alert-rule-action" - ).exists(): + for app in ( + SentryApp.objects.using_replica() + .filter( + installations__organization_id=organization_id, + is_alertable=True, + installations__status=SentryAppInstallationStatus.INSTALLED, + installations__date_deleted=None, + ) + .distinct("id") + ): + if ( + SentryAppComponent.objects.using_replica() + .filter(sentry_app_id=app.id, type="alert-rule-action") + .exists() + ): continue result.append( RpcSentryAppService( @@ -150,12 +163,13 @@ def get_custom_alert_rule_actions( def get_component_contexts( self, *, filter: SentryAppInstallationFilterArgs, component_type: str ) -> list[RpcSentryAppComponentContext]: - install_query = self._FQ.query_many(filter=filter) + install_query = self._FQ.base_query() + install_query = self._FQ.apply_filters(install_query, filter) install_query = install_query.select_related("sentry_app", "sentry_app__application") install_map: dict[int, list[SentryAppInstallation]] = defaultdict(list) for install in install_query: install_map[install.sentry_app_id].append(install) - component_query = SentryAppComponent.objects.filter( + component_query = SentryAppComponent.objects.using_replica().filter( type=component_type, sentry_app_id__in=list(install_map.keys()) ) output = [] @@ -178,10 +192,11 @@ def get_installation_component_contexts( component_type: str, include_contexts_without_component: bool = False, ) -> list[RpcSentryAppComponentContext]: - install_query = self._FQ.query_many(filter=filter) + install_query = self._FQ.base_query() + install_query = self._FQ.apply_filters(install_query, filter) app_ids = install_query.values_list("sentry_app_id", flat=True) - component_query = SentryAppComponent.objects.filter( + component_query = SentryAppComponent.objects.using_replica().filter( type=component_type, sentry_app_id__in=list(app_ids) ) component_map: dict[int, SentryAppComponent] = {} @@ -268,12 +283,12 @@ def find_installation_by_proxy_user( self, *, proxy_user_id: int, organization_id: int ) -> RpcSentryAppInstallation | None: try: - sentry_app = SentryApp.objects.get(proxy_user_id=proxy_user_id) + sentry_app = SentryApp.objects.using_replica().get(proxy_user_id=proxy_user_id) except SentryApp.DoesNotExist: return None try: - installation = SentryAppInstallation.objects.get( + installation = SentryAppInstallation.objects.using_replica().get( sentry_app_id=sentry_app.id, organization_id=organization_id ) except SentryAppInstallation.DoesNotExist: @@ -308,14 +323,16 @@ def trigger_sentry_app_action_creators( def find_service_hook_sentry_app(self, *, api_application_id: int) -> RpcSentryApp | None: try: - return serialize_sentry_app(SentryApp.objects.get(application_id=api_application_id)) + return serialize_sentry_app( + SentryApp.objects.using_replica().get(application_id=api_application_id) + ) except SentryApp.DoesNotExist: return None def get_published_sentry_apps_for_organization( self, *, organization_id: int ) -> list[RpcSentryApp]: - published_apps = SentryApp.objects.filter( + published_apps = SentryApp.objects.using_replica().filter( owner_id=organization_id, status=SentryAppStatus.PUBLISHED ) return [serialize_sentry_app(app) for app in published_apps] @@ -337,7 +354,7 @@ def get_internal_integrations( list[RpcSentryApp]: A list of serialized internal Sentry Apps matching the criteria. Returns an empty list if no matches are found. """ - internal_integrations = SentryApp.objects.filter( + internal_integrations = SentryApp.objects.using_replica().filter( owner_id=organization_id, status=SentryAppStatus.INTERNAL, name=integration_name, @@ -384,7 +401,7 @@ def prepare_sentry_app_components( ) -> RpcSentryAppComponent | None: from sentry.sentry_apps.models.sentry_app_installation import prepare_sentry_app_components - installation = SentryAppInstallation.objects.get(id=installation_id) + installation = SentryAppInstallation.objects.using_replica().get(id=installation_id) component = prepare_sentry_app_components(installation, component_type, project_slug) return serialize_sentry_app_component(component) if component else None