#26196: Django 1.9 ORM generates invalid subqueries for FK fields with
'to_field'
----------------------------------------------+--------------------
Reporter: hellpain | Owner: nobody
Type: Bug | Status: new
Component: Database layer (models, ORM) | Version: 1.9
Severity: Release blocker | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------------------+--------------------
Consider we have two models:
https://github.com/hellpain/django_to_field/blob/master/example/models.py
Product model referers to ProductCollection using Fk with 'to_field'.
Suppose I want to fetch all Products and I have already filtered
ProductCollections:
{{{
#!div style="font-size: 80%"
Code highlighting:
{{{#!python
product_collections = ProductCollection.objects.filter(id__gte=0)
products =
Product.objects.filter(collection__in=product_collections)
}}}
}}}
Queries in my project are a bit more complex, but this one has complexity
to show bug.
Generated query in django 1.8 looks like
{{{
#!div style="font-size: 80%"
Code highlighting:
{{{#!sql
SELECT "example_product"."id", "example_product"."collection_id" FROM
"example_product" WHERE "example_product"."collection_id" IN (SELECT
U0."slug" FROM "example_productcollection" U0 WHERE U0."id" >= 0)
}}}
}}}
As we see this is what we wanted to get.
Lets look what sql generates django 1.9
{{{
#!div style="font-size: 80%"
Code highlighting:
{{{#!sql
SELECT "example_product"."id", "example_product"."collection_id" FROM
"example_product" WHERE "example_product"."collection_id" IN (SELECT
U0."id" FROM "example_productcollection" U0 WHERE U0."id" >= 0)
}}}
}}}
Difference between them is in:
{{{
#!div style="font-size: 80%"
Code highlighting:
{{{#!sql
SELECT U0."id" and SELECT U0."slug"
}}}
}}}
As we see ORM on 1.9 didn`t took into attention that we have a 'to_field'
param in Product model. Query returns incorrect result.
This example project on github best of all shows problem:
https://github.com/hellpain/django_to_field/blob/master/example/tests.py
Tests are passing on 1.8 and fail on 1.9
If we wrap first query in list django starts to respect 'to_field' params
on both versions:
{{{
#!div style="font-size: 80%"
Code highlighting:
{{{#!python
product_collections = ProductCollection.objects.filter(id__gte=0)
products =
Product.objects.filter(collection__in=list(product_collections))
}}}
}}}
{{{
#!div style="font-size: 80%"
Code highlighting:
{{{#!sql
SELECT "example_product"."id", "example_product"."collection_id" FROM
"example_product" WHERE "example_product"."collection_id" IN (one, two,
three)
}}}
}}}
But we generate 2 queries and this is inefficient approach.
I suppose this bug is somehow connected with
https://docs.djangoproject.com/en/1.9/releases/1.9/#implicit-queryset-in-
lookup-removed
but this improvement influences only on incorrect code where 'in' operator
was skipped.
Perhaps while refactoring the issue above this bug have appeared.
May it be fixed in 1.9 release fixes? Can someone find place in django
code caused this degradation?
--
Ticket URL: <https://code.djangoproject.com/ticket/26196>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/051.229fec5f80fcbfe9295e729e759974e2%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.