1

I want to develop an application that monitors the database for new records and allows me to execute a method in the context of my Django application when a new record is inserted.

I am planning to use an approach where a Celery task checks the database for changes since the last check and triggers the above method.

Is there a better way to achieve this?

I'm using SQLite as the backend and tried apsw's setupdatehook API, but it doesn't seem to run my module in Django context.

NOTE: The updates are made by a different application outside Django.

VLAZ
  • 26,331
  • 9
  • 49
  • 67
user1908488
  • 189
  • 3
  • 9

2 Answers2

5

Create a celery task to do whatever it is you need to do with the object:

tasks.py

from celery.decorators import task

@task()
def foo(object):
    object.do_some_calculation()        

Then create a django signal that is fired every time an instance of your Model is saved , queuing up your task in Celery:

models.py

class MyModel(models.Model):
    ...

from django.db.models.signals import post_save
from django.dispatch import receiver
from mymodel import tasks

@receiver(post_save, sender=MyModel)
def queue_task(sender, instance, created, **kwargs):
    tasks.foo.delay(object=instance)

What's important to note that is django's signals are synchronous, in other words the queue_task function runs within the request cycle, but all the queue_task function is doing is telling Celery to handle the actual guts of the work (do_some_calculation) in theb background

Timmy O'Mahony
  • 53,000
  • 18
  • 155
  • 177
  • Ah, I didn't notice the note that says the records are updated/saved outside of the Django app, so this answer won't work but might be useful for others with a similar query but with the updates/saves within django – Timmy O'Mahony Mar 29 '13 at 22:29
1

A better way would be to have that application that modifies the records call yours. Or at least make a celery queue entry so that you don't really have to query the database too often to see if something changed.

But if that is not an option, letting celery query the database to find if something changed is probably the next best option. (surely better than the other possible option of calling a web service from the database as a trigger, which you should really avoid.)

lprsd
  • 84,407
  • 47
  • 135
  • 168