Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Be one of the first to start using Fabric Databases. View on-demand sessions with database experts and the Microsoft product team to learn just how easy it is to get started. Watch now

Reply
Syndicate_Admin
Administrator
Administrator

¿Cómo conectar la API REST de Jira como fuente de datos? Power BI Service amigable y con paginación??

Hola a todos

He pasado horas y horas tratando de cargar los datos de Jira en Power BI a través de su API REST. Ahora lo he conseguido, pero con el conocido problema del mensaje de error de una fuente de datos dinámica en Power BI Service. Aquí mi código de trabajo hasta ahora:

    BaseUrl = "https://XXX.XXX.net/jira/rest/api/2/search?jql=filter=525545&maxResults=1000&fields=issuetype,key,summary,customfield_10401,labels,customfield_10000,status,resolution,customfield_11200",
  
    JiraIDPerPage = 1000,

    GetJson = (Url) =>
        let 
            RawData = Web.Contents(Url,[Headers=[Authorization="Bearer XXX"]]),
            Json    = Json.Document(RawData)
        in  Json,

    GetJiraIDCount = () =>
        let Url   = BaseUrl & "&maxResults=0",
            Json  = GetJson(Url),
            Count = Json[#"total"]
        in  Count,

    GetPage = (Index) =>
        let Skip  = "&startAt=" & Text.From(Index * JiraIDPerPage),
            Top   = "&maxResults=" & Text.From(JiraIDPerPage),
            Url   = BaseUrl & Skip & Top,
            Json  = GetJson(Url),
            Value = Json[#"issues"]
        in  Value,

    JiraIDCount = List.Max({ JiraIDPerPage, GetJiraIDCount() }),

    PageCount   = Number.RoundUp(JiraIDCount / JiraIDPerPage),

    PageIndices = { 0 .. PageCount - 1 },

    Pages       = List.Transform(PageIndices, each GetPage(_)),

    JiraID    = List.Union(Pages),

    Table       = Table.FromList(JiraID, Splitter.SplitByNothing(), null, null, ExtraValues.Error),

...

Ahora que Power BI Desktop está funcionando, necesito abordar el problema de la fuente de datos dinámica y seguí encontrándome con esta publicación mientras navegaba por la comunidad:
https://blog.crossjoin.co.uk/2016/08/16/using-the-relativepath-and-query-options-with-web-contents-i...
https://blog.crossjoin.co.uk/2016/08/23/web-contents-m-functions-and-dataset-refresh-errors-in-power...


Mi código modificado hasta ahora:

let 
    BaseUrl = 
    Web.Contents(
        "https://XXX.XXX.net/jira/rest/api",
        [
            RelativePath="2/search",
            Query=
            [
                jql="filter=525545",
                maxResults="1000",
                fields="issuetype,key,summary,customfield_10401,labels,customfield_10000,status,resolution,customfield_11200"
            ],
            Headers=
            [
                Authorization="Bearer XXX"
            ]
        ]
        
    )  ,

    JiraIDPerPage = 1000,

    GetJson = (Url) =>
        let 
            RawData = Web.Contents(Url,[Headers=[Authorization="Bearer XXX"]]),
            Json    = Json.Document(RawData)
        in  Json,

    GetJiraIDCount = () =>
        let Url   = BaseUrl & "&maxResults=1000",
            Json  = GetJson(Url),
            Count = Json[#"total"]
        in  Count,

    GetPage = (Index) =>
        let Skip  = "&startAt=" & Text.From(Index * JiraIDPerPage),
            Top   = "&maxResults=" & Text.From(JiraIDPerPage),
            Url   = BaseUrl & Skip & Top,
            Json  = GetJson(Url),
            Value = Json[#"issues"]
        in  Value,

    JiraIDCount = List.Max({ JiraIDPerPage, GetJiraIDCount() }),

    PageCount   = Number.RoundUp(JiraIDCount / JiraIDPerPage),

    PageIndices = { 0 .. PageCount - 1 },

    Pages       = List.Transform(PageIndices, each GetPage(_)),

    JiraID    = List.Union(Pages),

    Table       = Table.FromList(JiraID, Splitter.SplitByNothing(), null, null, ExtraValues.Error)
    
...


Lo que no se describe en la publicación del blog, sin embargo, es cómo puedo administrar la paginación. Ahora es posible que haya administrado la consulta, pero mi mensaje de error actual se refiere específicamente a GetJiraIDCount=...

Expression.Error: No podemos aplicar el operador & a los tipos Binary y Text.
Detalles:
Operador=&
Izquierda=[Binario]
Derecha=&maxResultados=1000

Soy un completo principiante en este campo y me estoy perdiendo mucho. De alguna manera tiene que funcionar???? ¡Realmente agradecería cualquier ayuda!

5 REPLIES 5
Syndicate_Admin
Administrator
Administrator

Hola @Alina12,

La integración de Jira y Power BI puede ser un desafío, pero afortunadamente, puede usar dos métodos principales para lograrlo. Una opción es la API REST de Jira, que requiere habilidades técnicas y puede ser compleja. La segunda opción es Conector de Power BI para Jira.
Es una aplicación fácil de usar que le permite exportar datos de Jira a Power BI sin necesidad de conocimientos de codificación. Obtenga más información sobre el segundo método aquí:

https://marketplace.atlassian.com/apps/1221150/power-bi-connector-for-jira?hosting=cloud&tab=overvie... está disponible para Jira Cloud / Server / Data Center.

Dar

Syndicate_Admin
Administrator
Administrator

Hola @Alina12 ,

Espero que todo vaya bien.

Siga estos pasos:

1. El error que está encontrando en la función se debe a que intenta concatenar un binario () con una cadena. Dado que se usa con , se trata como un binario.

También debe modificar el enfoque de uso y las opciones dentro de la paginación. GetJiraIDCountBaseUrlBaseUrlWeb.ContentsRelativePathQueryWeb.Contents

2. Modifique la función GetPage:

GetPage = (Index) =>
    let
        Skip = Text.From(Index * JiraIDPerPage),
        Top = Text.From(JiraIDPerPage),
        PageData = Web.Contents(
            https://XXX.XXX.net/jira/rest/api,
            [
                RelativePath="2/search",
                Query=
                [
                    jql="filter=525545",
                    startAt=Skip,
                    maxResults=Top,
                    fields="issuetype,key,summary,customfield_10401,labels,customfield_10000,status,resolution,customfield_11200"
                ],
                Headers=[Authorization="Bearer XXX"]
            ]
        ),
        Json = Json.Document(PageData),
        Value = Json[#"issues"]
    in Value,

Si tiene otras preguntas, póngase en contacto conmigo en cualquier momento.

Saludos
Yang
Equipo de apoyo a la comunidad

Si hay alguna publicación que ayude, considere Aceptarla como la solución para ayudar a los otros miembros a encontrarla más rápidamente.
Si no entiendo sus necesidades o aún tiene problemas al respecto, no dude en hacérnoslo saber. ¡Muchas gracias!

Hola @v-huijiey-msft ,

¡Muchas gracias por tu respuesta!

He probado su recomendación, pero desafortunadamente todavía recibo el mensaje de error con las fuentes de datos dinámicos. ¿Tengo que usar Web.Contents, Relative Path y Query en todas partes en lugar de BaseUrl y no solo en PageData? ¿El problema también puede deberse a la paginación?

Mi código hasta ahora:

let 
    BaseUrl = 
    Web.Contents(
        "https://XXX.XXX.net/jira/rest/api",
        [
            RelativePath="2/search",
            Query=
            [
                jql="filter=525545",
                maxResults="1000",
                fields="issuetype,key,summary,customfield_10401,labels,customfield_10000,status,resolution,customfield_11200"
            ],
            Headers=
            [
                Authorization="Bearer XXX"
            ]
        ]
        
    )  ,
 
    JiraIDPerPage = 1000,

    GetJson = (Url) =>
        let 
            RawData = BaseUrl,
            Json    = Json.Document(RawData)
        in  Json,

    GetJiraIDCount = () =>
        let Url   = BaseUrl,
            Json  = GetJson(Url),
            Count = Json[#"total"]
        in  Count,

    GetPage = (Index) =>
    let
        Skip = Text.From(Index * JiraIDPerPage),
        Top = Text.From(JiraIDPerPage),
        PageData = Web.Contents(
            "https://XXX.XXX.net/jira/rest/api",
            [
                RelativePath="2/search",
                Query=
                [
                    jql="filter=525545",
                    startAt=Skip,
                    maxResults=Top,
                    fields="issuetype,key,summary,customfield_10401,labels,customfield_10000,status,resolution,customfield_11200"
                ],
                Headers=[Authorization="Bearer XXX"]
            ]
        ),
        Json = Json.Document(PageData),
        Value = Json[#"issues"]
    in Value,

    JiraIDCount = List.Max({ JiraIDPerPage, GetJiraIDCount() }),

    PageCount   = Number.RoundUp(JiraIDCount / JiraIDPerPage),

    PageIndices = { 0 .. PageCount - 1 },

    Pages       = List.Transform(PageIndices, each GetPage(_)),

    JiraID    = List.Union(Pages),

    Table       = Table.FromList(JiraID, Splitter.SplitByNothing(), null, null, ExtraValues.Error),

    ....

Hola @Alina12 ,

Ha mencionado que funciona bien en Power BI Desktop, pero hay un problema en Service. Un posible factor que influye es:

Compruebe que el token de autenticación sigue siendo válido y se pasa correctamente con cada solicitud. Los problemas de caducidad o autenticación de tokens a veces pueden manifestarse como errores con orígenes de datos dinámicos.

A continuación se muestra un enfoque revisado para la parte de paginación:

GetJiraIDCount = () =>
    let
        Json = Web.Contents(
            https://XXX.XXX.net/jira/rest/api,
            [
                RelativePath="2/search",
                Query=[jql="filter=525545", maxResults="0", fields=""],
                Headers=[Authorization="Bearer XXX"]
            ]
        ),
        Data = Json.Document(Json),
        Count = Data[total]
    in
        Count,

GetPage = (Index) =>
    let
        Skip = Text.From(Index * JiraIDPerPage),
        PageData = Web.Contents(
            https://XXX.XXX.net/jira/rest/api,
            [
                RelativePath="2/search",
                Query=[
                    jql="filter=525545",
                    startAt=Skip,
                    maxResults="1000",
                    fields="issuetype,key,summary,customfield_10401,labels,customfield_10000,status,resolution,customfield_11200"
                ],
                Headers=[Authorization="Bearer XXX"]
            ]
        ),
        Json = Json.Document(PageData),
        Value = Json[issues]
    in
        Value,

Para obtener más información sobre el uso en Power BI, recomiendo revisar la siguiente documentación:

Web.Contents - PowerQuery M | Microsoft Learn

Si tiene más preguntas, no dude en ponerse en contacto conmigo.

Saludos
Yang
Equipo de apoyo a la comunidad

Si hay alguna publicación que ayude, considere Aceptarla como la solución para ayudar a los otros miembros a encontrarla más rápidamente.
Si no entiendo sus necesidades o aún tiene problemas al respecto, no dude en hacérnoslo saber. ¡Muchas gracias!

Syndicate_Admin
Administrator
Administrator

ACTUALIZAR

He conseguido que el código funcione con Web.Contents, Relative Path y Query. El problema ahora es que a) solo obtengo los primeros 1000 hits en lugar de aprox. 5,500 hits (aunque JiraIDCount muestra el número correcto de hits totales) y b) todavía me muestra una fuente de datos dinámica y la actualización de datos no es posible.

Así que parece que mi problema podría estar en la paginación, porque todo el www dice que la actualización de datos dinámicos debería funcionar con Web.Contents, Relative Path y Query. ¿Alguien puede ayudarme?

let 
    BaseUrl = 
    Web.Contents(
        "https://XXX.XXX.net/jira/rest/api",
        [
            RelativePath="2/search",
            Query=
            [
                jql="filter=525545",
                maxResults="1000",
                fields="issuetype,key,summary,customfield_10401,labels,customfield_10000,status,resolution,customfield_11200"
            ],
            Headers=
            [
                Authorization="Bearer XXX"
            ]
        ]
        
    )  ,

    JiraIDPerPage = 1000,

    GetJson = (Url) =>
        let 
            RawData = BaseUrl,
            Json    = Json.Document(RawData)
        in  Json,

    GetJiraIDCount = () =>
        let Url   = BaseUrl,
            Json  = GetJson(Url),
            Count = Json[#"total"]
        in  Count,

    GetPage = (Index) =>
        let Skip  = "&startAt=" & Text.From(Index * JiraIDPerPage),
            Top   = "&maxResults=" & Text.From(JiraIDPerPage),
            Url   = Text.From(BaseUrl) & Skip & Top,
            Json  = GetJson(Url),
            Value = Json[#"issues"]
        in  Value,

    JiraIDCount = List.Max({ JiraIDPerPage, GetJiraIDCount() }),

    PageCount   = Number.RoundUp(JiraIDCount / JiraIDPerPage),

    PageIndices = { 0 .. PageCount - 1 },

    Pages       = List.Transform(PageIndices, each GetPage(_)),

    JiraID    = List.Union(Pages),

    Table       = Table.FromList(JiraID, Splitter.SplitByNothing(), null, null, ExtraValues.Error),

...

Helpful resources

Announcements
Las Vegas 2025

Join us at the Microsoft Fabric Community Conference

March 31 - April 2, 2025, in Las Vegas, Nevada. Use code MSCUST for a $150 discount!

Dec Fabric Community Survey

We want your feedback!

Your insights matter. That’s why we created a quick survey to learn about your experience finding answers to technical questions.

ArunFabCon

Microsoft Fabric Community Conference 2025

Arun Ulag shares exciting details about the Microsoft Fabric Conference 2025, which will be held in Las Vegas, NV.

December 2024

A Year in Review - December 2024

Find out what content was popular in the Fabric community during 2024.

Top Solution Authors
Top Kudoed Authors