запустить код после транзакции в Django - PullRequest
17 голосов
/ 04 июня 2009

Есть ли способ запустить некоторый код после фиксации транзакции в Django?

Мне нужно отправить некоторые сообщения на сервер rabbitmq для автономной обработки, но сообщение доходит до потребителя до того, как транзакция Django будет зафиксирована.

Мое сообщение отправлено в сигнале post_save модели. Я ищу похожий механизм, использующий сигналы или что-то еще, который будет выполнять код после фиксации (и ничего не делать в случае сбоя транзакции).

Я не нашел никакого общего способа сделать это в Django. У вас есть идеи?

Ответы [ 5 ]

10 голосов
/ 04 июня 2009

ОБНОВЛЕНИЕ 2 : крючки-транзакции django объединены в ядро ​​Django и выпущены в версии 1.9 Django.

ОБНОВЛЕНИЕ : django -action-hooks решает эту проблему.

Я не верю, что есть чистый способ сделать это; по крайней мере, я не могу думать об этом. Вы можете monkeypatch django.db.transaction.commit, чтобы отправить пользовательский сигнал; не красиво, но я думаю, что это будет работать.

Также было бы интересно поднять этот вариант использования в списке рассылки django-developers . Разработчики, как правило, не хотят добавлять новые сигналы, но у вас может быть хороший пример (и опровержение от основного разработчика может содержать полезное предложение о том, как разрешить вашу ситуацию). Вы, скорее всего, получите ответы, если будете ждать, пока не выйдет версия 1.1.

7 голосов
/ 12 января 2016

Надеюсь, что это может помочь кому-то, использующему Django 1.9 или новее. Начиная с версии 1.9 on_commit .

Так что в основном вы бы делали это так:

from django.db import transaction

transaction.on_commit(
    lambda: send_msg_to_rabbitmqp(param1, param2, ...)
)

Если вы хотите сохранить post_save, вы все равно можете использовать on_commit:

@receiver(pre_save, sender=MyModel)
def my_handler(sender, instance, created, **kwargs):
    transaction.on_commit(
        lambda: send_msg_to_rabbitmqp(instance.id)
    )
5 голосов
/ 03 декабря 2009

Я реализовал сигналы транзакции (post_commit и post_rollback), установив патчи для django: http://gist.github.com/247844

1 голос
/ 24 декабря 2012

Посмотрите на django-celery-Transactions , чтобы найти решение этой проблемы.

Я недавно закончил разделение и рефакторинг кода кода сигналов в автономное приложение django-db-сигналов .

1 голос
/ 04 июня 2009

Одной из возможностей было бы создание подкласса промежуточного программного обеспечения транзакции, чтобы он отправлял пользовательский сигнал при фиксации. Ваш код может прослушивать этот сигнал, а не post_save.

...