Ejecutar código después de la transacción de confirmación en Django
transactions signals (5)
Echa un vistazo a django-celery-transactions para encontrar una solución a esto.
Recientemente he terminado de dividir y refactorizar el código de las señales subyacentes en una aplicación independiente django-db-signals .
¿Hay alguna forma de ejecutar algún código después de la confirmación de transacción en Django?
Necesito enviar algunos mensajes a un servidor rabbitmq para su procesamiento fuera de línea, pero el mensaje llega al consumidor antes de que se comprometa la transacción de Django.
Mi mensaje se envía en la señal post_save del modelo. Lo que estoy buscando es un mecanismo similar, usando señales o algo más, que ejecute código después de la confirmación (y no haga nada si la transacción falla).
No he encontrado ninguna forma genérica de hacerlo en Django. ¿Tienes alguna idea?
Espero que esto pueda ayudar a alguien que use Django 1.9 o posterior. Desde 1.9 on_commit está disponible.
Así que básicamente lo harías así:
from django.db import transaction
transaction.on_commit(
lambda: send_msg_to_rabbitmqp(param1, param2, ...)
)
Si desea mantener post_save
, todavía puede usar on_commit
:
@receiver(pre_save, sender=MyModel)
def my_handler(sender, instance, created, **kwargs):
transaction.on_commit(
lambda: send_msg_to_rabbitmqp(instance.id)
)
He implementado señales de transacción ( post_commit
y post_rollback
) mediante el parche de mono django: http://gist.github.com/247844
Una posibilidad sería subclasificar el middleware de transacción para que envíe una señal personalizada en la confirmación. Su código podría escuchar esa señal, en lugar de post_save.
ACTUALIZACIÓN 2 : django-transaction-hooks se fusionó con el núcleo de Django y se lanzó en la versión 1.9 de Django.
ACTUALIZACIÓN : django-transaction-hooks resuelve este problema.
No creo que haya una manera limpia de hacer esto; Al menos no puedo pensar en uno. Podría monkeypatch django.db.transaction.commit para enviar una señal personalizada; No es bonito pero creo que funcionaría.
También podría ser interesante plantear este caso de uso en la lista de correo de django-developers . Los desarrolladores generalmente son reacios a agregar nuevas señales, pero podría tener un buen caso aquí (y una refutación de un desarrollador central puede incluir una sugerencia útil de cómo resolver su situación). Sin embargo, es más probable que obtengas respuestas si esperas hasta que sale 1.1.