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.
v-shex-msft
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
v-shex-msft
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
v-shex-msft
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"
.