0

I'm aware that signals aren't triggered for bulk updates, however, I need this behaviour. I'm wondering which of these two ways is more efficient:

qs = MyObject.objects.all()
  1. Do a bulk update, then in a loop manually trigger the signal for each instance:

    qs.update(active=True)
    for instance in qs:
        post_save.send(sender=MyObject, instance=instance)
    
  2. Loop the qs and call save on each instance:

    for instance in qs:
        instance.active = True
        instance.save(update_fields=['active'])
    
gdvalderrama
  • 713
  • 1
  • 17
  • 26
  • ... the manual save defeats the benefits of the bulk update. You'd get one update query for each `.save()`. – dhke Feb 07 '17 at 17:56
  • @dhke so there are no downsides to the manual trigger within a loop? – gdvalderrama Feb 07 '17 at 18:12
  • I didn't claim that, but it's more or less the same what [`.save()`](https://github.com/django/django/blob/cd69ac06d6e415f74e9566aa6473e8b577e29074/django/db/models/base.py#L832) does. But you will be relying on undocumented behavior nonetheless. – dhke Feb 07 '17 at 18:40
  • Depends on query objects count it would be big or huge performance improvement with one update query.. Besides that, manual signal triggering is absolutely common thing. Why you say that it would be "undocumented behavior"? – Alex T Feb 07 '17 at 19:08
  • The only efficient solution is to do bulk update, then trigger signal manually. – Dmitry Shilyaev Feb 07 '17 at 19:25
  • @AlexT Triggering a signal that does not belong to you? The semantics of `post_save` are defined by the ORM. If you deliver the signal from your own code that is fine, but you a) added technical debt and b) re-coded the ORM's signal delivery semantics in your code. If you can live with that: fine by me. But it's not "no downsides", but rather "heed that this may stop working sometime in the future". – dhke Feb 07 '17 at 21:13

0 Answers0