Celery и Django, запросы вызывают ProgrammingError

Я создаю небольшой проект Django с cookiecutter-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


person JanBrinker    schedule 05.03.2018    source источник


Ответы (1)


Я нашел свою ошибку. Если вы уверены, что ваша база данных перенесена правильно, и вы получаете ошибки, как указано выше: вполне может быть, что вы не можете подключиться к базе данных. Ваш хост базы данных может быть доступен, но не сама база данных.

Это означает, что ваш конфиг, вероятно, сломан.

Почему он был неправильно настроен: в случае с cookiecutter-django есть проблема, из-за которой Celery может жаловаться на запуск от имени пользователя root на Mac, поэтому я установил переменную среды C_FORCE_ROOT в моем файле docker-compose. [Только для локальной сети, никогда не делайте этого в рабочей среде!] Прочитайте об этой проблеме здесь 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 предотвратила установку переменных среды django в контейнере celeryworker, оставив меня с несуществующей конфигурацией базы данных.

Я добавил переменную POSTGRES_USER в этот контейнер вручную, и все снова заработало. Глупая ошибка с моей стороны, но я надеюсь, что смогу сэкономить время для кого-то с этим ответом.

person JanBrinker    schedule 13.03.2018