-
-
Notifications
You must be signed in to change notification settings - Fork 284
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
select_related and prefetch_related for inherited models #198
Comments
Thanks for the report! You've identified a spot where polymorphic isn't present yet. I'm not sure this can be solved; the also see #37 for a related issue. |
I played around with select related in the child models, and figured I need to create a manager for the
However the I think that if this line didn't exist, we would have a good chance so we can do I traced the history to 2010 and previous of this line. It seems to be there since the beginning. Could we do something like:
So that we don't override the select related config here? |
Are there any plans on supporting this and/or is any help needed? |
I like the assignment of the |
Actually I think it shall trigger any Django errors if something is wrong. The |
You would make me the happiest man in the world if there was a solution to this. I have many relationships in child models and the number of queries is too high. Thank you for your work @vdboor! |
While working on #244, I uncovered something that might be useful, assume these models: class Parent(PolymorphicModel):
pass
class ChildA(Parent):
name = models.CharField()
class ChildB(Parent):
height = models.IntegerField() This works: obj = Parent.objects.non_polymorphic().select_related('childa__name')
obj.childa.name # return the name! Although this doesn't: Parent.objects.select_related('childa__name')
# childa is an invalid field name here So we clearly don't need to fiddle with django's internals to get this issue fixed. I believe that we can actually deal with the |
Project maintainers: my employer is interested in putting a bounty on this ticket, for supporting both |
@vdboor ^^ |
FWIW, I'd chime in with a few dollars to a bounty for this -- I'd be able to make huge optimizations if this feature works. The same goes for #244. |
I want to press the question that @smcoll asked here, and express my own strong interest in getting this problem solved.
Frankly I don't have a problem with the syntax |
I would love a solution for this as well... I have to find a solution for the relationships in my child models in order to get a reasonable performance... |
Also interested in putting some dollars in a bounty.
|
Any updates on this? I would love to put in a bounty for this as well. |
Maybe we can use something like Bountysource to actually make these bounties a reality? There's plenty of us really wanting this implemented! |
@vdboor what factors would need to be considered for a PR to be merged (like the lookup syntax)? That could be the scope of the bounty ticket. There has been plenty of interest in funding a solution- we just need coordination from a project maintainer so we know the funded work will be accepted into the codebase. |
Ideally, the syntax should be the same as django's Another alternative is to have something like: queryset.select_polymorphic_related(
SubClassA,
'relation__to___subclass__a',
) This allows more explicit checks that the field actually exists for some subclass. |
Any updates on this? I'm currently having this issue. |
EDIT: Nevermind, I think this addresses a different issue Does this solve the problem for anyone? Based on work by AndySun25 from this discussion: #244 |
It previously depended on a private Django internal class that changed with Django 3.1. I've switched here instead to disabling the django-polymorphic accessors to get the underlying UnifiedJob object for a Job, which due to the way they implement those was resulting in N+1 behavior on deletes. This gets us back most of the way to the performance gains we achieved with the custom collector class. See jazzband/django-polymorphic#198.
By the way it appears doing a plain select_related() (without specifying fields) on the parent queryset works to select related instances on child classes, if this helps anyone |
This limitation made me switch to using the InheritanceManager from django-model-utils instead. I found this walkthrough of the alternatives helpful: |
Seems like this guy solved this issue. Need more tests I think, but I've tested tons of cases and so far so good. |
if only this project wasn't abandoned... edit:
thanks for this. InheritanceManager might be the move |
I was able to prefetch related polymorphic child subclass using Prefetch Given this relations: #models.py
class Respondent(PolymorphicModel):
name = models.CharField()
class ChildRespondent(Respondent):
extra = models.CharField()
class Answer(models.Model):
respondent = models.ForeignKey(Respondent) from django.db.models import Prefetch
# Get answers together with ChildRespondent instances
for answer in Answer.objects.prefetch_related(Prefetch("respondent", queryset=ChildRespondent.objects.all(), to_attr="child_respondent"):
assert isinstance(answer.child_respondent, ChildRespondent) Not the cleanest solution since polymorphism is lost, but at least the n+1 problem is solved. |
implement support for a single query for select related base fetches across polymorphic models. adds a polymorphic QuerySet Mixin to enable non polymorphic models to fetch related models. Fixes: jazzband#198 jazzband#436 jazzband#359 jazzband#244 Possible Fixes: jazzband#498: support for prefetch_related cannot fetch attributes not on all child models or via class names Related: jazzband#531
implement support for a single query for select related base fetches across polymorphic models. adds a polymorphic QuerySet Mixin to enable non polymorphic models to fetch related models. fixes: jazzband#198 jazzband#436 jazzband#359 jazzband#244 possible fixes: jazzband#498: support for prefetch_related cannot fetch attributes not on all child models or via class names related: jazzband#531
implement support for a single query for select related base fetches across polymorphic models. adds a polymorphic QuerySet Mixin to enable non polymorphic models to fetch related models. fixes: jazzband#198 jazzband#436 jazzband#359 jazzband#244 possible fixes: jazzband#498: support for prefetch_related cannot fetch attributes not on all child models or via class names related: jazzband#531
implement support for a single query for select related base fetches across polymorphic models. adds a polymorphic QuerySet Mixin to enable non polymorphic models to fetch related models. fixes: jazzband#198 jazzband#436 jazzband#359 jazzband#244 possible fixes: jazzband#498: support for prefetch_related cannot fetch attributes not on all child models or via class names related: jazzband#531
implement support for a single query for select related base fetches across polymorphic models. adds a polymorphic QuerySet Mixin to enable non polymorphic models to fetch related models. fixes: jazzband#198 jazzband#436 jazzband#359 jazzband#244 possible fixes: jazzband#498: support for prefetch_related cannot fetch attributes not on all child models or via class names related: jazzband#531
Regarding the documentation:
Is there a chance you will implement this? I mean select_related and prefetch_related for the inherited models, It would be really helpful. Because I don't know how to optimize some requests now. Thank you.
The text was updated successfully, but these errors were encountered: