Skip to content

ConnectionField loads the entire query set when paginating #589

Closed
@Dandi91

Description

@Dandi91

I've noticed that when I query Relay-based pagination it doesn't limit the database query, but loads everything into memory and then does slicing. I understand that for a database table of moderate size it might not be a problem, but it becomes a concern when you've got a few hundred thousands records and want to display only a hundred of them at a time.
Is it something that was missed or this behavior was deliberately omitted for some reason?

Also, so far I got this workaround:

class Query(ObjectType):
	all_users = relay.ConnectionField(UserConnection)

	def resolve_all_users(self, info, **args):
		_len = User.objects.count()
		return connection_from_list_slice(User.objects.all(), args, 
			connection_type=UserConnection,
			edge_type=UserConnection.Edge, pageinfo_type=relay.PageInfo,
			list_length=_len, list_slice_length=_len)

It is possible to hide this inside a class derived from ConnectionField and override resolve_connection() which would call connection_from_list_slice() instead of connection_from_list(). However, this workaround still relies on the current implementation of connection_from_list_slice(), which fortunately doesn't do anything that evaluates the passed QuerySet until it actually slices it (and only if you provide list_slice_length argument to it). From the description of the function it's unsure whether it was specifically designed not to evaluate QuerySet or it's just a coincidence. Another downside to it is a separate query that counts rows, but I guess it is a trade off for not fetching everything at once.

So, my question really is: is it a useful feature and if it is, could it be done cleaner (in particular, not relying on connection_from_list_slice() implementation)?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions