2

I am fetching dynamic data using Graphene-Django Relay specification.

import graphene
from graphene_django.types import DjangoObjectType
from graphene_django.fields import DjangoConnectionField

from . import models


class PostType(DjangoObjectType):
    class Meta:
        model = models.Post
        interfaces = (graphene.Node, )

class Query(graphene.ObjectType):
    post = graphene.Field(PostType)
    posts = DjangoConnectionField(PostType)

def resolve_posts(self, info, **kwargs):
    return models.Post.objects.order_by('-score', '-id')

When I add a new post after fetching cursors and data, cursors change. In other words, the cursor that was pointing to the exact offset of data does not point that data any longer. It points a new, different data. Thereby, I cannot implement a cursor-based pagination by using:

query fetchPosts ($cursor) {
    posts(first: 20, after: $cursor)...
}

Because cursor changes as data changes, it is no different than traditional offset-based-pagination. Is there something I am missing? What I want for the cursor is not to change. Like this article:

https://www.sitepoint.com/paginating-real-time-data-cursor-based-pagination/

How should I make the cursor point the same data that changes dynamically?

donnyyy
  • 452
  • 3
  • 11
Grateful
  • 383
  • 5
  • 18
  • What do you mean by "cursor changes"? Could you please provide an example or shared explanation? – donnyyy Aug 12 '19 at 14:13
  • @donnyyy Okay. Let me explain by using the link I pasted on the post. Let us say that cursor 0 was pointing to Record 20, cursor 1 -> Record 19, cursor 2 -> Record 18, and so on. When I add new Record 21 - Record 25, The cursor 0 should still point Record 20. However, it points Record 25, the newest Record. And cursor 1 points Record 24. Cursor 2 points Record 23. – Grateful Aug 12 '19 at 22:15
  • @donnyyy So when I call "fetchMore" by retrieving 10 more items from the server, it does not retrieve from Record 10 to Record 1. It retrieves from Record 15 to Record 5. So it causes items to be duplicated because there were already items from Record 20 to Record 11. – Grateful Aug 12 '19 at 22:18
  • @donnyyy Cursor values are the same with ordinary offset values. It just turns them into a base64 encoded form. A cursor does not act as a unique pointer that indicates the same item with the previous pagination, but it indicates a new item filed on the top. That is what I meant. – Grateful Aug 12 '19 at 22:23

2 Answers2

2

Unfortunately, I think that this behavior is expected. Relay's strategy is a more flexible than traditional offset pagination, but it has the same limitation.

If your underlying data changes, then the pagination that represents it will also need to change.

If you would like to avoid this, you can consider sorting your underlying data in a different way so that new records don't alter your pagination. For example, if you sort posts by creation time, new posts will be added to the end of the list and all your previous pagination will still be valid.

JuanCaicedo
  • 3,132
  • 2
  • 14
  • 36
0

It's weird, the graphene_django developers call it cursor pagination, but it doesn't work like a cursor, but like an offset. I also encountered this problem when I try to cut data in a sorted array by time. When adding a field to the first position, all cursors are shifted.

  • 1
    This does not really answer the question. If you have a different question, you can ask it by clicking [Ask Question](https://stackoverflow.com/questions/ask). To get notified when this question gets new answers, you can [follow this question](https://meta.stackexchange.com/q/345661). Once you have enough [reputation](https://stackoverflow.com/help/whats-reputation), you can also [add a bounty](https://stackoverflow.com/help/privileges/set-bounties) to draw more attention to this question. - [From Review](/review/late-answers/31925447) – Wouter Jun 05 '22 at 12:41