Automatic query optimization for django and strawberry-graphql
Project description
strawberry-django-optimizer
Optimize queries executed by strawberry automatically,
using select_related
, prefetch_related
and only
methods of Django QuerySet.
This package is heavily based on graphene-django-optimizer which is intended for use with graphene-django.
Install
pip install strawberry-django-optimizer
Usage
Having the following models based on the strawberry-graphql-django docs:
# models.py
from django.db import models
class Fruit(models.Model):
name = models.CharField(max_length=20)
color = models.ForeignKey('Color', blank=True, null=True,
related_name='fruits', on_delete=models.CASCADE)
class Color(models.Model):
name = models.CharField(max_length=20)
And the following schema:
# schema.py
import strawberry
from typing import List
from strawberry.django import auto
from strawberry_django_optimizer import optimized_django_field
from fruits import models
@strawberry.django.type(models.Fruit)
class Fruit:
id: auto
name: auto
color: 'Color'
@strawberry.django.type(models.Color)
class Color:
id: auto
name: auto
fruits: List[Fruit]
@strawberry.type
class Query:
fruits: List[Fruit] = optimized_django_field()
The following graphql query would cause n + 1 DB queries:
query Fruit {
fruits {
id
name
color {
id
name
}
}
}
Since optimized_django_field
was used instead of strawberry.django.field
the queryset is automatically optimized.
# optimized queryset:
Fruits.objects.select_related('color').only('id', 'name', 'color__id', 'color__name')
Reverse ForeignKey
relations also are automatically optimized with prefetch_related
:
query Colors {
colors {
id
name
fruits {
id
name
}
}
}
# optimized queryset:
Color.objects.only('id', 'name', 'color').prefetch_related(
Prefetch('fruits', queryset=Fruit.objects.only('id', 'name'))
)
Advanced usage
Use resolver_hint
for cases where only
, select_related
and prefetch_related
optimizations can't be inferred automatically.
To keep the only
optimization when using custom resolver functions, resolver_hints
must be used to declare all fields that are accessed
or the only
optimization will be disabled.
# schema.py
import strawberry
from strawberry.django import auto
from strawberry_django_optimizer import resolver_hints
from fruits import models
@strawberry.django.type(models.Fruit)
class Fruit:
id: auto
@resolver_hints(only=('name',))
@strawberry.field
def name_display(self) -> str:
return f'My name is: {self.name}'
If the resolver function accesses a related field you can add an optimization hint for select_related
:
# schema.py
import strawberry
from strawberry.django import auto
from strawberry_django_optimizer import resolver_hints
from fruits import models
@strawberry.django.type(models.Fruit)
class Fruit:
id: auto
@resolver_hints(
select_related=('color',),
only=('color__name',),
)
def color_display(self) -> str:
return f'My color is: {self.color.name}'
Parameters for resolver_hint
Parameter | Usage |
---|---|
model_field |
If the resolver returns a model field |
only |
Declare all fields that the resolver accesses |
select_related |
If the resolver uses related fields |
prefetch_reltaed |
If the resolver uses related fields |
Known issues (ToDo)
- Inline Fragments can't be optimized
- Interfaces and Unions are not supported
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for strawberry-django-optimizer-0.1.0.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9f9af241ac778098fa42f56eb1b411adbcbd7d214e7c62bfb0a13c289b839171 |
|
MD5 | 8c37ba59160c8863fc5131a9b21174a3 |
|
BLAKE2b-256 | 93119aed8082514e64bb25b2276209ddb77c18ddf5e6bc92c20ab10d1819524a |
Hashes for strawberry_django_optimizer-0.1.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 915612a57b223afaa894f66f5fd44ee5a7c6fda4415955f41b1702f1a0aa034e |
|
MD5 | 4f0c2dda397df84b914d7577eec3f3d9 |
|
BLAKE2b-256 | f4853cd8a88db9f06d20adaa4ac0dcc72949b4ce32492f906ec1371abc52c60f |