<?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 Using autoloader with multiple object types in load path in Data Engineering</title>
    <link>https://community.databricks.com/t5/data-engineering/using-autoloader-with-multiple-object-types-in-load-path/m-p/166090#M55527</link>
    <description>&lt;P&gt;My data source is going to generate csv files for multiple objects all into the same directory that I need to load from. The files will have names in the format along the lines of &amp;lt;objecttype&amp;gt;_YYYY_MM_DD_guid.csv.gz. Each objecttype will have it's own schema, and the goal is to load those files into objecttype tables.&lt;/P&gt;&lt;P&gt;I'm using Autoloader with cloudfiles to ingest these files. The objective is to have the process by dynamic and not have a static set of objecttypes, being able to adjust to new objecttypes being added. In my prototype, I'm performing an initial dbutils.fs.ls to get a file list and parse our the unique objecttypes. Then I loop through each objecttype, passing them to autoloader and globbing the objecttype out. But I feel this won't scale well as the number of files increases.&lt;/P&gt;&lt;P&gt;Is there a better method I can use to ingest these files and have them directed to the correct tables?&lt;/P&gt;</description>
    <pubDate>Thu, 20 Aug 2026 19:57:10 GMT</pubDate>
    <dc:creator>emorgoch</dc:creator>
    <dc:date>2026-08-20T19:57:10Z</dc:date>
    <item>
      <title>Using autoloader with multiple object types in load path</title>
      <link>https://community.databricks.com/t5/data-engineering/using-autoloader-with-multiple-object-types-in-load-path/m-p/166090#M55527</link>
      <description>&lt;P&gt;My data source is going to generate csv files for multiple objects all into the same directory that I need to load from. The files will have names in the format along the lines of &amp;lt;objecttype&amp;gt;_YYYY_MM_DD_guid.csv.gz. Each objecttype will have it's own schema, and the goal is to load those files into objecttype tables.&lt;/P&gt;&lt;P&gt;I'm using Autoloader with cloudfiles to ingest these files. The objective is to have the process by dynamic and not have a static set of objecttypes, being able to adjust to new objecttypes being added. In my prototype, I'm performing an initial dbutils.fs.ls to get a file list and parse our the unique objecttypes. Then I loop through each objecttype, passing them to autoloader and globbing the objecttype out. But I feel this won't scale well as the number of files increases.&lt;/P&gt;&lt;P&gt;Is there a better method I can use to ingest these files and have them directed to the correct tables?&lt;/P&gt;</description>
      <pubDate>Thu, 20 Aug 2026 19:57:10 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/using-autoloader-with-multiple-object-types-in-load-path/m-p/166090#M55527</guid>
      <dc:creator>emorgoch</dc:creator>
      <dc:date>2026-08-20T19:57:10Z</dc:date>
    </item>
    <item>
      <title>Re: Using autoloader with multiple object types in load path</title>
      <link>https://community.databricks.com/t5/data-engineering/using-autoloader-with-multiple-object-types-in-load-path/m-p/166092#M55528</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/112587"&gt;@emorgoch&lt;/a&gt;&amp;nbsp;,&lt;/P&gt;&lt;P&gt;Autoloader is absolutely the best tool when we just need to ingest new files as they land in storage. However, the way you are currently doing it—listing the files with dbutils and passing that list into Autoloader—isn't going to be very efficient. It actually bypasses a lot of the built-in magic that makes Autoloader so fast!&lt;/P&gt;&lt;P&gt;If you really need to cherry-pick specific files using dbutils, a much better approach is to use batching combined with threading.&lt;/P&gt;&lt;P&gt;Here is the catch you have to watch out for: standard Python threading only runs on the driver node. It can't distribute the Python threads themselves to your worker nodes. If you aren't careful, the threading will just run locally on the driver while your powerful worker nodes sit completely idle!&lt;/P&gt;&lt;P&gt;To get the full leverage of both your driver and your workers, we can use the threads on the driver just to kick off the Spark jobs. When we do this (and tell Spark to share resources), the driver handles the concurrency, but Spark distributes the actual heavy lifting across all your worker nodes in parallel.&lt;/P&gt;&lt;P&gt;By combining batching and threading this way, you'll see a massive performance boost. You can refer to the code below to see exactly how to set it up:&lt;/P&gt;&lt;LI-CODE lang="python"&gt;import concurrent.futures

