【发布时间】:2013-06-21 09:03:48
【问题描述】:
我有一个 django 视图,它创建一个用户,然后将 user.pk 发送到 celery 任务 (.delay),以便通过电子邮件向用户发送电子邮件并通过一些我不希望的 API 调用将用户添加到邮件列表中风景。
在我保存新的用户实例user.save() 后,我将user.pk 发送到芹菜任务email_user_task.delay(user.pk),但芹菜任务因用户不存在的错误而爆炸。
我尝试在 celery 任务中添加一个 try except 块,并休眠以等待视图完成,这可以工作,但当站点繁忙并尝试使用手动事务提交时会导致其他问题,但我得到了其他问题错误并认为这应该可以工作。
@render_to('signup.html')
def signup(request):
if request.method == "POST":
form = SignupForm(request.POST, request=request)
if form.is_valid():
new_user = form.save(commit=False)
new_user.email = form.cleaned_data["email"]
new_user.fist_name = form.cleaned_data["first_name"]
new_user.last_name = form.cleaned_data["last_name"]
new_user.save()
email_user_task.delay(new_user.pk) # this cannot get the User from the pk
HttpResponseRedirect(reverse("signup_complete"))
else:
form = SignupForm(request=request)
return locals()
这个芹菜任务炸了:
@task
def email_user_task(user_pk):
user = User.objects.get(pk=user_pk) # this yeilds a User.DoesNotExist error
除非 5 秒还不够,否则我的第一个修复方法有效:
def email_user_task(user_pk):
try:
user = User.objects.get(pk=user_pk)
except User.DoesNotExist:
import time
time.sleep(5)
user = User.objects.get(pk=user_pk) # this works I'm guessing after the view finishes
我错过了什么?即为什么new_user.save() 在调用 celery 任务之前不写入数据库?
【问题讨论】:
-
您是否查看了数据库并查看用户是否实际创建?另外,celery 进程和 django 进程实际上是在看同一个数据库吗?
-
是的,这就是修复添加睡眠的原因。我还在本地禁用并失效了所有缓存以进行测试。
-
啊,对不起。误读了。你有没有在你的 Django 应用中启用ATOMIC_REQUESTS?
-
我认为 ATOMIC_REQUESTS 仅在 dev django 版本中