def delete_tag_key(object_id, continuous=True, **kwargs): from sentry.models import ( EventTag, GroupTagKey, GroupTagValue, TagKey, TagKeyStatus, TagValue ) try: tagkey = TagKey.objects.get(id=object_id) except TagKey.DoesNotExist: return if tagkey.status != TagKeyStatus.DELETION_IN_PROGRESS: tagkey.update(status=TagKeyStatus.DELETION_IN_PROGRESS) bulk_model_list = ( GroupTagValue, GroupTagKey, TagValue ) for model in bulk_model_list: has_more = bulk_delete_objects(model, project_id=tagkey.project_id, key=tagkey.key, logger=logger) if has_more: if continuous: delete_tag_key.delay(object_id=object_id, countdown=15) return has_more = bulk_delete_objects(EventTag, project_id=tagkey.project_id, key_id=tagkey.id, logger=logger) if has_more: if continuous: delete_tag_key.delay(object_id=object_id, countdown=15) return tagkey.delete()
def delete_project(object_id, continuous=True, **kwargs): from sentry.models import ( Activity, EventMapping, Group, GroupAssignee, GroupBookmark, GroupEmailThread, GroupHash, GroupMeta, GroupResolution, GroupRuleStatus, GroupSeen, GroupTagKey, GroupTagValue, Project, ProjectKey, ProjectStatus, SavedSearchUserDefault, SavedSearch, TagKey, TagValue, UserReport ) try: p = Project.objects.get(id=object_id) except Project.DoesNotExist: return if p.status == ProjectStatus.VISIBLE: raise DeleteAborted('Aborting project deletion as status is invalid') if p.status != ProjectStatus.DELETION_IN_PROGRESS: pending_delete.send(sender=Project, instance=p) p.update(status=ProjectStatus.DELETION_IN_PROGRESS) # XXX: remove keys first to prevent additional data from flowing in model_list = ( Activity, EventMapping, GroupAssignee, GroupBookmark, GroupEmailThread, GroupHash, GroupSeen, GroupRuleStatus, GroupTagKey, GroupTagValue, ProjectKey, TagKey, TagValue, SavedSearchUserDefault, SavedSearch, UserReport ) for model in model_list: has_more = bulk_delete_objects(model, project_id=p.id, logger=logger) if has_more: if continuous: delete_project.delay(object_id=object_id, countdown=15) return # TODO(dcramer): no project relation so we cant easily bulk # delete today has_more = delete_objects([GroupMeta, GroupResolution], relation={'group__project': p}, logger=logger) if has_more: if continuous: delete_project.delay(object_id=object_id, countdown=15) return has_more = delete_events(relation={'project_id': p.id}, logger=logger) if has_more: if continuous: delete_project.delay(object_id=object_id, countdown=15) return model_list = (Group,) for model in model_list: has_more = bulk_delete_objects(model, project_id=p.id, logger=logger) if has_more: if continuous: delete_project.delay(object_id=object_id, countdown=15) return p.delete()
def delete_group(object_id, continuous=True, **kwargs): from sentry.models import ( EventMapping, Group, GroupHash, GroupRuleStatus, GroupStatus, GroupTagKey, GroupTagValue, GroupEmailThread, ) try: group = Group.objects.get(id=object_id) except Group.DoesNotExist: return if group.status != GroupStatus.DELETION_IN_PROGRESS: group.update(status=GroupStatus.DELETION_IN_PROGRESS) bulk_model_list = ( GroupHash, GroupRuleStatus, GroupTagValue, GroupTagKey, EventMapping, GroupEmailThread, ) for model in bulk_model_list: has_more = bulk_delete_objects(model, group_id=object_id, logger=logger) if has_more: if continuous: delete_group.delay(object_id=object_id, countdown=15) return has_more = delete_events(relation={'group_id': object_id}, logger=logger) if has_more: if continuous: delete_group.delay(object_id=object_id, countdown=15) return group.delete()
def delete_group(object_id, continuous=True, **kwargs): from sentry.models import ( EventMapping, Group, GroupAssignee, GroupBookmark, GroupHash, GroupMeta, GroupResolution, GroupRuleStatus, GroupSnooze, GroupSubscription, GroupStatus, GroupTagKey, GroupTagValue, GroupEmailThread, GroupRedirect, UserReport ) try: group = Group.objects.get(id=object_id) except Group.DoesNotExist: return if group.status != GroupStatus.DELETION_IN_PROGRESS: group.update(status=GroupStatus.DELETION_IN_PROGRESS) bulk_model_list = ( # prioritize GroupHash GroupHash, GroupAssignee, GroupBookmark, GroupMeta, GroupResolution, GroupRuleStatus, GroupSnooze, GroupTagValue, GroupTagKey, EventMapping, GroupEmailThread, UserReport, GroupRedirect, GroupSubscription, ) for model in bulk_model_list: has_more = bulk_delete_objects(model, group_id=object_id, logger=logger) if has_more: if continuous: delete_group.delay(object_id=object_id, countdown=15) return has_more = delete_events(relation={'group_id': object_id}, logger=logger) if has_more: if continuous: delete_group.delay(object_id=object_id, countdown=15) return group.delete()
def delete_group(object_id, continuous=True, **kwargs): from sentry.models import ( Group, GroupHash, GroupRuleStatus, GroupTagKey, GroupTagValue, EventMapping ) try: group = Group.objects.get(id=object_id) except Group.DoesNotExist: return bulk_model_list = ( GroupHash, GroupRuleStatus, GroupTagValue, GroupTagKey, EventMapping ) for model in bulk_model_list: has_more = bulk_delete_objects(model, group_id=object_id, logger=logger) if has_more: if continuous: delete_group.delay(object_id=object_id, countdown=15) return has_more = delete_events(relation={'group_id': object_id}, logger=logger) if has_more: if continuous: delete_group.delay(object_id=object_id, countdown=15) return group.delete()
def delete_project(object_id, continuous=True, **kwargs): from sentry.models import ( Project, ProjectKey, ProjectStatus, TagKey, TagValue, GroupTagKey, GroupTagValue, Activity, EventMapping, Group, GroupEmailThread, GroupRuleStatus, GroupHash, GroupSeen, UserReport ) try: p = Project.objects.get(id=object_id) except Project.DoesNotExist: return if p.status == ProjectStatus.VISIBLE: raise DeleteAborted('Aborting project deletion as status is invalid') if p.status != ProjectStatus.DELETION_IN_PROGRESS: pending_delete.send(sender=Project, instance=p) p.update(status=ProjectStatus.DELETION_IN_PROGRESS) # XXX: remove keys first to prevent additional data from flowing in model_list = ( ProjectKey, TagKey, TagValue, GroupTagKey, GroupTagValue, EventMapping, Activity, GroupRuleStatus, GroupHash, GroupSeen, UserReport, GroupEmailThread ) for model in model_list: has_more = bulk_delete_objects(model, project_id=p.id, logger=logger) if has_more: if continuous: delete_project.delay(object_id=object_id, countdown=15) return has_more = delete_events(relation={'project_id': p.id}, logger=logger) if has_more: if continuous: delete_project.delay(object_id=object_id, countdown=15) return model_list = (Group,) for model in model_list: has_more = bulk_delete_objects(model, project_id=p.id, logger=logger) if has_more: if continuous: delete_project.delay(object_id=object_id, countdown=15) return p.delete()
def delete_tag_key(object_id, transaction_id=None, continuous=True, **kwargs): from sentry.models import ( EventTag, GroupTagKey, GroupTagValue, TagKey, TagKeyStatus, TagValue ) try: tagkey = TagKey.objects.get(id=object_id) except TagKey.DoesNotExist: return if tagkey.status != TagKeyStatus.DELETION_IN_PROGRESS: tagkey.update(status=TagKeyStatus.DELETION_IN_PROGRESS) bulk_model_list = ( GroupTagValue, GroupTagKey, TagValue ) for model in bulk_model_list: has_more = bulk_delete_objects(model, project_id=tagkey.project_id, key=tagkey.key, logger=logger) if has_more: if continuous: delete_tag_key.apply_async( kwargs={'object_id': object_id, 'transaction_id': transaction_id}, countdown=15, ) return has_more = bulk_delete_objects(EventTag, project_id=tagkey.project_id, key_id=tagkey.id, logger=logger) if has_more: if continuous: delete_tag_key.apply_async( kwargs={'object_id': object_id, 'transaction_id': transaction_id}, countdown=15, ) return tagkey_id = tagkey.id tagkey.delete() logger.info('object.delete.executed', extra={ 'object_id': tagkey_id, 'transaction_id': transaction_id, 'model': TagKey.__name__, })
def delete_project(object_id, continuous=True, **kwargs): from sentry.models import ( Project, ProjectKey, ProjectStatus, TagKey, TagValue, GroupTagKey, GroupTagValue, Activity, EventMapping, Group, GroupRuleStatus, GroupHash, GroupSeen, ) try: p = Project.objects.get(id=object_id) except Project.DoesNotExist: return if p.status != ProjectStatus.DELETION_IN_PROGRESS: p.update(status=ProjectStatus.DELETION_IN_PROGRESS) # XXX: remove keys first to prevent additional data from flowing in model_list = ( ProjectKey, TagKey, TagValue, GroupTagKey, GroupTagValue, EventMapping, Activity, GroupRuleStatus, GroupHash, GroupSeen, ) for model in model_list: has_more = bulk_delete_objects(model, project_id=p.id, logger=logger) if has_more: if continuous: delete_project.delay(object_id=object_id, countdown=15) return has_more = delete_events(relation={'project_id': p.id}, logger=logger) if has_more: if continuous: delete_project.delay(object_id=object_id, countdown=15) return model_list = (Group,) for model in model_list: has_more = bulk_delete_objects(model, project_id=p.id, logger=logger) if has_more: if continuous: delete_project.delay(object_id=object_id, countdown=15) return p.delete()
def delete_group(object_id, transaction_id=None, continuous=True, **kwargs): from sentry.models import ( EventMapping, Group, GroupAssignee, GroupBookmark, GroupCommitResolution, GroupHash, GroupMeta, GroupRelease, GroupResolution, GroupRuleStatus, GroupSnooze, GroupSubscription, GroupStatus, GroupTagKey, GroupTagValue, GroupEmailThread, GroupRedirect, UserReport ) try: group = Group.objects.get(id=object_id) except Group.DoesNotExist: return if group.status != GroupStatus.DELETION_IN_PROGRESS: group.update(status=GroupStatus.DELETION_IN_PROGRESS) bulk_model_list = ( # prioritize GroupHash GroupHash, GroupAssignee, GroupCommitResolution, GroupBookmark, GroupMeta, GroupRelease, GroupResolution, GroupRuleStatus, GroupSnooze, GroupTagValue, GroupTagKey, EventMapping, GroupEmailThread, GroupRedirect, GroupSubscription, UserReport, ) for model in bulk_model_list: has_more = bulk_delete_objects(model, group_id=object_id, logger=logger) if has_more: if continuous: delete_group.apply_async( kwargs={'object_id': object_id, 'transaction_id': transaction_id}, countdown=15, ) return has_more = delete_events(relation={'group_id': object_id}, logger=logger) if has_more: if continuous: delete_group.apply_async( kwargs={'object_id': object_id, 'transaction_id': transaction_id}, ) return features.delete(group) g_id = group.id group.delete() logger.info('object.delete.executed', extra={ 'object_id': g_id, 'transaction_id': transaction_id, 'model': Group.__name__, })
def delete_api_application(object_id, transaction_id=None, continuous=True, **kwargs): from sentry.models import ApiApplication, ApiApplicationStatus, ApiGrant try: app = ApiApplication.objects.get(id=object_id) except ApiApplication.DoesNotExist: return if app.status == ApiApplicationStatus.active: raise DeleteAborted if app.status != ApiApplicationStatus.deletion_in_progress: app.update(status=ApiApplicationStatus.deletion_in_progress) has_more = revoke_api_tokens(object_id) if has_more: if continuous: delete_api_application.apply_async( kwargs={ 'object_id': object_id, 'transaction_id': transaction_id, }, countdown=15, ) return bulk_model_list = (ApiGrant,) for model in bulk_model_list: has_more = bulk_delete_objects(model, application_id=app.id, logger=logger) if has_more: if continuous: delete_api_application.apply_async( kwargs={ 'object_id': object_id, 'transaction_id': transaction_id, }, countdown=15, ) return app.delete() logger.info('object.delete.executed', extra={ 'object_id': object_id, 'transaction_id': transaction_id, 'model': ApiApplication.__name__, })
def delete_group(object_id, transaction_id=None, continuous=True, **kwargs): from sentry.models import ( EventMapping, Group, GroupAssignee, GroupBookmark, GroupCommitResolution, GroupHash, GroupMeta, GroupRelease, GroupResolution, GroupRuleStatus, GroupSnooze, GroupSubscription, GroupStatus, GroupTagKey, GroupTagValue, GroupEmailThread, GroupRedirect, UserReport ) try: group = Group.objects.get(id=object_id) except Group.DoesNotExist: return if group.status != GroupStatus.DELETION_IN_PROGRESS: group.update(status=GroupStatus.DELETION_IN_PROGRESS) bulk_model_list = ( # prioritize GroupHash GroupHash, GroupAssignee, GroupCommitResolution, GroupBookmark, GroupMeta, GroupRelease, GroupResolution, GroupRuleStatus, GroupSnooze, GroupTagValue, GroupTagKey, EventMapping, GroupEmailThread, GroupRedirect, GroupSubscription, UserReport, ) for model in bulk_model_list: has_more = bulk_delete_objects(model, group_id=object_id, logger=logger) if has_more: if continuous: delete_group.apply_async( kwargs={'object_id': object_id, 'transaction_id': transaction_id}, countdown=15, ) return has_more = delete_events(relation={'group_id': object_id}, logger=logger) if has_more: if continuous: delete_group.apply_async( kwargs={'object_id': object_id, 'transaction_id': transaction_id}, ) return g_id = group.id group.delete() logger.info('object.delete.executed', extra={ 'object_id': g_id, 'transaction_id': transaction_id, 'model': Group.__name__, })
def delete_instance_bulk(self): try: return bulk_delete_objects(model=self.model, limit=self.chunk_size, transaction_id=self.transaction_id, **self.query) finally: # Don't log Group and Event child object deletions. model_name = self.model.__name__ if not _leaf_re.search(model_name): self.logger.info( 'object.delete.bulk_executed', extra=dict( { 'transaction_id': self.transaction_id, 'app_label': self.model._meta.app_label, 'model': model_name, }, **self.query))
def delete_instance_bulk(self): try: return bulk_delete_objects( model=self.model, limit=self.chunk_size, transaction_id=self.transaction_id, **self.query ) finally: self.logger.info( 'object.delete.bulk_executed', extra=dict( { 'transaction_id': self.transaction_id, 'app_label': self.model._meta.app_label, 'model': self.model.__name__, }, **self.query ) )
def delete_instance_bulk(self): try: return bulk_delete_objects(model=self.model, limit=self.chunk_size, transaction_id=self.transaction_id, partition_key=self.partition_key, **self.query) finally: # Don't log Group and Event child object deletions. model_name = self.model.__name__ if not _leaf_re.search(model_name): self.logger.info( "object.delete.bulk_executed", extra=dict( { "transaction_id": self.transaction_id, "app_label": self.model._meta.app_label, "model": model_name, }, **self.query), )
def delete_instance_bulk(self): try: return bulk_delete_objects( model=self.model, limit=self.chunk_size, transaction_id=self.transaction_id, **self.query ) finally: # Don't log Group and Event child object deletions. model_name = self.model.__name__ if not _leaf_re.search(model_name): self.logger.info( 'object.delete.bulk_executed', extra=dict( { 'transaction_id': self.transaction_id, 'app_label': self.model._meta.app_label, 'model': model_name, }, **self.query ) )
def delete_tag_key(object_id, continuous=True, **kwargs): from sentry.models import (GroupTagKey, GroupTagValue, TagKey, TagKeyStatus, TagValue) try: tagkey = TagKey.objects.get(id=object_id) except TagKey.DoesNotExist: return if tagkey.status != TagKeyStatus.DELETION_IN_PROGRESS: tagkey.update(status=TagKeyStatus.DELETION_IN_PROGRESS) bulk_model_list = (GroupTagValue, GroupTagKey, TagValue) for model in bulk_model_list: has_more = bulk_delete_objects(model, project_id=tagkey.project_id, key=tagkey.key, logger=logger) if has_more: if continuous: delete_tag_key.delay(object_id=object_id, countdown=15) return tagkey.delete()
def delete_project(object_id, continuous=True, **kwargs): from sentry.models import ( Project, ProjectKey, ProjectStatus, TagKey, TagValue, GroupTagKey, GroupTagValue, Activity, EventMapping, Group, GroupRuleStatus, GroupHash, GroupSeen, ) try: p = Project.objects.get(id=object_id) except Project.DoesNotExist: return if p.status == ProjectStatus.VISIBLE: raise DeleteAborted('Aborting project deletion as status is invalid') if p.status != ProjectStatus.DELETION_IN_PROGRESS: pending_delete.send(sender=Project, instance=p) p.update(status=ProjectStatus.DELETION_IN_PROGRESS) # XXX: remove keys first to prevent additional data from flowing in model_list = ( ProjectKey, TagKey, TagValue, GroupTagKey, GroupTagValue, EventMapping, Activity, GroupRuleStatus, GroupHash, GroupSeen, ) for model in model_list: has_more = bulk_delete_objects(model, project_id=p.id, logger=logger) if has_more: if continuous: delete_project.delay(object_id=object_id, countdown=15) return has_more = delete_events(relation={'project_id': p.id}, logger=logger) if has_more: if continuous: delete_project.delay(object_id=object_id, countdown=15) return model_list = (Group, ) for model in model_list: has_more = bulk_delete_objects(model, project_id=p.id, logger=logger) if has_more: if continuous: delete_project.delay(object_id=object_id, countdown=15) return p.delete()
def delete_project(object_id, transaction_id=None, continuous=True, **kwargs): from sentry.models import ( Activity, EventMapping, EventUser, Group, GroupAssignee, GroupBookmark, GroupEmailThread, GroupHash, GroupMeta, GroupRelease, GroupResolution, GroupRuleStatus, GroupSeen, GroupSubscription, GroupSnooze, GroupTagKey, GroupTagValue, Project, ProjectBookmark, ProjectKey, ProjectStatus, Release, ReleaseFile, SavedSearchUserDefault, SavedSearch, TagKey, TagValue, UserReport, ReleaseEnvironment, Environment ) try: p = Project.objects.get(id=object_id) except Project.DoesNotExist: return if p.status == ProjectStatus.VISIBLE: raise DeleteAborted('Aborting project deletion as status is invalid') if p.status != ProjectStatus.DELETION_IN_PROGRESS: pending_delete.send(sender=Project, instance=p) p.update(status=ProjectStatus.DELETION_IN_PROGRESS) # Immediately revoke keys project_keys = list(ProjectKey.objects.filter(project_id=object_id).values_list('id', flat=True)) ProjectKey.objects.filter(project_id=object_id).delete() for key_id in project_keys: logger.info('object.delete.executed', extra={ 'object_id': key_id, 'transaction_id': transaction_id, 'model': ProjectKey.__name__, }) model_list = ( Activity, EventMapping, EventUser, GroupAssignee, GroupBookmark, GroupEmailThread, GroupHash, GroupRelease, GroupRuleStatus, GroupSeen, GroupSubscription, GroupTagKey, GroupTagValue, ProjectBookmark, ProjectKey, TagKey, TagValue, SavedSearchUserDefault, SavedSearch, UserReport, ReleaseEnvironment, Environment ) for model in model_list: has_more = bulk_delete_objects(model, project_id=p.id, transaction_id=transaction_id, logger=logger) if has_more: if continuous: delete_project.apply_async( kwargs={'object_id': object_id, 'transaction_id': transaction_id}, countdown=15, ) return # TODO(dcramer): no project relation so we cant easily bulk # delete today has_more = delete_objects([GroupMeta, GroupResolution, GroupSnooze], relation={'group__project': p}, transaction_id=transaction_id, logger=logger) if has_more: if continuous: delete_project.apply_async( kwargs={'object_id': object_id, 'transaction_id': transaction_id}, countdown=15, ) return has_more = delete_events(relation={'project_id': p.id}, transaction_id=transaction_id, logger=logger) if has_more: if continuous: delete_project.apply_async( kwargs={'object_id': object_id, 'transaction_id': transaction_id}, ) return # Release needs to handle deletes after Group is cleaned up as the foreign # key is protected model_list = (Group, ReleaseFile, Release) for model in model_list: has_more = bulk_delete_objects(model, project_id=p.id, transaction_id=transaction_id, logger=logger) if has_more: if continuous: delete_project.apply_async( kwargs={'object_id': object_id, 'transaction_id': transaction_id}, countdown=15, ) return p_id = p.id p.delete() logger.info('object.delete.queued', extra={ 'object_id': p_id, 'transaction_id': transaction_id, 'model': Project.__name__, })
def delete_project(object_id, continuous=True, **kwargs): from sentry.models import ( Activity, EventMapping, Group, GroupAssignee, GroupBookmark, GroupEmailThread, GroupHash, GroupMeta, GroupResolution, GroupRuleStatus, GroupSeen, GroupTagKey, GroupTagValue, Project, ProjectBookmark, ProjectKey, ProjectStatus, Release, ReleaseFile, SavedSearchUserDefault, SavedSearch, TagKey, TagValue, UserReport ) try: p = Project.objects.get(id=object_id) except Project.DoesNotExist: return if p.status == ProjectStatus.VISIBLE: raise DeleteAborted('Aborting project deletion as status is invalid') if p.status != ProjectStatus.DELETION_IN_PROGRESS: pending_delete.send(sender=Project, instance=p) p.update(status=ProjectStatus.DELETION_IN_PROGRESS) # Immediately revoke keys ProjectKey.objects.filter(project_id=object_id).delete() model_list = ( Activity, EventMapping, GroupAssignee, GroupBookmark, GroupEmailThread, GroupHash, GroupSeen, GroupRuleStatus, GroupTagKey, GroupTagValue, ProjectBookmark, ProjectKey, TagKey, TagValue, SavedSearchUserDefault, SavedSearch, UserReport ) for model in model_list: has_more = bulk_delete_objects(model, project_id=p.id, logger=logger) if has_more: if continuous: delete_project.delay(object_id=object_id, countdown=15) return # TODO(dcramer): no project relation so we cant easily bulk # delete today has_more = delete_objects([GroupMeta, GroupResolution], relation={'group__project': p}, logger=logger) if has_more: if continuous: delete_project.delay(object_id=object_id, countdown=15) return has_more = delete_events(relation={'project_id': p.id}, logger=logger) if has_more: if continuous: delete_project.delay(object_id=object_id, countdown=15) return # Release needs to handle deletes after Group is cleaned up as the foreign # key is protected model_list = (Group, ReleaseFile, Release) for model in model_list: has_more = bulk_delete_objects(model, project_id=p.id, logger=logger) if has_more: if continuous: delete_project.delay(object_id=object_id, countdown=15) return p.delete()
def delete_project(object_id, continuous=True, **kwargs): from sentry.models import (Activity, EventMapping, Group, GroupAssignee, GroupBookmark, GroupEmailThread, GroupHash, GroupMeta, GroupResolution, GroupRuleStatus, GroupSeen, GroupTagKey, GroupTagValue, Project, ProjectBookmark, ProjectKey, ProjectStatus, Release, ReleaseFile, SavedSearchUserDefault, SavedSearch, TagKey, TagValue, UserReport) try: p = Project.objects.get(id=object_id) except Project.DoesNotExist: return if p.status == ProjectStatus.VISIBLE: raise DeleteAborted('Aborting project deletion as status is invalid') if p.status != ProjectStatus.DELETION_IN_PROGRESS: pending_delete.send(sender=Project, instance=p) p.update(status=ProjectStatus.DELETION_IN_PROGRESS) # Immediately revoke keys ProjectKey.objects.filter(project_id=object_id).delete() model_list = (Activity, EventMapping, GroupAssignee, GroupBookmark, GroupEmailThread, GroupHash, GroupSeen, GroupRuleStatus, GroupTagKey, GroupTagValue, ProjectBookmark, ProjectKey, TagKey, TagValue, SavedSearchUserDefault, SavedSearch, UserReport) for model in model_list: has_more = bulk_delete_objects(model, project_id=p.id, logger=logger) if has_more: if continuous: delete_project.delay(object_id=object_id, countdown=15) return # TODO(dcramer): no project relation so we cant easily bulk # delete today has_more = delete_objects([GroupMeta, GroupResolution], relation={'group__project': p}, logger=logger) if has_more: if continuous: delete_project.delay(object_id=object_id, countdown=15) return has_more = delete_events(relation={'project_id': p.id}, logger=logger) if has_more: if continuous: delete_project.delay(object_id=object_id, countdown=15) return # Release needs to handle deletes after Group is cleaned up as the foreign # key is protected model_list = (Group, ReleaseFile, Release) for model in model_list: has_more = bulk_delete_objects(model, project_id=p.id, logger=logger) if has_more: if continuous: delete_project.delay(object_id=object_id, countdown=15) return p.delete()