Error 404 al cargar datos de la API REST que pagina al modelo

Un usuario Pregunto ✅

Anónimo

Hola a todos,

Estoy extrayendo datos de la API REST que está paginada con la siguiente consulta M,

let
Pagination = List.Skip(List.Generate( () => [WebCall=[], Page = 1, Counter=0], // Start Value
   		each List.Count(Record.FieldNames([WebCall]))>0 or [Counter]=0, // Condition under which the next execution will happen
   		each [ WebCall = Json.Document(Web.Contents("http://py-soconnect.fusesport.com/api/members/for-season/250/?page="&Text.From([Page])&"")), // retrieve results per call
     			Page = [Page]+1,
     			Counter = [Counter]+1// internal counter
]
) ,1),
    #"Converted to Table" = Table.FromList(Pagination, Splitter.SplitByNothing(), null, null, ExtraValues.Error)
in
    #"Converted to Table"

Sin embargo, el último registro es un registro de ERROR y el mensaje de error es el siguiente:

DataSource.Error: Web.Contents failed to get contents from 'http://py-soconnect.fusesport.com/api/members/for-season/250/?page=246' (404): Not Found
Details:
    DataSourceKind=Web
    DataSourcePath=http://py-soconnect.fusesport.com/api/members/for-season/250
    Url=http://py-soconnect.fusesport.com/api/members/for-season/250/?page=246

No puedo cargar los datos en el modelo. Cualquier ayuda con esto será muy apreciada.

Gracias por adelantado.

En respuesta a Anónimo

Hola @Anonimo,

Modifico mi condición y verifico dos veces para confirmar que puedo obtener los registros de la última página:

let
Pagination = List.Skip(List.Buffer(List.Generate( () => [WebCall=[], Page = 0, Counter=0], // Start Value
   		each try Record.Field([WebCall],"next")<>null or (Record.Field([WebCall],"next")=null and [Counter]>0) otherwise false or [Counter]=0, // Condition under which the next execution will happen
   		each [ WebCall = Json.Document(Web.Contents("http://py-soconnect.fusesport.com/api/members/for-season/250/?page="&Text.From([Page])&"")), // retrieve results per call
     			Page = [Page]+1,
     			Counter = [Counter]+1// internal counter
]
)),1),
    #"Converted to Table" = Table.FromList(Pagination, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    Column1 = #"Converted to Table"{19}[Column1]
in
    Column1

Saludos,

Xiaoxin-sheng

Hola @Anonimo,

Después de probar con la URL que compartió, descubrí que su API devolverá la URL de solicitud anterior y siguiente al mismo tiempo. Creo que debe agregar una condición para verificar el contenido de la respuesta para confirmar si contiene el resultado de la página siguiente.

let
Pagination = List.Skip(List.Buffer(List.Generate( () => [WebCall=[], Page = 1, Counter=0], // Start Value
   		each try Record.Field([WebCall],"next")<>null otherwise false or [Counter]=0, // Condition under which the next execution will happen
   		each [ WebCall = Json.Document(Web.Contents("http://py-soconnect.fusesport.com/api/members/for-season/250/?page="&Text.From([Page])&"")), // retrieve results per call
     			Page = [Page]+1,
     			Counter = [Counter]+1// internal counter
]
)),1),
    #"Converted to Table" = Table.FromList(Pagination, Splitter.SplitByNothing(), null, null, ExtraValues.Error)
in
    #"Converted to Table"

Por cierto, la función de búfer se usa para resolver el problema de la memoria para las funciones de bucle cuando guarda cambios y genera un modelo de datos.

Saludos,

Xiaoxin-sheng

Anónimo

En respuesta a v-shex-msft

Hola @v-shex-msft,

Veo que hay una pérdida de datos con el código anterior ya que no se extraen los registros de la última página.

    "recuento": 24628, "siguiente": "http://py-soconnect.fusesport.com/api/members/for-season/250/?page=2", "anterior": nulo, "resultados": [

 The total number of records are 24628 and thus 246 pages , but this query returns only 245 records. Could you suggest a way to get records from the last page as well.

 

Thanks

In response to Anonymous

Hi @Anonymous,

 

I modify my condition and double check to confirm it can get the last page records:

let
Pagination = List.Skip(List.Buffer(List.Generate( () => [WebCall=[], Página = 0, Contador = 0], // Valor de inicio cada intento Registro.Campo([WebCall],"siguiente")<>null o (Registro.Campo([WebCall],"siguiente")=null y [Counter]>0) de lo contrario falso o [Counter]=0, // Condición bajo la cual ocurrirá la siguiente ejecución cada [ WebCall = Json.Document(Web.Contents("http://py-soconnect.fusesport.com/api/members/for-season/250/?page="&Text.From([Page])&"")), // recuperar resultados por llamada Página = [Page]+1, Contador = [Counter]+1// contador interno ])),1), #"Convertido a tabla" = Table.FromList(Paginación, Splitter.SplitByNothing(), null, null, ExtraValues.Error), Column1 = #"Convertido a tabla"{ 19}[Column1]
en Columna1

Saludos,

Xiaoxin-sheng

sankzpower

En respuesta a v-shex-msft

Hola @v-shex-msft

Espero que puedas arrojar algo de luz. La API se restringe para llevar los datos hasta 100 filas por llamada. Por lo tanto, he encontrado que se ejecuta la siguiente consulta, sin embargo, la condición continúa en un bucle infinito donde la consulta recupera datos nulos, incluso si no se encuentran datos. Por ejemplo, como se muestra en la imagen de abajo. Descubrí que hay un campo de registro llamado «hasMore»: verdadero o falso (imágenes adjuntas: la fila 7 contiene hasmore como verdadero y la fila 8 contiene tiene más como falso) que determina si ver si hay más datos en cada página . Solo estoy probando diferentes consultas diferentes para ver cómo se puede ajustar esto para el examen: cuando la consulta llega a Hasmore = False, entonces la consulta debería dejar de recuperar datos, ya que creo que esta es probablemente la solución.

let
Pagination = List.Skip(List.Generate( () => [WebCall=[], Page = 0, Counter=0], // Start Value
   		each List.Count(Record.FieldNames([WebCall]))>0 or [Counter]=0, // Condition under which the next execution will happen
   		each [ WebCall = Json.Document(Web.Contents("https://energycloud.com/api/Supplier?apiKey=a1459b&orderby=name&page="&Text.From([Page])&"")), // retrieve results per call
     			Page = [Page]+1,
     			Counter = [Counter]+1// internal counter
]
) ,1),
    #"Converted to Table" = Table.FromList(Pagination, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    #"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"WebCall", "Page", "Counter"}, {"WebCall", "Page", "Counter"}),
    #"Expanded WebCall" = Table.ExpandRecordColumn(#"Expanded Column1", "WebCall", {"items", "hasMore"}, {"items", "hasMore"})
in
    #"Expanded WebCall"

.

Capturar.JPG

 

hasmore_false.JPGhasmore_True.JPG

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *