Сельдерей и Джанго, запросы вызывают 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
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
Переменная в этот контейнер вручную, и все снова заработало. Глупая ошибка с моей стороны, но я надеюсь, что смогу сэкономить время для кого-то с этим ответом.