Django обновить фильтр /prefetch_related изменение поведения?

Я нахожусь в процессе обновления с Django 1.8.19 до 1.11.15, и я нашел кусок кода, который ломается.

В частности, этот запрос делает что-то отличное от того, что он делал раньше.

project_groups = brand.project_groups.prefetch_related(
   'project', 'project__score', 'project__themes').filter(
   project=projects
).distinct()

Ранее (в Django 1.8), согласно выводу "project_groups.query", он создавал SQL, в том числе:

... projectgroup.project_id IN [projects query]

Теперь он производит чтение SQL:

... projectgroup.project_id = [projects query]

Это прерывается, поскольку [проектный запрос] возвращает более одной строки. Итак, я получаю:

ProgrammingError: more than one row returned by a subquery used as an expression

Единственные изменения, которые я внес в код для этого обновления, касаются моделей и миграций для использования ArrayField и HStoreField из django.contrib.postgres.fields вместо django_hstore эквивалентов.

Я предполагаю, что оригинальный код был неправильным, но работал из-за ошибки в Django (filter/prefetch_related), которая теперь была исправлена. Это может быть правильно? Если это на самом деле новая ошибка в Django, я не хочу писать код, который опирается на это!

1 ответ

Решение

Произошло изменение в поведении Django при поиске в поле между 1.8 и 1.9, что объясняет это - вы можете увидеть детали в билете Django № 25284.

В Django 1.8 такой запрос, как Model.objects.filter(related_id = RelatedModel.objects.all()) раньше приводил к неявному поиску __in, поэтому SQL-запрос содержал related_id IN (SELECT id FROM ...), Но в Django 1.9 "IN" изменяется на "=", что приводит к разрыву запроса в MySql и Postgres. Изменение было классифицировано как исправление ошибки, поскольку неявное поведение "IN" было недокументированным и, вероятно, случайным.

Вы должны иметь возможность довольно легко исправить запрос, добавив явный тип поиска к полевому поиску, такой как .filter(project__in=projects) - см. документацию Django: полевые поиски

Другие вопросы по тегам