Аннотация Django SearchRank не назначена, ошибка в производстве, но не разработчик - PullRequest
0 голосов
/ 21 мая 2019

Мое приложение Django (Apache / WSGI с бэкэндом Postgres) сталкивается с производственной ошибкой, которую я не могу воспроизвести в dev или при использовании оболочки Django на рабочей машине.Как я могу отладить это?

Приложение имеет модель Story

class Story(models.Model): 
    title = models.CharField(max_length=400)
    content = models.TextField(blank=True) 
    quality = models.FloatField(default=0)
    search = SearchVectorField(null=True)

с сигналом для заполнения search при сохранении:

@receiver(post_save, sender=Story) 
def update_search_vector(sender, instance, **kwargs):
   Story.objects.filter(pk=instance.pk).update(search=SearchVector('title', 'content'))

Когда пользовательпоиски, хочу вернуть релевантные и качественные результаты.Я присваиваю оценку как среднее гармоническое для этих двух значений:

query = SearchQuery(form.cleaned_data['query'])
stories = stories.annotate(
    rank=SearchRank(F('search'), query),
    score=F('rank') * F('quality') / (F('rank') + F('quality'))
).filter(rank__gte=SEARCH_RANK_CUTOFF).order_by('-score')

Это отлично работает в dev и на оболочке Django в производстве.Но при выполнении через работающее приложение возникает следующая ошибка: django.core.exceptions.FieldError: Cannot resolve keyword 'rank' into field.

У меня возникают проблемы с выяснением, как это отладить.Может ли это быть какое-то ошибочное кэширование набора запросов?

Вот полный текст трассировки ошибок:

ERROR 2019-05-21 11:59:03,388 Internal Server Error: /stories
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/django/core/handlers/exception.py", line 34, in inner
  response = get_response(request)
File "/usr/local/lib/python3.5/dist-packages/django/core/handlers/base.py", line 115, in _get_response
  response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.5/dist-packages/django/core/handlers/base.py", line 113, in _get_response
  response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/opt/myapp/myapp/views.py", line 75, in browse
  score=F('rank') * F('quality') / (F('rank') + F('quality'))
File "/usr/local/lib/python3.5/dist-packages/django/db/models/query.py", line 1056, in annotate
  clone.query.add_annotation(annotation, alias, is_summary=False)
File "/usr/local/lib/python3.5/dist-packages/django/db/models/sql/query.py", line 1000, in add_annotation
  summarize=is_summary)
File "/usr/local/lib/python3.5/dist-packages/django/db/models/expressions.py", line 446, in resolve_expression
  c.lhs = c.lhs.resolve_expression(query, allow_joins, reuse, summarize, for_save)
File "/usr/local/lib/python3.5/dist-packages/django/db/models/expressions.py", line 446, in resolve_expression
  c.lhs = c.lhs.resolve_expression(query, allow_joins, reuse, summarize, for_save)
File "/usr/local/lib/python3.5/dist-packages/django/db/models/expressions.py", line 511, in resolve_expression
  return query.resolve_ref(self.name, allow_joins, reuse, summarize, simple_col)
File "/usr/local/lib/python3.5/dist-packages/django/db/models/sql/query.py", line 1601, in resolve_ref
  join_info = self.setup_joins(field_list, self.get_meta(), self.get_initial_alias(), can_reuse=reuse)
File "/usr/local/lib/python3.5/dist-packages/django/db/models/sql/query.py", line 1504, in setup_joins
  names[:pivot], opts, allow_many, fail_on_missing=True,
File "/usr/local/lib/python3.5/dist-packages/django/db/models/sql/query.py", line 1420, in names_to_path
  "Choices are: %s" % (name, ", ".join(available)))
django.core.exceptions.FieldError: Cannot resolve keyword 'rank' into field. Choices are: content, id, quality, search, title

У меня установлены те же версии зависимостей (через requirements.txt), но я заметил, чтопроизводство работает на python3.5.2, в то время как dev работает 3.7.3.(И, возможно, libapache2-mod-wsgi-py3 вызывает другую версию?) Это похоже на возможное место для изучения, но я не понимаю, как аннотация, добавляющая rank, может потерпеть неудачу без другого исключения.

...