Power BI Service verversingstijd en 429 Too Many Requests bij Teamleader Focus

Platform: Teamleader Focus
Tool: Power BI Service (automatische vernieuwing) + Power BI Desktop

De automatische vernieuwing van het semantische model “AucoteamTickets” mislukt regelmatig met twee verschillende fouten:

  1. Time-out na 10–45 minuten met foutcode Microsoft.Data.Mashup.ErrorCode = 10122 - onderliggende verbinding gesloten bij OData-verzoek.
  2. HTTP 429 Too Many Requests tijdens handmatige optimalisatiepogingen.

Handmatige vernieuwing in Power BI Desktop werkt, maar duurt erg lang. Automatische vernieuwing in Power BI Service mislukt consequent.

Zonder de tabel TicketMessagesAll wordt het rapport probleemloos vernieuwd. We kunnen deze tabel echter niet verwijderen, omdat het de enige bron is die de volledige ticketomschrijving/body-tekst bevat. De ticketdetailweergave in ons rapport is volledig afhankelijk van deze tabel.

Datavolumes:

  • Tickets: ongeveer 140 (gefilterd op één klant-ID).
  • TicketMessages: momenteel ongeveer 140, verwacht ongeveer 600 tegen eind 2026.
  • Contacts: totaal aantal onbekend, gefilterd tot 3 kolommen.
  • Users: ongeveer 15.
  • Companies: klein
  • TicketStatuses: klein

Reeds toegepaste optimalisaties:

  • Alle filters verplaatst naar de OData-URL ($filter, $select, $orderby, $top).
  • Parallel laden van tabellen uitgeschakeld in Power BI.
  • Header Accept-Encoding: gzip, deflate toegevoegd.
  • Overbodige Table.SelectColumns-stappen verwijderd.
  • $top=2000 ingesteld om paginering te voorkomen.

Huidige M-query’s:

Teamleader V2 Tickets@tlr

let
    KundenID = "739295e2-7443-07b1-aa70-bbba438579f5",
    URL = "https://bridge-online.invantive.com/acme-teamleader-focus/odata4/" &
          "Teamleader.V2.Tickets@tlr" &
          "?$filter=customer_id eq '" & KundenID & "'" &
          " or participant_customer_id eq '" & KundenID & "'" &
          "&$select=subject,id,assignee_id,status_id,customer_id," &
          "participant_customer_id,closed_at,created_at,reference,project_id",
    Quelle = OData.Feed(URL, null, [
        Implementation="2.0",
        Headers=[#"Accept-Encoding"="gzip, deflate"]
    ])
in
    Quelle

Teamleader V2 TicketStatuses@tlr:

let
    URL = "https://bridge-online.invantive.com/acme-teamleader-focus/odata4/" &
          "Teamleader.V2.TicketStatuses@tlr",
    Quelle = OData.Feed(URL, null, [
        Implementation="2.0",
        Headers=[#"Accept-Encoding"="gzip, deflate"]
    ])
in
    Quelle

Teamleader V2 Companies@tlr:

let
    URL = "https://bridge-online.invantive.com/acne-teamleader-focus/odata4/" &
          "Teamleader.V2.Companies@tlr" &
          "?$select=name,id",
    Quelle = OData.Feed(URL, null, [
        Implementation="2.0",
        Headers=[#"Accept-Encoding"="gzip, deflate"]
    ])
in
    Quelle

Teamleader V2 Users@tlr:

let
    URL = "https://bridge-online.invantive.com/acme-teamleader-focus/odata4/" &
          "Teamleader.V2.Users@tlr",
    Quelle = OData.Feed(URL, null, [
        Implementation="2.0",
        Headers=[#"Accept-Encoding"="gzip, deflate"]
    ])
in
    Quelle

Teamleader V2 Contacts@tlr:

let
    URL = "https://bridge-online.invantive.com/acme-teamleader-focus/odata4/" &
          "Teamleader.V2.Contacts@tlr" &
          "?$select=first_name,last_name,id",
    Quelle = OData.Feed(URL, null, [
        Implementation="2.0",
        Headers=[#"Accept-Encoding"="gzip, deflate"]
    ])
in
    Quelle

Teamleader V2Flat TicketMessagesAll@tlr:

let
    KundenID = "739295e2-7443-07b1-aa70-bbba438579f5",
    FilterParam =
        "(ticket_customer_id eq '" & KundenID & "'" &
        " or ticket_participant_customer_id eq '" & KundenID & "')" &
        " and created_at ge 2026-01-01T00:00:00Z" &
        " and (type eq 'customer' or type eq 'outbound' or type eq 'third_party')",
    URL = "https://bridge-online.invantive.com/acme-teamleader-focus/odata4/" &
          "Teamleader.V2Flat.TicketMessagesAll@tlr" &
          "?$filter=" & Uri.EscapeDataString(FilterParam) &
          "&$select=message_id,ticket_id,body,type,created_at,sent_by_id" &
          "&$orderby=created_at asc" &
          "&$top=2000",
    Quelle = OData.Feed(URL, null, [
        Implementation="2.0",
        MaxUriLength=32000,
        Headers=[#"Accept-Encoding"="gzip, deflate"]
    ]),
    #"HTML bereinigt" = Table.TransformColumns(Quelle, {{"body", each
        let t = _ in
        Text.Replace(Text.Replace(Text.Replace(Text.Replace(Text.Replace(
        Text.Replace(Text.Replace(Text.Replace(Text.Replace(Text.Replace(
        Text.Replace(Text.Replace(Text.Replace(Text.Replace(
            t, "<br />", " "), "<br/>", " "),
            "&uuml;", "ü"), "&Uuml;", "Ü"),
            "&auml;", "ä"), "&Auml;", "Ä"),
            "&ouml;", "ö"), "&Ouml;", "Ö"),
            "&szlig;", "ß"), "&amp;", "&"),
            "&lt;", "<"), "&gt;", ">"),
            "&eacute;", "é"), "&nbsp;", " ")
    }})
in
    #"HTML bereinigt"

Vragen:

  1. Is er een aanbevolen aanpak voor Teamleader Focus om 429-fouten en time-outs te voorkomen bij het vernieuwen in Power BI Service wanneer TicketMessagesAll wordt gebruikt?
  2. Zijn er gecachte of incrementele varianten van TicketMessagesAll beschikbaar, vergelijkbaar met incrementele synchronisatietabellen op andere platforms?
  3. Is het body-/omschrijvingsveld van een ticket toegankelijk via een andere tabel of endpoint die minder duur is qua API-aanroepen?

De aanpak verschilt van de aanpak die doorgaans wordt gebruikt. Het wordt aanbevolen om de persoon binnen uw bedrijf te raadplegen die de training van één uur over de reguliere aanpak gratis heeft gevolgd.

Raadpleeg voor 429-fouten:

om te bepalen welke rate limiter wordt overschreden.

Let op dat de tabelfunctie TicketMessagesByTicketId wordt uitgevoerd voor elk ticket afzonderlijk met filtering. Voor optimalisatie wordt het over het algemeen afgeraden om URL’s in code te construeren, tenzij de logica van de UniversalSQL Engine en OData volledig wordt begrepen, maar in plaats daarvan gebruik te maken van de voordelen van „query folding". OR-optimalisatie is over het algemeen niet beschikbaar op databaseplatforms.

Er is geen bekend efficiënt alternatief om de inhoud van alle berichten op te halen die door de Teamleader API’s worden aangeboden.

Deze vraag werd automatisch gesloten na ten minste 1 week van inactiviteit nadat een mogelijke oplossing was gegeven. Het laatste gegeven antwoord is als oplossing gemarkeerd.

Stel alstublieft een nieuwe vraag via een apart onderwerp als het probleem zich opnieuw voordoet. Voeg een link naar dit onderwerp toe in de nieuwe vraag door de URL ervan in de tekst te plakken.