Paginate without requiring length
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 35/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Bastante claro
- Estado de actividad
- Estancado
- Stack tecnológico
- graphql, python
- Área
- api, backend-api-design
Línea de trabajo
Comienza localizando la implementación existente de paginación de conexiones y compara cómo gestiona first, last, before, after y los recuentos totales con la función propuesta connection_from_list_slice. Determina si la paginación sin recuento debe convertirse en la estrategia predeterminada o en una estrategia opcional y, después, verifica que la información sobre la página siguiente/anterior y el comportamiento de total_count sigan siendo correctos.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
The current implementation requires you to pass the total length of the iterable, and this usually means making an extra query to find out the count. There's no need for this, since we can actually accomplish the same results by trying to fetch n+1 results, which will mean that there are more to be consumed, without the need for the real total count.
This is the custom implementation we have applied to spare us the count query, which can be costly and adds an unnecessary overhead to every query. We only need the real total count, when that value is requested (using a custom CountableConnection)
class CountableConnection(graphene.relay.Connection):
class Meta:
abstract = True
total_count = graphene.Int()
@staticmethod
def resolve_total_count(root, info, *args, **kwargs):
try:
t_count = root.iterable.count()
except:
t_count = len(root.iterable)
return t_count
def connection_from_list_slice(list_slice, args=None, connection_type=None,
edge_type=None, pageinfo_type=None):
'''
Given an iterator it consumes the needed amount based on the pagination
params, and also tries to figure out if there are more results to be
consumed. We do so by trying to fetch one more element than the specified
amount, if we were able to fetch n+1 it means there are more to be consumed.
This spares the caller passing the total count of results, which
usually means making an extra query just to find out that number.
'''
from graphql_relay.utils import base64, unbase64, is_str
from graphql_relay.connection.connectiontypes import Connection, PageInfo, Edge
connection_type = connection_type or Connection
edge_type = edge_type or Edge
pageinfo_type = pageinfo_type or PageInfo
args = args or {}
before = args.get('before')
after = args.get('after')
first = args.get('first')
last = args.get('last')
if first:
after = get_offset_with_default(after, -1) + 1
_slice = list_slice[after: max(after, 0) + first + 1] # fetch n+1
items = _slice[:-1]
if len(items) < first:
items = _slice[:] # If there are not enough, get them all
edges = [
edge_type(
node=node,
cursor=offset_to_cursor(after + i)
)
for i, node in enumerate(items)
]
elif last:
if before:
before = get_offset_with_default(before)
_slice = list_slice[max(before-last-1, 0):before] # fetch n+1
else:
# beware that not specifying before results in the need
# to calculate the total amount
_slice = list_slice[(last*-1)-1:]
try:
before = list_slice.count()
except:
before = len(list_slice)
items = _slice[1:]
if len(items) < last:
items = _slice[:] # If there are not enough, get them all
edges = [
edge_type(
node=node,
cursor=offset_to_cursor(before - last -1 + i)
)
for i, node in enumerate(items)
]
else: # we are not allowing to pass after/before without first/last
items = list_slice[:]
edges = [
edge_type(
node=node,
cursor=offset_to_cursor(i)
)
for i, node in enumerate(items)
]
first_edge_cursor = edges[0].cursor if edges else None
last_edge_cursor = edges[-1].cursor if edges else None
has_previous_page = False
if (isinstance(last, int) and len(_slice) > last) or after > 0:
has_previous_page = True
return connection_type(
edges=edges,
page_info=pageinfo_type(
start_cursor=first_edge_cursor,
end_cursor=last_edge_cursor,
has_previous_page=has_previous_page,
has_next_page=len(_slice) > first if isinstance(first, int) else False
)
)
@syrusakbary Not sure if we want this as the default or at least have this as an optional stragey.
If this sounds reasonable I can make a PR for this.
- Lenguaje dominante
- Python
- Estrellas
- 143
- Forks
- 42
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de graphql-python/graphql-relay-py
-
Dificultad 4/5 3-5 días Aptitud para principiantes 35/100
-
Why are nodes optional?Abierto
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
graphql-python/graphql-relay-py#19 · 3 comentarios ·
-
has_previous_page and has_next_page always False while navigatingPosiblemente ocupada @sciyoshi la tomó hace 3249 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 45/100
graphql-python/graphql-relay-py#12 · 4 comentarios · 3 reacciones ·
-
Dificultad 3/5 1-2 días Aptitud para principiantes 35/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 35/100
graphql-python/graphql-relay-py#9 · 2 reacciones ·
Todos los issues de graphql-python/graphql-relay-py
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
common-workflow-language/cwl-utils#477 ·
Los mantenedores suelen responder en 1 día
-
Add dependabotAbiertofeat
Dificultad 2/5 Menos de una hora Aptitud para principiantes 72/100
open-nudge/opentemplate#204 ·
Los mantenedores suelen responder en 1 día
-
github-stale-ci-pr-closer: KV state is double-wrapped, never persists, and hits the depth-32 limitPosiblemente ocupada @VascoSch92 la tomó hoy. Abiertopriority:medium ready-for-dev
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
OpenHands/extensions#781 ·
Los mantenedores suelen responder en 1 día
-
bug good first issue
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día
-
curriculum documentation quality
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
githubnext/gh-aw-workshop#4638 ·
Los mantenedores suelen responder en 1 día