strawberry-graphql / strawberry-django

Strawberry GraphQL Django extension
MIT License
391 stars 115 forks source link

Deduce model field names from custom prefetches #473

Open diesieben07 opened 4 months ago

diesieben07 commented 4 months ago

Description

Currently the QuerySet optimizer is oblivious to custom prefetch_related like the following:

@strawberry_django.type(models.Project)
class ProjectType(models.Project):
      @strawberry_django.field(
        prefetch_related=lambda _: Prefetch(
            "milestones",
            to_attr="next_milestones_pf",
            queryset=Milestone.objects.filter(due_date__isnull=False).order_by("due_date")
        )
    )
    def next_milestones(self) -> "list[MilestoneType]":
        return self.next_milestones_pf

The current optimizer cannot understand how to optimize "through" this prefetch, because it cannot find the model field (milestones in Project) that the field uses. This results in the optimization essentially stopping at the next_milestones field and any further nested relations will cause N+1 issues.

This pull request attempts to address this shortcoming.

Types of Changes

Now the optimizer first inspects the field configuration to find any custom Prefetch. A custom prefetch is one which has a custom to_attr set. The optimizer then uses these custom Prefetches to perform further optimization instead of stopping here.

Issues Fixed or Closed by This PR

Checklist

diesieben07 commented 4 months ago

Some guidance on the test failures would be great. I am not 100% sure what the correct approach would be for the changed GraphQL schema.

codecov-commenter commented 4 months ago

Codecov Report

Attention: Patch coverage is 83.01887% with 9 lines in your changes are missing coverage. Please review.

Project coverage is 88.21%. Comparing base (5c999e9) to head (746ec95). Report is 20 commits behind head on main.

Files Patch % Lines
strawberry_django/optimizer.py 83.01% 9 Missing :warning:
Additional details and impacted files ```diff @@ Coverage Diff @@ ## main #473 +/- ## ========================================== + Coverage 87.90% 88.21% +0.30% ========================================== Files 37 37 Lines 3166 3215 +49 ========================================== + Hits 2783 2836 +53 + Misses 383 379 -4 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

diesieben07 commented 4 months ago

@bellini666 I think all the linting and type errors should be resolved now and the snapshot test fixed.