Skip to main content

Automatic query optimization for django and strawberry-graphql

Project description

strawberry-django-optimizer

PyPI version python version django version

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

strawberry-django-optimizer-0.1.0.tar.gz (9.4 kB view details)

Uploaded Source

Built Distribution

strawberry_django_optimizer-0.1.0-py3-none-any.whl (9.7 kB view details)

Uploaded Python 3

File details

Details for the file strawberry-django-optimizer-0.1.0.tar.gz.

File metadata

  • Download URL: strawberry-django-optimizer-0.1.0.tar.gz
  • Upload date:
  • Size: 9.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.2 CPython/3.9.6

File hashes

Hashes for strawberry-django-optimizer-0.1.0.tar.gz
Algorithm Hash digest
SHA256 9f9af241ac778098fa42f56eb1b411adbcbd7d214e7c62bfb0a13c289b839171
MD5 8c37ba59160c8863fc5131a9b21174a3
BLAKE2b-256 93119aed8082514e64bb25b2276209ddb77c18ddf5e6bc92c20ab10d1819524a

See more details on using hashes here.

File details

Details for the file strawberry_django_optimizer-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: strawberry_django_optimizer-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 9.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.2 CPython/3.9.6

File hashes

Hashes for strawberry_django_optimizer-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 915612a57b223afaa894f66f5fd44ee5a7c6fda4415955f41b1702f1a0aa034e
MD5 4f0c2dda397df84b914d7577eec3f3d9
BLAKE2b-256 f4853cd8a88db9f06d20adaa4ac0dcc72949b4ce32492f906ec1371abc52c60f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page