question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

prefetch relay children - duplicate issue of #1, #4, etc.

See original GitHub issue

Hey, I guess something is wrong with my setup, perhaps not even related to graphene-django-optimizer.

I have exactly the same issue with #1

I have used all solutions I can see from Graphene and here, plus that I am even manually calling prefetch_related('children_set'), queries will still be N+1.

Here’s my model.

class Province(Model):
    name                        = CharField(max_length=10)

class City(Model):
    province                    = ForeignKey(Province, on_delete=CASCADE)
    name                        = CharField(max_length=15)

Overridding DjangoConnectionField to not use merge_querysets, like suggested: #429

class PrefetchingConnectionField(DjangoFilterConnectionField): 
# or just subclass DjangoConnectionField, doesn't make a difference for N+1

    @classmethod
    def merge_querysets(cls, default_queryset, queryset):
        return queryset

    @classmethod
    def resolve_connection(cls, connection, default_manager, args, iterable):
        if iterable is None:
            iterable = default_manager

        if isinstance(iterable, QuerySet):
            _len = iterable.count()
        else:
            _len = len(iterable)

        connection = connection_from_list_slice(
            iterable,
            args,
            slice_start=0,
            list_length=_len,
            list_slice_length=_len,
            connection_type=connection,
            edge_type=connection.Edge,
            pageinfo_type=PageInfo,
        )
        connection.iterable = iterable
        connection.length = _len
        return connection

Schema

class Province(DjObj):
    class Meta(NodeI):
        model = models.Province
        filter_fields = {   # for DjangoFilterConnectionField
            'id': ['exact'],
        }

class City(DjObj):
    class Meta(NodeI):
        model = models.City
        filter_fields = {
            'id': ['exact'],
        }


class GeoQueryCodex:
    provinces                      = PrefetchingConnectionField(Province)
    province                       = Node.Field(Province)

    def resolve_provinces(self, info, *args, **kw):
        # use the plugin
        qs = gql_optimizer.query(models.Province.objects.all(), info)
        # or just manually prefetch
        qs = models.Province.objects.all().prefetch_related('city_set')
        return qs

    cities                         = PrefetchingConnectionField(City)
    city                           = Node.Field(City)

And the query

query Provinces {
  provinces(first:10) {
    edges {
      node {
        id
        name
        citySet {  # default naming of the children, since a related_name is not supplied
          edges {
            node {
              name
            }
          }
        }
      }
    }
  }
}

just for sanity check, python query does work:


@timeit
def d():
    result = []
    for x in Province.objects.all().prefetch_related('city_set'):
        result.append((x.id, x.name, [area.name for cityin x.city_set.all()]))
    print(result)

# this does not result in N+1, as it would be much faster than without 'prefetch_related'

Now, this result in N+1… Driving me crazy 😦

Hope you don’t mind me calling for help here @maarcingebala 😃 Your Saleor repo was the original inspiration that I used the Graphene stack.

please help me fellow python gods

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:17
  • Comments:8 (1 by maintainers)

github_iconTop GitHub Comments

3reactions
svengtcommented, Apr 30, 2019

We are also experiencing the same issues. It appears that edges are not auto prefetched. The following query for example results in an extra query per To-Do. Expected result would be to prefetch all items.

{
  allTodos {
    edges {
      node {
        id
        name
        items {
          edges {
            node {
              id
              todo
            }
          }
        }
      }
    }
  }
}

Tested in Python 3.7, Django 2.1 and 2.2

0reactions
omegioncommented, May 22, 2020

I am having a similar problem, nested relations with filters produce more queries.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Django- Duplicated queries in nested models ... - Stack Overflow
The prefetch worked for these lookups prefetch_related("children__children") as the queries are grouped in two separate queries, as it should be ...
Read more >
List of settings and detailed descriptions
Parent relay; Child relay. Peer to peer mode; Miscellaneous. For information related to parallel FillDB configuration, see Configuring parallel FillDB.
Read more >
Setting up an email server in 2020 with OpenSMTPD and ...
The Mail Delivery Agent (MDA) is a program that watches over the server's copy of your mailbox: it manages your inbox, remembers which...
Read more >
HealthFetch: An Influence-Based, Context-Aware Prefetch ...
For this reason, this paper proposes a novel data prefetching scheme that can be adopted by health data storage cloud solutions, which will...
Read more >
mk-slave-prefetch(1) - Linux man page
mk-slave-prefetch pipelines relay logs to pre-warm the slave's caches. ... source for updated information is always the online issue tracking system.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found