Optimisation import csv quotidien en masse

  • Optimisation import csv quotidien en masse

    Posted by DSC Communities on January 10, 2022 at 7:47 pm

    Optimisation import csv quotidien en masseFollow
    Guillaume Ragues
    Guillaume RaguesJan 10, 2022 09:30 AM
    Bonjour Ć  tous, J’exporte tous les jours de SAP des tables en fichier .csv afin de pouvoir garder un …
    1. Optimisation import csv quotidien en masse

    Guillaume Ragues
    Posted Jan 10, 2022 09:30 AM
    Bonjour Ć  tous,

    J’exporte tous les jours de SAP des tables en fichier .csv afin de pouvoir garder un historique et faire des courbes d’Ć©volution et d’analyse dans Power BI.
    Une connexion directe ne me permettrait que d’avoir un Ć©tat instantanĆ©, et la fonction n’est de toute faƧon pas encore disponible chez nous.

    Chaque export de chaque table est rangƩ dans un dossier particulier.

    J’utilise l’importation par dossier et ma problĆ©matique est que cela reprĆ©sente une centaine de fichiers csv de chaque type dans plusieurs dossiers

    Chaque jour PowerBI réimporte donc les mêmes fichiers + les nouveaux du jour, ce qui prend tous les jours de plus en plus de temps pour des taches inutiles.
    Je prĆ©cise qu’une fois exportĆ©, les csv ne sont que trĆØs rarement modifiĆ©s Ć  posteriori.

    Auriez vous des idĆ©es afin d’optimiser tout Ƨa ?

    N’y aurait il pas une mĆ©thode pour importer les csv dans une table, les archivĆ©s puis rajoutĆ© tous les jours uniquement les nouveaux fichiers ?
    Ou de n’importĆ© dans le dossier que les nouveaux fichiers ou ceux qui auraient Ć©tĆ© modifiĆ© un peu comme dans un direct query ?

    A l’heure actuelle, ma seule idĆ©e serait de crĆ©er un fichier Excel avec une macro pour importer les csv, et dĆ©placer les csv dĆ©jĆ  importĆ© dans un dossier d’archive, un onglet par type de csv, et de connecter PowerBI Ć  ce fichier Excel… l’importation d’un fichier Excel Ć©tant bien plus rapide que l’importation de plusieurs centaines de csv Ć  nombre de ligne Ć©quivalent…

    Nous disposons d’un sharepoint d’entreprise et de PowerBI prĆ©mium

    ——————————
    Guillaume Ragues
    Responsable amƩlioration continue
    ——————————

    2. RE: Optimisation import csv quotidien en masse

    Gold Contributor
    Tristan Malherbe
    Posted Jan 10, 2022 09:36 AM
    Bonjour Guillaume,

    Je vous conseille de mettre en place un rafraƮchissement incrƩmental en vous basant sur la date de crƩation ou la date de modification de vos fichiers (propriƩtƩs disponibles en utilisant le connecteur Site SharePoint).

    Cela fonctionne parfaitement et ne nécessite même pas Power BI Premium.
    Bon courage !

    ——————————
    Tristan Malherbe
    Co-Fondateur du Club Power BI
    Expert/Formateur Power BI – Microsoft MVP
    ——————————

     

    3. RE: Optimisation import csv quotidien en masse

    Bronze Contributor
    Bertrand d’Arbonneau
    Posted Jan 11, 2022 08:07 AM
    A titre d’exemple, voici un code qui s’inspire d’un article trĆØs instructif de Miguel Escobar sur ce sujet (Incremental refresh for files in a Folder or SharePoint). Un des points importants (cf commentaire) est de prĆ©voir le cas où la combinaison de dates d’une partition ne ramĆØne aucun rĆ©sultat. Afin d’Ć©viter une erreur, la derniĆØre Ć©tape permet de retourner une table vide ayant le mĆŖme schema que lorsqu’il y a des resultats.

    AprĆØs avoir examinĆ© les traces http dans Fiddler, j’ai optĆ© pour Sharepoint.Contents plutot que Sharepoint.Files. Il m’a semblĆ© que le Query folding fonctionnait mieux ainsi.

    // Events
    let
    Source = SharePoint.Contents(myOneDriveURL, [ApiVersion = 15]),
    Documents = Source{[Name=”Documents”]}[Content],
    #”Power BI Audit events” = Documents{[Name=”Power BI Audit events”]}[Content],
    #”Filtered Rows” = Table.SelectRows(#”Power BI Audit events”, each [Date created] >= DateTimeZone.From(RangeStart) and [Date created] <= DateTimeZone.From(RangeEnd)),
    BufferBinaries = List.Transform(#”Filtered Rows”[Content],Binary.Buffer),
    TransformEachFile = List.Transform(BufferBinaries, f_TransformCSV),
    CombineIntoTable = Table.Combine(TransformEachFile),
    TryError = try CombineIntoTable otherwise Emptytable
    in
    TryError

    // RangeStart
    #datetime(2021, 1, 1, 0, 0, 0) meta [IsParameterQuery=true, Type=”DateTime”, IsParameterQueryRequired=true]

    // RangeEnd
    #datetime(2021, 1, 5, 0, 0, 0) meta [IsParameterQuery=true, Type=”DateTime”, IsParameterQueryRequired=true]

    // f_TransformCSV
    let
    Source = (Content as binary) => let
    #”Imported CSV” = Csv.Document(Content,[Delimiter=”,”, Encoding=65001, QuoteStyle=QuoteStyle.None]),
    #”Promoted Headers” = Table.PromoteHeaders(#”Imported CSV”, [PromoteAllScalars=true]),
    #”Removed Other Columns” = Table.SelectColumns(#”Promoted Headers”,{“CreationTime”, “Operation”, “WorkSpaceName”, “DatasetName”, “ReportName”, “WorkspaceId”, “ObjectId”, “DatasetId”, “ReportId”}),
    #”Changed Type” = Table.TransformColumnTypes(#”Removed Other Columns”,{{“CreationTime”, type datetime}, {“Operation”, type text}, {“WorkSpaceName”, type text}, {“DatasetName”, type text}, {“ReportName”, type text}, {“WorkspaceId”, type text}, {“ObjectId”, type text}, {“DatasetId”, type text}, {“ReportId”, type text}})
    in
    #”Changed Type”
    in
    Source

    // Emptytable
    let
    Source = #table (type table
    [
    #”CreationTime” = datetime,
    #”Operation” = text,
    #”WorkSpaceName” = text,
    #”DatasetName” = text,
    #”ReportName” = text,
    #”WorkspaceId” = text,
    #”ObjectId” = text,
    #”DatasetId” = text,
    #”ReportId” = text
    ] ,{})
    in
    Source

    ——————————
    Bertrand d’Arbonneau
    ——————————

     

    4. RE: Optimisation import csv quotidien en masse

    Guillaume Ragues
    Posted Feb 18, 2022 07:37 AM
    Bonjour Ć  tous les deux,

    DĆ©jĆ  un immense MERCI, je ne connaissais pas du tout l’actualisation incrĆ©mentielle, ni le Query folding. Rien qu’avec le Query folding en mixant votre de code et celui de Miguel l’actualisation est devenue beaucoup beaucoup plus rapide (et suffisante Ć  l’heure actuelle mĆŖme sans l’incrĆ©mentielle)

    En revanche pour aller plus loin avec l’actualisation incrĆ©mentielle j’ai encore quelques soucis…
    Avec une table Ƨa fonctionne parfaitement (qqs secondes au lieu de plusieurs minutes), par contre ce n’est pas prĆ©vu pour 3 tables comme dans mon cas…
    (Je ne vois pas comment ni l’intĆ©rĆŖt de combiner les 3 tables)

    Ma derniĆØre option Ć©tait de faire 3 flux de donnĆ©es avec chacune l’actualisation incrĆ©mentielle, mais le power query et le paramĆ©trage du rafraichissement incrĆ©mental n’est pas le mĆŖme que dans la version Desktop et cela ne fonctionne pas du tout !

    Pbi Desktop :
    Pbi Desktop
    PQuery_flux_donnƩes :
    PQuery_flux_donnƩes
    Dans le flux de donnĆ©es il m’oblige Ć  sĆ©lectionner une colonne de type datetime alors que dans la version desktop non.
    N’ayant pas de colonne Datetime dans le rĆ©sultat final de la table, cela ne fonctionne pas…

    code type actuel d’une des 3 tables :
    // fCSV_libƩ
    // Fonction de transformation des fichiers csv

    (Content as binary) => let
    #”Imported CSV” = Csv.Document(Binary.Buffer(Content),[Delimiter=”;”, Columns=4, Encoding=1252, QuoteStyle=QuoteStyle.None]),
    #”Promoted Headers” = Table.PromoteHeaders(#”Imported CSV”, [PromoteAllScalars=true]),
    #”Type modifiĆ©” = Table.TransformColumnTypes(#”Promoted Headers”,{{“Article”, type text}, {“Lot”, type text}, {“Jour de libĆ©ration”, Int64.Type}, {“Nb Pal”, Int64.Type}}),
    #”Lignes filtrĆ©es” = Table.SelectRows(#”Type modifiĆ©”, each [Article] <> null and [Article] <> “”)
    in
    #”Lignes filtrĆ©es”

    //myFX_libƩ
    //Fonction principal inpirƩ de votre code et celui de Miguel

    (StartDate as datetime, EndDate as datetime) =>

    let

    start = Date.From(StartDate),
    end = Date.From(EndDate),
    Fichiers = List.Transform(List.Dates(start,Number.From(end)-Number.From(start)+1,#duration(1, 0, 0, 0)), each “Lib_” & Date.ToText(Date.From(_), “yyyyMMdd”) & “.csv”),
    Source = SharePoint.Contents(“https://xxxxx.sharepoint.com/sites/xxxxx”, [ApiVersion=15]),
    #”Documents partages” = Source{[Name=”Documents partages”]}[Content],
    #”05 – SLR” = #”Documents partages”{[Name=”05 – SLR”]}[Content],
    #”05 – 04 – Extraction SAP” = #”05 – SLR”{[Name=”05 – 04 – Extraction SAP”]}[Content],
    #”LibĆ©ration” = #”05 – 04 – Extraction SAP”{[Name=”LibĆ©ration”]}[Content],
    #”Type modifiĆ©1″ = Table.TransformColumnTypes(#”LibĆ©ration”,{{“Date created”, type datetime}, {“Date modified”, type datetime}}),
    #”Filtered Rows” = Table.SelectRows(#”Type modifiĆ©1″, each List.Contains( List.Transform( Fichiers, (x)=> Text.Contains( [Name],x) ), true)),

    #”Fonction personnalisĆ©e appelĆ©e” = Table.AddColumn(#”Filtered Rows”, “Content.2″, each fCSV_libĆ©([Content])),

    AddFileNameToTable = Table.AddColumn(#”Fonction personnalisĆ©e appelĆ©e”, “Custom.1”, each Table.AddColumn([Content.2], “File Name”, (R)=> [Name],type text)),
    RemoveContentCol = Table.SelectColumns(AddFileNameToTable,{“Custom.1″}),
    #”Custom 1″ = Table.Combine(RemoveContentCol[Custom.1]),
    #”Plage de texte insĆ©rĆ©e” = Table.AddColumn(#”Custom 1″, “Date”, each Text.Middle([File Name], 4, 8), type text),
    #”Type modifiĆ©” = Table.TransformColumnTypes(#”Plage de texte insĆ©rĆ©e”,{{“Date”, type date}}),
    #”Colonnes supprimĆ©es” = Table.RemoveColumns(#”Type modifiĆ©”,{“File Name”}),
    #”PersonnalisĆ©e ajoutĆ©e” = Table.AddColumn(#”Colonnes supprimĆ©es”, “Jour de libĆ©ration (texte)”, each Text.End(“00″ & Text.From([Jour de libĆ©ration]),3),type text),

    Schema = #table( type table [Date = date, #”Article” = text, #”Lot” = text, #”Jour de libĆ©ration” = text, #”Nb Pal” = Int64.Type, #”Jour de libĆ©ration (chiffre)” = Int64.Type], {})
    in
    try #”PersonnalisĆ©e ajoutĆ©e” otherwise Schema

    //LibƩration
    //La table
    let
    Source = fx_libƩ(RangeStart,RangeEnd)
    in
    Source

    //RangeStart
    #datetime(2021, 8, 13, 13, 0, 42) meta [IsParameterQuery=true, Type=”DateTime”, IsParameterQueryRequired=true]

    //RangeEnd
    #datetime(2022, 2, 15, 8, 0, 0) meta [IsParameterQuery=true, Type=”DateTime”, IsParameterQueryRequired=true]​

    Si vous avez une idƩe pour pouvoir faire une actualisation incrƩmentale avec 3 tables ?

    PS : dĆ©solĆ© pour le temps de rĆ©ponse, grosse surcharge j’ai pu dĆ©marrer que cette semaine Ć  travailler le sujet …

    ——————————
    Guillaume Ragues
    Responsable amƩlioration continue
    ——————————

     

    5. RE: Optimisation import csv quotidien en masse

    Bronze Contributor
    Bertrand d’Arbonneau
    Posted Mar 04, 2022 03:46 AM
    La dĆ©marche pour un dataflow est lĆ©gĆØrement diffĆ©rente. Lorsque l’on veut mettre en place la politique de rafraichissement, il faut impĆ©rativement une colonne de type datetime. Et le dataflow ajoute automatiquement une Ć©tape de filtrage Ć  la fin, que l’on ne peut pas supprimer ou modifier (elle est recrĆ©e Ć  chaque sauvegarde). L’astuce consiste Ć  neutraliser cette Ć©tape en fournissant une colonne datetime bidon contenant la valeur du paramĆØtre RangeStart. Il faut bien entendu que prĆ©alablement on applique le filtrage par RangeStart et RangeEnd au plus prĆØs de la source pour assurer le query folding. On ajoute alors une colonne fixe datetime avec la valeur RangeStart, et on peut appliquer alors la politique de rafraichissement incrĆ©mental au niveau de l’entitĆ© du dataflow.

    Pour simplifier cette dĆ©marche et tester chaque Ć©tape, je commence Ć  mettre en place le query de base avec des paramĆØtres Range_Start et Range_End. J’applique la politique de rafraichissement sans effectuer de rafraichissement: cela crĆ©e les ‘vrais’ RangeStart et RangeEnd ainsi que la derniĆØre Ć©tape de filtrage. Je n’ai plus alors qu’Ć  modifier les rĆ©fĆ©rences Ć  Range_Start et Range_End et retirer le caractĆØre ‘_’.

    A noter que lorsqu’on veut rƩƩditer le query, il faut rƩƩcraser les valeurs de RangeStart et RangeEnd avec un range de test afin d’avoir des donnĆ©es visibles.

     

    ——————————
    Bertrand d’Arbonneau
    ——————————

    replied 3 years, 4 months ago 1 Member · 0 Replies
  • 0 Replies

Sorry, there were no replies found.

The discussion ‘Optimisation import csv quotidien en masse’ is closed to new replies.

Start of Discussion
0 of 0 replies June 2018
Now

Welcome to our new site!

Here you will find a wealth of information created for peopleĀ  that are on a mission to redefine business models with cloud techinologies, AI, automation, low code / no code applications, data, security & more to compete in the Acceleration Economy!