4

Upgrading to Django 1.6 has introduced a tricky problem into my code: database operations that are triggered by a post_save signal are getting contained within the with transaction.atomic(): block of Django's get_or_create().

The impact for me is that custom sql (unmanaged) isn't getting committed to the db in time.

Is there a different signal that I can use that gets sent after obj.save() exits its atomic block?

Or have I diagnosed this wrong?

probabble
  • 444
  • 4
  • 13
  • apparently this has been a [ticket/discussion for years now](https://code.djangoproject.com/ticket/14051)... which led me to [this module](https://github.com/aaugustin/django-transaction-signals) which adds transaction-level signals. – probabble Feb 12 '14 at 23:22
  • but to clarify the question: is the post_save signal getting fired from within that atomic block, causing all code run by that signal to be executed with autocommit turned off? – probabble Feb 12 '14 at 23:24

3 Answers3

6

Django's get_or_create() executes its save() in an atomic block, and signals fired post_save are nested within that atomic block.

My workaround was to override the native get_or_create() with my own version in a custom manager, without the transaction.atomic() block.

probabble
  • 444
  • 4
  • 13
0

for the signal to function properly you need out of the atomic transaction, because in the midst of shooting transsaccion signal without the commmit in the database.

alfonsoolavarria
  • 1,141
  • 11
  • 11
0

Old question, but I came across this today.

Django >=1.9 supports transaction.on_commit hooks.

Here's how my resulting code came out, and appears to behave as expected:

from django.db import transaction

def my_post_save_hook(sender, instance):
    transaction.on_commit(
        lambda: do_the_thing()
    )

post_save.connect(my_post_save_hook, sender=MyModel)
Red Twoon
  • 685
  • 4
  • 14