<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Help with notebooks / multiple .csv files for complete newbie in Data Science</title>
    <link>https://community.fabric.microsoft.com/t5/Data-Science/Help-with-notebooks-multiple-csv-files-for-complete-newbie/m-p/3431931#M1</link>
    <description>&lt;P&gt;Hi, I have a need to ingest a ton of Power BI audit logs into Fabric. The eventual target is a Lakehouse table or tables. I have one log file per day (as csv), about 500 altogether. These files need extensive reshaping - things like pivoting attribute:value pairs into columns, parsing the text, etc. There's also reasonably large - about 40 or 50 million total lines, and maybe 4 or 5 million distinct audit log entries (see image below of a single entry)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I was going to do this using a Gen2 dataflow, but I can't figure out how to get a Gen2 dataflow to ingest a folder of files. Works perfectly with our on-prem network file shares, but in Fabric the Gen2 dataflow seems to want only one file at a time, no way to combine things under a Lakehouse Files section.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I'm a complete newbie on notebooks and really barely understand any Python (working to rectify that, going to take some time).&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here's a sample log file entry:&lt;/P&gt;&lt;P class="lia-indent-padding-left-30px"&gt;&lt;img /&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Things I've tried:&lt;/P&gt;&lt;P&gt;1. Using some of the sample code in the "learn fabric" paths to combine the files and publish to a Delta lakehouse table. This doesn't really work - if set VORDER on it screws up the order of lines in the audit log, making it impossible to associate lines with the proper audit log ID. If I turn VORDER off, querying the resulting table returns "&lt;FONT color="#FF0000"&gt;&lt;SPAN&gt;Failed to read parquet file because the column segment for column '_c0' is too large&lt;/SPAN&gt;&lt;/FONT&gt;"&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;2. I've tried using code like the following to append the 500 individual csv files into a single file. But it doesn't work - it seems instead to create a folder that has a ton of separate files in it instead of a single large file&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;DIV class="lia-indent-padding-left-30px"&gt;&lt;STRONG&gt;df = spark.read.format("csv").load('Files/Power BI audit logs/Audit log*.csv')&lt;/STRONG&gt;&lt;/DIV&gt;&lt;DIV class="lia-indent-padding-left-30px"&gt;&lt;STRONG&gt;df.write.mode("overwrite").format("csv").save("Files/singleFile")&lt;/STRONG&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Any ideas or guidance would be greatly appreciated - thanks!&lt;/P&gt;&lt;P&gt;Scott&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Thu, 14 Sep 2023 22:35:35 GMT</pubDate>
    <dc:creator>Scott_Powell</dc:creator>
    <dc:date>2023-09-14T22:35:35Z</dc:date>
    <item>
      <title>Help with notebooks / multiple .csv files for complete newbie</title>
      <link>https://community.fabric.microsoft.com/t5/Data-Science/Help-with-notebooks-multiple-csv-files-for-complete-newbie/m-p/3431931#M1</link>
      <description>&lt;P&gt;Hi, I have a need to ingest a ton of Power BI audit logs into Fabric. The eventual target is a Lakehouse table or tables. I have one log file per day (as csv), about 500 altogether. These files need extensive reshaping - things like pivoting attribute:value pairs into columns, parsing the text, etc. There's also reasonably large - about 40 or 50 million total lines, and maybe 4 or 5 million distinct audit log entries (see image below of a single entry)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I was going to do this using a Gen2 dataflow, but I can't figure out how to get a Gen2 dataflow to ingest a folder of files. Works perfectly with our on-prem network file shares, but in Fabric the Gen2 dataflow seems to want only one file at a time, no way to combine things under a Lakehouse Files section.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I'm a complete newbie on notebooks and really barely understand any Python (working to rectify that, going to take some time).&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here's a sample log file entry:&lt;/P&gt;&lt;P class="lia-indent-padding-left-30px"&gt;&lt;img /&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Things I've tried:&lt;/P&gt;&lt;P&gt;1. Using some of the sample code in the "learn fabric" paths to combine the files and publish to a Delta lakehouse table. This doesn't really work - if set VORDER on it screws up the order of lines in the audit log, making it impossible to associate lines with the proper audit log ID. If I turn VORDER off, querying the resulting table returns "&lt;FONT color="#FF0000"&gt;&lt;SPAN&gt;Failed to read parquet file because the column segment for column '_c0' is too large&lt;/SPAN&gt;&lt;/FONT&gt;"&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;2. I've tried using code like the following to append the 500 individual csv files into a single file. But it doesn't work - it seems instead to create a folder that has a ton of separate files in it instead of a single large file&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;DIV class="lia-indent-padding-left-30px"&gt;&lt;STRONG&gt;df = spark.read.format("csv").load('Files/Power BI audit logs/Audit log*.csv')&lt;/STRONG&gt;&lt;/DIV&gt;&lt;DIV class="lia-indent-padding-left-30px"&gt;&lt;STRONG&gt;df.write.mode("overwrite").format("csv").save("Files/singleFile")&lt;/STRONG&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Any ideas or guidance would be greatly appreciated - thanks!&lt;/P&gt;&lt;P&gt;Scott&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 14 Sep 2023 22:35:35 GMT</pubDate>
      <guid>https://community.fabric.microsoft.com/t5/Data-Science/Help-with-notebooks-multiple-csv-files-for-complete-newbie/m-p/3431931#M1</guid>
      <dc:creator>Scott_Powell</dc:creator>
      <dc:date>2023-09-14T22:35:35Z</dc:date>
    </item>
    <item>
      <title>Re: Help with notebooks / multiple .csv files for complete newbie</title>
      <link>https://community.fabric.microsoft.com/t5/Data-Science/Help-with-notebooks-multiple-csv-files-for-complete-newbie/m-p/3432557#M2</link>
      <description>&lt;P&gt;&lt;a href="javascript:void(0)" data-lia-user-mentions="" data-lia-user-uid="535913" data-lia-user-login="Scott_Powell" class="lia-mention lia-mention-user"&gt;Scott_Powell&lt;/a&gt;&amp;nbsp;It sounds like you have quite the challenge on your hands, Scott!&lt;span class="lia-unicode-emoji" title=":winking_face:"&gt;😉&lt;/span&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;&lt;P&gt;For reading in the files, Spark has ability to read multiple csv files into a single DataFrame is definitely good way to get started , However i highly suggest adding a unique ID field to each row is a smart idea to preserve order later on. ( The error you mentioned sounds more like a corrupted parquet structure error at first glance)&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;&lt;P&gt;Since you mentioned extensive data reshaping is needed, we can work together on the transformations - whether it's parsing text fields, pivoting, or anything else. Feel free to connect and share some example rows and we can prototype the logic.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Finally i would suggest instead of output as&amp;nbsp; CSV try outputing the input csv in to Delta format in a Lakehouse architecture makes sense for your further workloads&lt;BR /&gt;&lt;SPAN&gt;The main thought is to maintain data integrity - both in order and values - as i suggest you move from raw CSVs to a transformed Delta table.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 15 Sep 2023 08:32:26 GMT</pubDate>
      <guid>https://community.fabric.microsoft.com/t5/Data-Science/Help-with-notebooks-multiple-csv-files-for-complete-newbie/m-p/3432557#M2</guid>
      <dc:creator>puneetvijwani</dc:creator>
      <dc:date>2023-09-15T08:32:26Z</dc:date>
    </item>
    <item>
      <title>Re: Help with notebooks / multiple .csv files for complete newbie</title>
      <link>https://community.fabric.microsoft.com/t5/Data-Science/Help-with-notebooks-multiple-csv-files-for-complete-newbie/m-p/3961982#M187</link>
      <description>&lt;P&gt;&lt;a href="javascript:void(0)" data-lia-user-mentions="" data-lia-user-uid="535913" data-lia-user-login="Scott_Powell" class="lia-mention lia-mention-user"&gt;Scott_Powell&lt;/a&gt;&amp;nbsp;-&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I read a lot of files data that are fed into OneLake via API calls to external systems.&amp;nbsp; Even though my data source are .json files; the code below will work for .csv files as well.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;#Imports and Includes to use different functions down the line
