Initial optimize in connections

This commit is contained in:
Syrus Akbary 2016-01-19 20:49:43 -08:00
parent 6e3fe9c40f
commit 25d680fa00
3 changed files with 33 additions and 4 deletions

View File

@ -4,6 +4,7 @@ from ...core.types.base import FieldType
from ...core.types.definitions import List from ...core.types.definitions import List
from ...relay import ConnectionField from ...relay import ConnectionField
from ...relay.utils import is_node from ...relay.utils import is_node
from .fetcher import get_fields
from .utils import DJANGO_FILTER_INSTALLED, get_type_for_model, maybe_queryset from .utils import DJANGO_FILTER_INSTALLED, get_type_for_model, maybe_queryset
@ -37,10 +38,14 @@ class DjangoConnectionField(DjangoField, ConnectionField):
def get_queryset(self, resolved_qs, args, info): def get_queryset(self, resolved_qs, args, info):
return resolved_qs return resolved_qs
def get_fetch_fields(self, info):
return get_fields(info)
def from_list(self, connection_type, resolved, args, info): def from_list(self, connection_type, resolved, args, info):
if not resolved: if not resolved:
resolved = self.get_manager() resolved = self.get_manager()
resolved_qs = maybe_queryset(resolved) only = self.get_fetch_fields(info)
resolved_qs = maybe_queryset(resolved, only)
qs = self.get_queryset(resolved_qs, args, info) qs = self.get_queryset(resolved_qs, args, info)
return super(DjangoConnectionField, self).from_list(connection_type, qs, args, info) return super(DjangoConnectionField, self).from_list(connection_type, qs, args, info)

View File

@ -1,11 +1,12 @@
import pytest import pytest
import graphene import graphene
from graphene.contrib.django import DjangoObjectType from graphene.contrib.django import DjangoNode
from ..tests.models import Reporter from ..tests.models import Reporter
from ..debug.plugin import DjangoDebugPlugin from ..debug.plugin import DjangoDebugPlugin
from ..fetcher import fetch_only_required, get_fields from ..fetcher import fetch_only_required, get_fields
from ..fields import DjangoConnectionField
# from examples.starwars_django.models import Character # from examples.starwars_django.models import Character
@ -18,7 +19,7 @@ def test_should_query_well():
r2 = Reporter(last_name='Griffin') r2 = Reporter(last_name='Griffin')
r2.save() r2.save()
class ReporterType(DjangoObjectType): class ReporterType(DjangoNode):
class Meta: class Meta:
model = Reporter model = Reporter
@ -26,6 +27,7 @@ def test_should_query_well():
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
reporter = graphene.Field(ReporterType) reporter = graphene.Field(ReporterType)
all_reporters = ReporterType.List() all_reporters = ReporterType.List()
all_reporters_connection = DjangoConnectionField(ReporterType)
@fetch_only_required @fetch_only_required
def resolve_all_reporters(self, args, info): def resolve_all_reporters(self, args, info):
@ -40,6 +42,14 @@ def test_should_query_well():
lastName lastName
email email
} }
allReportersConnection(first:1) {
edges {
node {
lastName
email
}
}
}
reporter { reporter {
email email
} }
@ -58,12 +68,24 @@ def test_should_query_well():
'lastName': 'Griffin', 'lastName': 'Griffin',
'email': '', 'email': '',
}], }],
'allReportersConnection': {
'edges': [{
'node': {
'lastName': 'ABA',
'email': '',
}
}]
},
'reporter': { 'reporter': {
'email': '' 'email': ''
}, },
'__debug': { '__debug': {
'sql': [{ 'sql': [{
'rawSql': str(Reporter.objects.all().only('last_name', 'email').query) 'rawSql': str(Reporter.objects.all().only('last_name', 'email').query)
}, {
'rawSql': 'SELECT COUNT(*) AS "__count" FROM "tests_reporter"'
}, {
'rawSql': str(Reporter.objects.all()[:1].query)
}, { }, {
'rawSql': str(Reporter.objects.only('email').order_by('pk')[:1].query) 'rawSql': str(Reporter.objects.only('email').order_by('pk')[:1].query)
}] }]

View File

@ -49,10 +49,12 @@ class WrappedQueryset(LazyList):
return self._origin.count() return self._origin.count()
def maybe_queryset(value): def maybe_queryset(value, only=[]):
if isinstance(value, Manager): if isinstance(value, Manager):
value = value.get_queryset() value = value.get_queryset()
if isinstance(value, QuerySet): if isinstance(value, QuerySet):
if only:
value = value.only(*only)
return WrappedQueryset(value) return WrappedQueryset(value)
return value return value