Celery和Django,查询导致ProgrammingError

时间:2018-03-05 18:32:17

标签: django celery cookiecutter-django

我正在使用cookiecutter-django构建一个小型Django项目,我需要在后台运行任务。即使我用cookiecutter设置项目,我也面临着与Celery的一些问题。

假设我有一个名为Job的模型类,其中包含三个字段:默认主键,UUID和日期:

class Job(models.Model):
    access_id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
    date = models.DateTimeField(auto_now_add=True)

现在如果我在Django视图中执行以下操作,一切正常:

job1 = Job()
job1.save()
logger.info("Created job {}".format(job1.access_id))

job2 = Job.objects.get(access_id=job1.access_id)
logger.info("Retrieved job {}".format(job2.access_id))

如果我创建一个完全相同的Celery任务,我会收到错误:

django.db.utils.ProgrammingError: relation "metagrabber_job" does not exist
LINE 1: INSERT INTO "metagrabber_job" ("access_id", "date") VALUES ('e8a2...

同样,这就是我的Postgres码头工人容器当时所说的:

postgres_1      | 2018-03-05 18:23:23.008 UTC [85] STATEMENT:  INSERT INTO "metagrabber_job" ("access_id", "date") VALUES ('e8a26945-67c7-4c66-afd1-bbf77cc7ff6d'::uuid, '2018-03-05T18:23:23.008085+00:00'::timestamptz) RETURNING "metagrabber_job"."id"

有趣的是,如果我查看我的Django管理员,我确实看到Job对象创建的,但它带有一个不同的UUID,如日志所说..

如果我然后设置CELERY_ALWAYS_EAGER = False以使Django执行任务而不是Celery:瞧,它再次正常工作而没有错误。但是在Django中运行任务并非如此。

我做了很多搜索,我只发现了解决方案运行manage.py migrate的类似问题。但是我已经这样做了,这不是解决方案,否则Django无论是否使用Celery都无法执行有问题的代码。

那是怎么回事?我为所有模型对象获得了完全相同的行为。

编辑: 为了以防万一,我使用Django 2.0.2和Celery 4.1

1 个答案:

答案 0 :(得分:0)

我发现了自己的错误。如果您确定数据库已正确迁移并且出现上述错误:很可能是您无法连接到数据库。您的数据库主机可能已到达,但不是数据库本身。

这意味着您的配置可能已损坏。

为什么它配置错误:在cookiecutter-django的情况下,Celery可能会抱怨在Mac上以root用户身份运行,因此我在docker-compose文件中设置了环境变量C_FORCE_ROOT。 [仅限本地,您应该从不在制作中执行此操作!]在此处阅读此问题https://github.com/pydanny/cookiecutter-django/issues/1304

配置的相关部分如下所示:

django: &django
  build:
    context: .
    dockerfile: ./compose/local/django/Dockerfile
  depends_on:
    - postgres
  volumes:
    - .:/app
  environment:
    - POSTGRES_USER=asdfg123456
    - USE_DOCKER=yes
  ports:
    - "8000:8000"
    - "3000:3000"
  command: /start.sh

celeryworker:
  <<: *django
  depends_on:
    - redis
    - postgres
  environment:
    - C_FORCE_ROOT=true
  ports: []
  command: /start-celeryworker.sh

然而通过docker-compose文件设置此环境变量会阻止在celeryworker容器上设置django环境变量,从而使我的数据库配置不存在。

我手动将POSTGRES_USER变量添加到该容器中,事情又开始起作用了。我的愚蠢错误,但我希望我可以为有这个答案的人节省一些时间。