我正在从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
我对此升级代码所做的唯一更改是模型和迁移,以使用django.contrib.postgres.fields中的ArrayField和HStoreField而不是django_hstore等效项。
我的猜测是原始代码是错误的,但由于Django中的一个错误(filter / prefetch_related)而得以解决,该错误现已修复。那可能是正确的吗?如果实际上这是Django中的 new 错误,我不想编写依赖它的代码!
答案 0 :(得分:1)
Django在1.8和1.9之间的字段查找行为发生了变化,这解释了这一点-您可以在Django ticket #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 Documentation: Field Lookups