Skip to content
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

feat: Avoid joins when only fetching an ID #483

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion strawberry_django/fields/field.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,24 @@
result = getattr(source, attr.field.attname)
elif isinstance(attr, ForwardManyToOneDescriptor):
# This will raise KeyError if it is not cached
result = attr.field.get_cached_value(source) # type: ignore
try:
result = attr.field.get_cached_value(source) # type: ignore
except KeyError:
selected_field = next(
f for f in info.selected_fields if f.name == info.field_name

Check failure on line 190 in strawberry_django/fields/field.py

View workflow job for this annotation

GitHub Actions / Typing

"selected_fields" is not a known member of "None" (reportOptionalMemberAccess)

Check failure on line 190 in strawberry_django/fields/field.py

View workflow job for this annotation

GitHub Actions / Typing

Cannot access member "name" for type "InlineFragment"   Member "name" is unknown (reportAttributeAccessIssue)

Check failure on line 190 in strawberry_django/fields/field.py

View workflow job for this annotation

GitHub Actions / Typing

"field_name" is not a known member of "None" (reportOptionalMemberAccess)
)
target_attname = attr.field.target_field.attname

Check failure on line 192 in strawberry_django/fields/field.py

View workflow job for this annotation

GitHub Actions / Typing

Cannot access member "target_field" for type "Field[Any, Any]"   Member "target_field" is unknown (reportAttributeAccessIssue)
if (
len(selected_field.selections) == 1
and selected_field.selections[0].name == target_attname

Check failure on line 195 in strawberry_django/fields/field.py

View workflow job for this annotation

GitHub Actions / Typing

Cannot access member "name" for type "InlineFragment"   Member "name" is unknown (reportAttributeAccessIssue)
):
# If we are only retrieving the referenced `id` of a related foreignkey with no additional columns
# then we can optimize away this retrieval by reusing the existing value from the `source` object.
value = source.__dict__[attr.field.get_attname()]
target_model = attr.field.target_field.model

Check failure on line 200 in strawberry_django/fields/field.py

View workflow job for this annotation

GitHub Actions / Typing

Cannot access member "target_field" for type "Field[Any, Any]"   Member "target_field" is unknown (reportAttributeAccessIssue)
result = target_model(pk=value)
else:
raise
elif isinstance(attr, ReverseOneToOneDescriptor):
# This will raise KeyError if it is not cached
result = attr.related.get_cached_value(source)
Expand Down
6 changes: 4 additions & 2 deletions strawberry_django/optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,6 @@ def _get_model_hints(

if isinstance(model_field, (models.ForeignKey, OneToOneRel)):
store.only.append(path)
store.select_related.append(path)

# If adding a reverse relation, make sure to select its pointer to us,
# or else this might causa a refetch from the database
Expand All @@ -514,7 +513,10 @@ def _get_model_hints(
cache=cache,
level=level + 1,
)
if f_store is not None:
if f_store is not None and set(f_store.only) != {
model_field.target_field.attname
}:
store.select_related.append(path)
cache.setdefault(f_model, []).append((level, f_store))
store |= f_store.with_prefix(path, info=info)
elif GenericForeignKey and isinstance(model_field, GenericForeignKey):
Expand Down
Loading