from pyspark.sql.functions import *
from pyspark.sql.window import *
from pyspark.sql.types import DateType
from pyspark.sql.functions import to_date,to_timestamp,sequence
from delta.tables import *

##Define a Parameter Cell in the Notebook to be able to dynamically pass a file struct
_year = "9999"
_month = "5"
_day = "2"

##Generating the path to my files dynamically
##Instead of *.json you can use *.csv as this will look for any file that ends .csv for the path specific.

_root = "Files/XCM/TaskSignOff"
_path = "/" + _year + "/" + "/" + _month +  "/" + _day + "/*.json"
_full = _root + _path

##If your CSV file has a defined schema, I recommend defining the schema in your Notebook so you can control schema drift.  I am calling out the expect elements/headers that will be in the files that I am reading.  By setting the schema, if the vendor adds a new field; we do not necessarily bring it in right away.

_schema = StructType(
    [
        StructField("taskId",StringType()),
        StructField("signOffId",StringType()),
        StructField("comments",StringType()),
        StructField("requiredComments",StringType()),
        StructField("requiredDate",StringType()),
        StructField("requiredName",StringType()),
        StructField("signOffBy",StringType()),
        StructField("signOffComments",StringType()),
        StructField("signOffDate",StringType()),
        StructField("signOffRequired",StringType()),
        StructField("signOffName",StringType()),
        StructField("statusName",StringType()),
        StructField("updatedBy",StringType()),
        StructField("updatedOn",StringType())
    ]
)

##Actual Dataframe ingestion
##Change format form 'json' to 'csv'
##I also append the source path &amp;amp; file name to my column set
_df = spark.read.format('json').schema(_schema).load(_full).select("*","_metadata.file_name","_metadata.file_path")

##Display the results of the read (first 1000 rows)
display(_df)

##Write to Delta Table
##Write Initial Task List To Delta
_df.write.mode("append").format("delta").save("Tables/&amp;lt;Table_Name&amp;gt;")&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;When you try to write to a file from spark, all of the different work threads have part of the data.&amp;nbsp; So each worker writes their piece of the pie which results in a bunch of files with guids and other oddities for names.&amp;nbsp; In order to write as a single file you would have to call the collect() statement and that would then result in&amp;nbsp;&lt;EM&gt;&lt;STRONG&gt;all data&lt;/STRONG&gt;&lt;/EM&gt;&lt;EM&gt;&amp;nbsp;&lt;/EM&gt;getting combined in 1 single worker and then you could write the data.&amp;nbsp; It is a very memory intensive operation.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Hope this helps out a little bit.&lt;/P&gt;</description>
      <pubDate>Thu, 30 May 2024 18:32:48 GMT</pubDate>
      <guid>https://community.fabric.microsoft.com/t5/Data-Science/Help-with-notebooks-multiple-csv-files-for-complete-newbie/m-p/3961982#M187</guid>
      <dc:creator>jwinchell40</dc:creator>
      <dc:date>2024-05-30T18:32:48Z</dc:date>
    </item>
  </channel>
</rss>