# 1. Tell Spark to use the FAIR scheduler so concurrent threads can share the worker nodes
spark.conf.set("spark.scheduler.mode", "FAIR")

# Let's say this is your massive list of files from dbutils
all_files = [f"s3://your-bucket/file_{i}.parquet" for i in range(100)]

# 2. Break the files into manageable batches (e.g., 10 files per batch)
batch_size = 10
file_batches = [all_files[i:i + batch_size] for i in range(0, len(all_files), batch_size)]

# 3. Define the function that Spark will run for each batch
def process_batch(file_list):
    # Passing the list of files directly to spark.read distributes the work to the workers!
    df = spark.read.format("parquet").load(file_list)
    
    # Do your transformations and write the data
    df.write.format("delta").mode("append").save("/target/table")
    return f"Processed a batch of {len(file_list)} files successfully."

# 4. Use threading on the driver to submit these batches in parallel
# (max_workers defines how many parallel jobs the driver will try to submit at once)
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
    # Submit all the batches
    futures = [executor.submit(process_batch, batch) for batch in file_batches]
    
    # Wait for them to finish
    for future in concurrent.futures.as_completed(futures):
        print(future.result())&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 20 Aug 2026 21:42:38 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/using-autoloader-with-multiple-object-types-in-load-path/m-p/166092#M55528</guid>
      <dc:creator>ShamenParis</dc:creator>
      <dc:date>2026-08-20T21:42:38Z</dc:date>
    </item>
    <item>
      <title>Re: Using autoloader with multiple object types in load path</title>
      <link>https://community.databricks.com/t5/data-engineering/using-autoloader-with-multiple-object-types-in-load-path/m-p/166097#M55529</link>
      <description>&lt;P class="p8i6j01 paragraph"&gt;&lt;STRONG&gt;&lt;BR /&gt;&lt;/STRONG&gt;Use one Auto Loader streaming table per object type, generated from a governed configuration registry;&amp;nbsp; not&amp;nbsp;&lt;STRONG&gt;&lt;CODE class="p8i6j0f"&gt;dbutils.fs.ls&lt;/CODE&gt;.&lt;/STRONG&gt; Each object type needs an independent schema and checkpoint. Auto Loader cannot use one CSV stream to infer unrelated schemas and dynamically choose target tables: CSV inference produces one global schema for the stream.&lt;/P&gt;
&lt;P class="p8i6j01 paragraph"&gt;Prefer changing the landing layout to:&lt;/P&gt;
&lt;DIV class="l8rrz21 _1ibi0s3en" data-ui-element="code-block-container"&gt;
&lt;PRE&gt;&lt;CODE class="markdown-code-text p8i6j0e hljs language-text _12n1b832"&gt;&amp;lt;landing&amp;gt;/object_type=customer/...
&amp;lt;landing&amp;gt;/object_type=order/...
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;DIV class="l8rrz23 _1ibi0s3dp _1ibi0s332 _1ibi0s3eo _1ibi0s3bm _1ibi0s3ce"&gt;
&lt;DIV class="lqznwq0"&gt;&lt;SPAN&gt;If that is impossible, keep the shared directory and assign each stream a non-overlapping &lt;/SPAN&gt;&lt;CODE class="p8i6j0f"&gt;pathGlobFilter&lt;/CODE&gt;&lt;SPAN&gt;&lt;SPAN&gt;.&lt;BR /&gt;&lt;BR /&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;P&gt;&lt;STRONG&gt;Maintain a small registry containing:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Validated object type&lt;/LI&gt;
&lt;LI&gt;Expected CSV schema&lt;/LI&gt;
&lt;LI&gt;Target table&lt;/LI&gt;
&lt;LI&gt;Optional CSV parsing options&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;BR /&gt;Lakeflow Spark Declarative Pipelines can read this registry during pipeline planning and generate multiple streaming tables programmatically. The definitions are evaluated serially, but the resulting flows can execute in parallel. New objects become active on the next pipeline update. The registry should remain additive because removing a generated dataset causes that dataset to be dropped from the pipeline target schema.&lt;/P&gt;
&lt;P&gt;Each generated flow:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Reads the landing path with Auto Loader.&lt;/LI&gt;
&lt;LI&gt;Selects only its filenames using pathGlobFilter.&lt;/LI&gt;
&lt;LI&gt;Applies that object’s explicit schema.&lt;/LI&gt;
&lt;LI&gt;Writes to its own streaming table with independently managed state.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;BR /&gt;Auto Loader supports pre-compressed CSV files, including gzip. Lakeflow manages checkpoint and schema locations automatically; standalone streams require unique durable locations for each workload.&lt;/P&gt;
&lt;P&gt;For production discovery, enable managed file events. They share one notification queue per external location, require Unity Catalog and DBR 14.3 LTS or later, and should run at least every seven days to avoid falling back to directory listing.&lt;BR /&gt;&lt;BR /&gt;&lt;STRONG&gt;Minimal implementation example&lt;BR /&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;import re
from pyspark import pipelines as dp

SOURCE = "/Volumes/&amp;lt;source_catalog&amp;gt;/&amp;lt;source_schema&amp;gt;/&amp;lt;landing_volume&amp;gt;"

# Small governed registry:
# object_type STRING, schema_ddl STRING, enabled BOOLEAN
objects = (
    spark.table("&amp;lt;config_catalog&amp;gt;.&amp;lt;config_schema&amp;gt;.ingestion_objects")
         .where("enabled = true")
         .select("object_type", "schema_ddl")
         .collect()
)

def define_object_table(object_type: str, schema_ddl: str):
    # Prevent target-name or glob injection.
    if not re.fullmatch(r"[A-Za-z][A-Za-z0-9_]*", object_type):
        raise ValueError(f"Invalid object_type: {object_type}")

    &lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/25059"&gt;@DP&lt;/a&gt;.table(name=f"bronze_{object_type.lower()}")
    def ingest_object():
        return (
            spark.readStream
                 .format("cloudFiles")
                 .option("cloudFiles.format", "csv")
                 .option("header", "true")
                 .option(
                     "pathGlobFilter",
                     f"{object_type}_????_??_??_*.csv.gz"
                 )
                 .option("cloudFiles.useManagedFileEvents", "true")
                 .option("rescuedDataColumn", "_rescued_data")
                 .schema(schema_ddl)
                 .load(SOURCE)
                 .selectExpr(
                     "*",
                     "_metadata.file_path AS _source_file",
                     "current_timestamp() AS _ingested_at"
                 )
        )

for row in objects:
    define_object_table(row.object_type, row.schema_ddl)
&lt;/LI-CODE&gt;
&lt;P&gt;&lt;BR /&gt;Another alternative could be to look into DLT-Meta, which is a datbaricks labs project. Its a meta data driven pipeline config for spark declarative pipelines.&amp;nbsp;&lt;A href="https://docs.databricks.com/aws/en/ldp/developer/dlt-meta" target="_self"&gt;https://docs.databricks.com/aws/en/ldp/developer/dlt-meta&lt;/A&gt;&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;</description>
      <pubDate>Fri, 21 Aug 2026 00:53:35 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/using-autoloader-with-multiple-object-types-in-load-path/m-p/166097#M55529</guid>
      <dc:creator>adnan_alvee</dc:creator>
      <dc:date>2026-08-21T00:53:35Z</dc:date>
    </item>
  </channel>
</rss>

