Django – Delay in creating database entry
Question:
I have a Django app where I create a db entry in the view. I then want to perform background processing on the new entry. Instead of sending the created object to the task, I send the object’s id then the background task can fetch the db object as explained here. Below is my code:
# In tasks.py
@shared_task
def my_task(model_id):
my_model = MyModel.objects.get(pk=model_id)
# Do stuff with my_model
# In views.py:
def some_view(request):
if request.method == 'POST' and request.is_ajax():
instance = MyModel.objects.create(**kwargs)
tasks.my_task.delay(instance.id)
....
However, when I try to get the object in the background task, I get matching query does not exist error. If I add sleep(1)
before getting the object, it works as excepted. I do not understand why I’m getting this error, since the object should be in the DB? Does anybody know how to solve this? I don’t really want to add a sleep command everywhere.
I’m using Postgres as my DB.
Answers:
Try this
from django.db import transaction
with transaction.atomic():
instance = MyModel.objects.create(**kwargs)
tasks.my_task.delay(instance.id)
https://docs.djangoproject.com/en/4.1/topics/db/transactions/
Performing actions after commit Sometimes you need to perform an
action related to the current database transaction, but only if the
transaction successfully commits. Examples might include a Celery
task, an email notification, or a cache invalidation.
Django provides the on_commit()
function to register callback
functions that should be executed after a transaction is successfully
committed:
on_commit(func, using=None)
I have a Django app where I create a db entry in the view. I then want to perform background processing on the new entry. Instead of sending the created object to the task, I send the object’s id then the background task can fetch the db object as explained here. Below is my code:
# In tasks.py
@shared_task
def my_task(model_id):
my_model = MyModel.objects.get(pk=model_id)
# Do stuff with my_model
# In views.py:
def some_view(request):
if request.method == 'POST' and request.is_ajax():
instance = MyModel.objects.create(**kwargs)
tasks.my_task.delay(instance.id)
....
However, when I try to get the object in the background task, I get matching query does not exist error. If I add sleep(1)
before getting the object, it works as excepted. I do not understand why I’m getting this error, since the object should be in the DB? Does anybody know how to solve this? I don’t really want to add a sleep command everywhere.
I’m using Postgres as my DB.
Try this
from django.db import transaction
with transaction.atomic():
instance = MyModel.objects.create(**kwargs)
tasks.my_task.delay(instance.id)
https://docs.djangoproject.com/en/4.1/topics/db/transactions/
Performing actions after commit Sometimes you need to perform an
action related to the current database transaction, but only if the
transaction successfully commits. Examples might include a Celery
task, an email notification, or a cache invalidation.Django provides the
on_commit()
function to register callback
functions that should be executed after a transaction is successfully
committed:
on_commit(func, using=None)