Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

387
Visualizações
¿Cuál es la forma más eficiente de verificar si hay huérfanos al eliminar objetos en Django?

Digamos que tengo un modelo con una tabla Things y una tabla de relaciones entre las cosas llamada ThingRelations . No debería ser posible eliminar una Thing cuando hay ThingRelations que apuntan a ella, y cuando no hay más ThingRelations que apuntan a una Thing determinada, debe eliminarse. Actualmente estoy tratando de implementar eso con signals.post_delete así:

 from django.db import models class ThingRelation(models.Model): first_thing = models.ForeignKey('Thing', on_delete=models.PROTECT) second_thing = models.ForeignKey('Thing', on_delete=models.PROTECT) class Thing(models.Model): name = CharField(max_length=260) @receiver(models.signals.post_delete, sender=ThingRelation) def check_relation_and_delete(sender, instance, *args, **kwargs): for thing_id in [instance.first_thing, instance.second_thing]: first_thing_match = ThingRelation.objects.filter(first_thing=thing_id).exists() second_thing_match = ThingRelation.objects.filter(second_thing=thing_id).exists() if not first_thing_match and not second_thing_match: Thing.objects.get(pk=thing_id).delete()

¿Es esta la forma más eficiente de encontrar y eliminar Things huérfanas? Soy muy nuevo en las bases de datos en general, pero ¿no será lento filtrar la tabla Things (potencialmente bastante grande) cuatro veces por cada ThingRelation eliminada al eliminar muchos objetos a la vez? ¿Existe algún tipo de funcionalidad SQL o Django que haga que este código no se ejecute para cada objeto en una operación masiva?

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

signals.py no está diseñado para operaciones masivas . Además, a menudo se los considera un antipatrón , debido a la dificultad de rastrearlos cuando se intenta depurar alguna lógica.

Prefiero aconsejarle que pruebe el enfoque de rutina aquí. Un ejemplo, que te puede ser útil:

 def remove_orphaned_things(): orphaned_things = Thing.objects.filter( ~Q(id__in=ThingRelation.objects.values_list('first_thing_id').filter( first_thing_id=OuterRef('pk') ) | ~Q(id__in=ThingRelation.objects.values_list('second_thing_id').filter( second_thing_id=OuterRef('pk') ) ).delete()

Esta función elimina todas las cosas Thing . Así que todo lo que queda es que necesitamos llamarlo correctamente.

La forma más fácil y directa es organizarlo en una rutina interminable while-true sleep y ejecutarlo como un demonio. Por ejemplo:

 from datetime import time from django.core.management import BaseCommand # Also some import of `remove_orphaned_things` class Command(BaseCommand): def handle(self, *args, **options): while True: remove_orphaned_things() time.sleep(300)

Por lo tanto, se ejecutaría casi una vez cada 5 minutos. Podría ejecutarse con algo como supervisor (mejor) o tmux (peor), para que pueda estar seguro de que siempre se está ejecutando.

La mejor manera es usar algo como periodic para orquestarlo. Aquí hay una guía de instalación (también necesitaría RabbitMQ) y un pequeño ejemplo de cómo organizarlo:

 @dramatiq.actor(periodic=cron('*/5 * * * *'), max_retries=0) def remove_orphaned_things(): # Exact the same code of `remove_orphaned_things`

¡Buena suerte!

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda