<?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>article Performing DML Operations on Unity Catalog Managed Tables from External Engines in Technical Blog</title>
    <link>https://community.databricks.com/t5/technical-blog/performing-dml-operations-on-unity-catalog-managed-tables-from/ba-p/156308</link>
    <description>&lt;H2&gt;&lt;SPAN&gt;Summary&lt;/SPAN&gt;&lt;/H2&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;External engines — &lt;/SPAN&gt;&lt;A href="https://spark.apache.org/" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Apache Spark&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;™ (batch and Structured Streaming), &lt;/SPAN&gt;&lt;A href="https://duckdb.org/" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;DuckDB&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;, &lt;/SPAN&gt;&lt;A href="https://flink.apache.org/" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Apache Flink&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;, &lt;/SPAN&gt;&lt;A href="https://docs.starburst.io/starburst-galaxy/working-with-data/create-catalogs/non-object-storage/unity.html" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Starburst&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;, and &lt;/SPAN&gt;&lt;A href="https://streamnative.io/" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;StreamNative&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; Kafka Service — can now create, read, and write Unity Catalog-managed Delta tables from outside Databricks, with every commit coordinated by Unity Catalog.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;UC serializes commits across engines, so concurrent external writers don't corrupt the transaction log; every operation is auditable; and &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/optimizations/predictive-optimization" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Predictive Optimization&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; continues to manage table health (compaction, vacuuming, statistics)&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Ships with &lt;/SPAN&gt;&lt;A href="https://github.com/delta-io/delta/releases/tag/v4.2.0" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Delta Lake 4.2.0&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; and &lt;/SPAN&gt;&lt;A href="https://github.com/unitycatalog/unitycatalog/releases/tag/v0.4.1" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Unity Catalog 0.4.1&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;. Grant&lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt; EXTERNAL_USE_SCHEMA&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt;, authenticate with M2M OAuth, and external clients are up and running in minutes — reading from and writing to &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/external-access/unity-rest" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Unity Catalog managed Delta tables&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; through the Unity REST API.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN&gt;The &lt;/SPAN&gt;&lt;A href="https://www.databricks.com/product/data-lakehouse" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;open data lakehouse&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; is built on a simple principle: maintain a single copy of your data, govern it centrally, and access it from the engine best suited to each workload. Previously, we launched &lt;/SPAN&gt;&lt;A href="https://www.databricks.com/blog/secure-external-access-unity-catalog-assets-open-apis" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;UC Open APIs&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; and credential vending, enabling external engines to access tables in Unity Catalog. Now, we are evolving this vision to safely create or write to them.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;The Beta of External Access to Unity Catalog Managed Tables with &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/delta/catalog-commits" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Catalog Commits&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; extends Unity Catalog’s open APIs to deliver full read and write interoperability for managed Delta tables from external engines. External engines can now create, read, and write to these tables, while Unity Catalog coordinates every transaction to ensure consistency, governance, and safe multi-engine operation.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Enterprises can bring the best engine to every workload and benefit from price/performance optimizations –without moving or duplicating data. This further establishes Unity Catalog as the industry's most open and interoperable catalog: one copy of data, governed centrally, and accessible from any engine, without requiring separate copies for different platforms or workloads.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;In this blog, we walk through how to perform DML operations on Unity Catalog managed Delta tables from external engines using Apache Spark™ and DuckDB. You can find the complete code examples in &lt;/SPAN&gt;&lt;A href="https://github.com/databricks-solutions/databricks-blogposts/tree/main/2026-05-external-access-to-unity-catalog-managed-delta-tables" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;this GitHub repository&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Scope note. This Beta is for managed Delta tables only. Managed Iceberg tables already support external writes through Iceberg REST in Public Preview, so both open formats under Unity Catalog now offer full external read, write, and create from outside Databricks.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Scope of this walkthrough. The Beta currently ships connector integrations for five engines: Apache Spark™, DuckDB, Apache Flink, Starburst, and StreamNative Kafka Service. The hands-on examples below cover Apache Spark™, DuckDB, and Apache Flink end to end. Starburst and StreamNative Kafka Service use the same Delta Kernel + catalog-commits substrate, so the integration is identical; see their connector docs for SDK-specific setup.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;STRONG&gt;How Unity Catalog Enables Safe External Writes&lt;/STRONG&gt;&lt;/H2&gt;
&lt;H3&gt;&lt;STRONG&gt;The Challenge of Coordinating Writes&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;Delta tables track every change in an ordered transaction log. When two writers append concurrently without a coordinator, they can pick the same log version, corrupt the log, or silently overwrite each other. Reads alone are safe—they're snapshot-isolated by design—but writes from multiple external engines on the same table were not.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Catalog Commits: A Centralized Commit Coordinator&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;Catalog commits solve this by making Unity Catalog the commit coordinator. Every write—regardless of which engine initiated it—flows through Unity Catalog, which serializes commits, enforces access controls, and records each operation for audit. Because Unity Catalog sees every external operation, &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/optimizations/predictive-optimization" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Predictive Optimization&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; continues to maintain table health even when tables are written entirely by engines outside Databricks. Catalog commits also lay the foundation for capabilities that require centralized coordination, such as &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/transactions/" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;multi-table transactions&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Delta Kernel: The Foundation for Open Connectivity&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;The open source library that enables connector authors to make this possible is Delta Kernel—a set of Java and Rust APIs for reading, writing, and committing to Delta tables. Delta Kernel abstracts the low-level Delta protocol, so new connectors need only integrate it into their engine's I/O layer. Apache Spark™ integration (&lt;/SPAN&gt;&lt;SPAN&gt;unitycatalog-spark&lt;/SPAN&gt;&lt;SPAN&gt;), Apache Flink, StreamNative, and the DuckDB integration (&lt;/SPAN&gt;&lt;SPAN&gt;unity_catalog&lt;/SPAN&gt;&lt;SPAN&gt; core extension) are built on Delta Kernel.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3&gt;&lt;SPAN&gt;Authentication: M2M OAuth&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;External clients authenticate to Databricks using &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/dev-tools/auth/oauth-m2m" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;machine-to-machine (M2M) OAuth&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; with a service principal. &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/dev-tools/auth/pat" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Personal Access Tokens&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; (PATs) are also supported, but they're legacy, per-user, long-lived, and difficult to rotate.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;The Databricks SDK fetches a short-lived access token from the Service Principal's client credentials:&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;from databricks.sdk.core import Config, oauth_service_principal

def get_oauth_token() -&amp;gt; str:
    config = Config(
        host=DATABRICKS_HOST,
        client_id=DATABRICKS_CLIENT_ID,
        client_secret=DATABRICKS_CLIENT_SECRET,
    )
    token_source = oauth_service_principal(config)
    return token_source().access_token&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN&gt;For the Spark connector, you don't need to mint a token yourself — the connector accepts the SP's client credentials and refreshes its own tokens against &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;/oidc/v1/token&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; whenever they expire. This is the production path for long-running pipelines (especially Structured Streaming).&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3&gt;&lt;SPAN&gt;Setting up the demo catalog&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;From a Databricks workspace, create a catalog and schema. For this blog, we have cloned eight &lt;/SPAN&gt;&lt;SPAN&gt;samples.tpch&lt;/SPAN&gt;&lt;SPAN&gt; tables as UC-managed Delta tables into the schema, and granted &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;EXTERNAL_USE_SCHEMA&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; on the schema to the Service Principal that the external engines will authenticate as. Full DDL is in &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;00_setup_databricks.sql&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt;; the essentials:&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;DROP CATALOG IF EXISTS uc_ext_access_demo CASCADE;
CREATE CATALOG uc_ext_access_demo;
CREATE SCHEMA  uc_ext_access_demo.tpch_managed;
USE CATALOG uc_ext_access_demo;
USE SCHEMA  tpch_managed;
CREATE OR REPLACE TABLE customer TBLPROPERTIES ('delta.feature.catalogManaged' = 'supported') AS SELECT * FROM samples.tpch.customer;
CREATE OR REPLACE TABLE orders TBLPROPERTIES ('delta.feature.catalogManaged' = 'supported') AS SELECT * FROM samples.tpch.orders;
-- repeat for lineitem, nation, part, partsupp, region, supplier
GRANT USE CATALOG          ON CATALOG uc_ext_access_demo                   TO `&amp;lt;SP_CLIENT_ID&amp;gt;`;
GRANT USE SCHEMA, SELECT, MODIFY, CREATE TABLE, EXTERNAL_USE_SCHEMA  ON SCHEMA  uc_ext_access_demo.tpch_managed TO `&amp;lt;SP_CLIENT_ID&amp;gt;`;&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN&gt;The &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;DROP CATALOG IF EXISTS … CASCADE&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; at the start makes this idempotent — every run wipes prior state and reseeds, so the demo always starts from a known baseline.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;DuckDB — READ and INSERT&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;DuckDB connects to Unity Catalog via two core extensions — &lt;/SPAN&gt;&lt;SPAN&gt;unity_catalog&lt;/SPAN&gt;&lt;SPAN&gt; (Databricks UC integration) and &lt;/SPAN&gt;&lt;SPAN&gt;delta&lt;/SPAN&gt;&lt;SPAN&gt; (Kernel-based Delta reader/writer). Both are installed and loaded at runtime, then a single anonymous &lt;/SPAN&gt;&lt;SPAN&gt;UNITY_CATALOG&lt;/SPAN&gt;&lt;SPAN&gt; secret carries the OAuth token, and the &lt;/SPAN&gt;&lt;SPAN&gt;ATTACH&lt;/SPAN&gt;&lt;SPAN&gt; integrates the catalog into DuckDB's namespace:&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;con = duckdb.connect()
con.execute("INSTALL unity_catalog; LOAD unity_catalog;")
con.execute("INSTALL delta; LOAD delta;")
con.execute(f"""
    CREATE SECRET (
        TYPE UNITY_CATALOG,
        TOKEN     '{get_oauth_token()}',
        ENDPOINT  '{DATABRICKS_HOST}/',
        AWS_REGION '{AWS_REGION}'
    );
""")

con.execute("""
    ATTACH 'uc_ext_access_demo' AS uc_ext_access_demo
        (TYPE UNITY_CATALOG);
""")&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN&gt;Two details that the &lt;/SPAN&gt;&lt;A href="https://duckdb.org/docs/current/core_extensions/unity_catalog" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;official `unity_catalog` extension docs&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; emphasize: the &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;ENDPOINT&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; is the workspace root URL (not &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;&amp;lt;host&amp;gt;/api/2.1/unity-catalog&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt;), and the &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;SECRET&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; is created without a name, so the extension auto-resolves it by type when &lt;/SPAN&gt;&lt;SPAN&gt;ATTACH&lt;/SPAN&gt;&lt;SPAN&gt; runs without an explicit &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;SECRET&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; reference.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;The cloned TPCH tables behave like native DuckDB tables. Read, scan, JOIN — all the standard DuckDB SQL surface works against managed Delta tables:&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;con.execute("""
    SELECT n.n_name, count(*) AS customer_count
    FROM uc_ext_access_demo.tpch_managed.customer c
    JOIN uc_ext_access_demo.tpch_managed.nation   n
      ON c.c_nationkey = n.n_nationkey
    GROUP BY n.n_name
    ORDER BY customer_count DESC
    LIMIT 5
""").fetchdf()&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN&gt;And with &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;INSERT INTO&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; support, DuckDB can now append rows directly to existing Unity Catalog managed Delta tables. UC serializes the commit, the Delta extension runs the actual write through the kernel, and Spark / Databricks readers see the new rows immediately:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;orders = "uc_ext_access_demo.tpch_managed.orders"&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;# Single-row VALUES — three rows in one statement
con.execute(f"""
    INSERT INTO {orders} (
        o_orderkey, o_custkey, o_orderstatus, o_totalprice,
        o_orderdate, o_orderpriority, o_clerk, o_shippriority, o_comment
    ) VALUES
        (9000000301, 1, 'O', 100.00, DATE '2026-04-23', '3-MEDIUM',
         'Clerk#external-duckdb', 0, 'duckdb single-row insert'),
        (9000000302, 2, 'O', 200.00, DATE '2026-04-23', '3-MEDIUM',
         'Clerk#external-duckdb', 0, 'duckdb single-row insert'),
        (9000000303, 3, 'O', 300.00, DATE '2026-04-23', '5-LOW',
         'Clerk#external-duckdb', 0, 'duckdb single-row insert');
""")

# Bulk insert from another UC table
con.execute(f"""
    INSERT INTO {orders}
    SELECT
        o_orderkey + 9_000_000_400 AS o_orderkey,
        o_custkey, o_orderstatus, o_totalprice, o_orderdate,
        o_orderpriority,
        'Clerk#external-duckdb-bulk' AS o_clerk,
        o_shippriority,
        'duckdb bulk insert' AS o_comment
    FROM {orders}
    WHERE o_orderkey BETWEEN 11396166 AND 11396175
""")&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN&gt;The DuckDB &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;unity_catalog&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; extension is currently focused on the read and &lt;FONT face="courier new,courier"&gt;INSERT&lt;/FONT&gt; path against Databricks UC; the &lt;/SPAN&gt;&lt;A href="https://duckdb.org/docs/current/core_extensions/unity_catalog" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;extension docs&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; are the source of truth for what's supported as the integration evolves.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Apache Spark™ — batch read&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;The Spark connector for Unity Catalog (&lt;/SPAN&gt;&lt;SPAN&gt;unitycatalog-spark&lt;/SPAN&gt;&lt;SPAN&gt;) is the reference implementation for catalog commits. Configure a Spark session outside Databricks, point it at your workspace, and let the connector handle the OAuth flow:&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;spark = (
    SparkSession.builder.appName("uc-external-access-demo")
    .config("spark.jars.packages",
            "io.delta:delta-spark_2.13:4.2.0,"
            "io.unitycatalog:unitycatalog-spark_2.13:0.4.1,"
            "org.apache.hadoop:hadoop-aws:3.4.2")
    .config("spark.sql.extensions",
            "io.delta.sql.DeltaSparkSessionExtension")
    .config("spark.sql.catalog.spark_catalog",
            "org.apache.spark.sql.delta.catalog.DeltaCatalog")
# Register UC as a Spark catalog with M2M OAuth
    .config(f"spark.sql.catalog.{UC_CATALOG}",
            "io.unitycatalog.spark.UCSingleCatalog")
    .config(f"spark.sql.catalog.{UC_CATALOG}.uri", DATABRICKS_HOST)
    .config(f"spark.sql.catalog.{UC_CATALOG}.auth.type", "oauth")
    .config(f"spark.sql.catalog.{UC_CATALOG}.auth.oauth.uri",
            f"{DATABRICKS_HOST}/oidc/v1/token")
    .config(f"spark.sql.catalog.{UC_CATALOG}.auth.oauth.clientId",
            DATABRICKS_CLIENT_ID)
    .config(f"spark.sql.catalog.{UC_CATALOG}.auth.oauth.clientSecret",
            DATABRICKS_CLIENT_SECRET)
    .config(f"spark.sql.catalog.{UC_CATALOG}.renewCredential.enabled", "true")
    .config("spark.sql.defaultCatalog", UC_CATALOG)
    # UC returns s3:// URIs; map them to Hadoop's S3A FileSystem
    .config("spark.hadoop.fs.s3.impl",
            "org.apache.hadoop.fs.s3a.S3AFileSystem")
    .config("spark.hadoop.fs.AbstractFileSystem.s3.impl",
            "org.apache.hadoop.fs.s3a.S3A")
).getOrCreate()

&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN&gt;A few config lines worth calling out: &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;auth.type=oauth&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; is what tells the connector to mint and refresh tokens itself, so a long-running session doesn't expire mid-job. And &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;spark.hadoop.fs.s3.impl=S3AFileSystem&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; is the bridge between UC's &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;s3://&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; URIs and Hadoop's S3A driver.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Once that's established, reading a managed Delta table from the external Spark process looks identical to reading any other Spark table — every operation goes through UC behind the scenes:&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;spark.table("uc_ext_access_demo.tpch_managed.orders").show(5)
spark.sql(
    "DESCRIBE HISTORY uc_ext_access_demo.tpch_managed.orders"
).show(truncate=False)&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN&gt;The &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;DESCRIBE HISTORY&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; output will show &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;engineInfo = Apache-Spark/4.1.1 Delta-Lake/4.2.0&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; for any commit produced by this external session — alongside the original &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;Databricks-Runtime/...&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; commit that seeded the table using a &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/compute/sql-warehouse/" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Databricks SQL Warehouse&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Apache Spark™ — batch write&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;The same external session can append rows or create a brand-new managed Delta table with &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;CREATE TABLE AS SELECT&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt;:&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;new_df.write.mode("append").saveAsTable(
    "uc_ext_access_demo.tpch_managed.orders"
)
spark.sql("""
    CREATE TABLE uc_ext_access_demo.tpch_managed.orders_summary
    USING DELTA
    TBLPROPERTIES ('delta.feature.catalogManaged' = 'supported')
    AS
    SELECT
      o_orderstatus,
      o_orderpriority,
      count(*)             AS order_count,
      sum(o_totalprice)    AS total_value,
      avg(o_totalprice)    AS avg_value
    FROM uc_ext_access_demo.tpch_managed.orders
    GROUP BY o_orderstatus, o_orderpriority
""")&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN&gt;Two things worth noting:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;`USING DELTA TBLPROPERTIES ('delta.feature.catalogManaged' = 'supported')` is required when an external engine creates a managed Delta table for the first time. This is the table-level feature flag that enables catalog-managed commits — UC would otherwise reject the create managed table request.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;`saveAsTable` DataFrame writer just works for appending to existing managed tables; no DDL feature flag needed at append time because the property is already set.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN&gt;Once both writes are complete, &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;DESCRIBE HISTORY&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; shows the original Databricks-Runtime CTAS sitting alongside the new &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;Apache-Spark/4.1.1 Delta-Lake/4.2.0&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; commits — same managed table, multiple engine&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;writes with catalog commits.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Apache Spark™ — Structured Streaming&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;Catalog-managed commits also cover Structured Streaming writes. Each micro-batch becomes a single UC commit, attributed to the external Spark engine. The pattern below uses Spark's built-in &lt;/SPAN&gt;&lt;SPAN&gt;rate&lt;/SPAN&gt;&lt;SPAN&gt; source, so the example is self-contained — no external broker required — but the exact same code shape works for Kafka, Kinesis, files, anything Spark can stream from.&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;spark.sql("""
    CREATE TABLE uc_ext_access_demo.tpch_managed.orders_stream (
        o_orderkey BIGINT, o_custkey BIGINT, o_orderstatus STRING,
        o_totalprice DECIMAL(18,2), o_orderdate DATE,
        o_orderpriority STRING, o_clerk STRING,
        o_shippriority INT, o_comment STRING
    )
    USING DELTA
    TBLPROPERTIES ('delta.feature.catalogManaged' = 'supported')
""")

src=(
    spark.readStream.format("rate")
    .option("rowsPerSecond", 50)
    .load()
)
shaped = (
    src
    .withColumn("o_orderkey",   (lit(9_100_000_000) + col("value")).cast("bigint"))
    .withColumn("o_custkey",    ((col("value") % lit(1500)) + lit(1)).cast("bigint"))
    .withColumn("o_orderstatus", lit("O"))
    .withColumn("o_totalprice",  expr("cast(rand() * 1000 as decimal(18,2))"))
    .withColumn("o_orderdate",   current_date())
    .withColumn("o_orderpriority", lit("3-MEDIUM"))
    .withColumn("o_clerk",       lit("Clerk#external-spark-stream"))
    .withColumn("o_shippriority", lit(0))
    .withColumn("o_comment",
     concat(lit("streamed by external Spark @ batch_value="),
     col("value").cast("string")))
    .select("o_orderkey", "o_custkey", "o_orderstatus", "o_totalprice",
     "o_orderdate", "o_orderpriority", "o_clerk",
     "o_shippriority", "o_comment")
)

query = (
    shaped.writeStream
    .format("delta")
    .outputMode("append")
    .option("checkpointLocation", "/tmp/orders_stream_ckpt")
    .trigger(processingTime="5 seconds")
    .toTable("uc_ext_access_demo.tpch_managed.orders_stream")
)

query.awaitTermination(30)   # run for ~30 seconds, then exit&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN&gt;After the stream stops, &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;DESCRIBE HISTORY&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; on &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;orders_stream&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; shows the &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;CREATE TABLE&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; commit (version 0) followed by a &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;STREAMING UPDATE&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; for each micro-batch — everyone tagged &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;Apache-Spark/4.1.1 Delta-Lake/4.2.0&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt;. The checkpoint is a local directory; UC only coordinates the catalog commit itself, not the engine's micro-batch state.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Apache Flink — Streaming Sink to a UC Managed Delta Table&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;Delta Lake 4.2 ships a brand-new Flink connector built on Delta Kernel — the legacy Flink connector deprecated in Delta 4.0 alongside Delta Standalone is gone, and the new connector supports Unity Catalog managed Delta tables from inception. It is sink-only and experimental today, with exactly-once semantics backed by a Flink Sink Writer and a single global Committer — every Flink checkpoint becomes one UC commit on the target table. The connector accepts a bearer credential through the Flink catalog's token field. Personal Access Tokens (PATs) work here, and so do machine-to-machine (M2M) OAuth bearer tokens — this demo passes the M2M OAuth bearer token used by the DuckDB and Spark sections (PATs are considered legacy at Databricks).&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;The pattern below pairs a bounded datagen source (so the job terminates cleanly without an explicit STOP JOB) with a UC-managed Delta sink created up front with delta.feature.catalogManaged='supported'. Each Flink checkpoint produces a real Delta version coordinated by UC.&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;SET 'table.dml-sync' = 'true';
-- Register Unity Catalog as a Flink catalog. The Flink catalog name must
-- match the UC catalog name so 3-part identifiers resolve straight through.
CREATE CATALOG `uc_ext_access_demo` WITH (
  'type' = 'unitycatalog',
  'endpoint' = '&amp;lt;DATABRICKS_HOST&amp;gt;/',
  'token' = '&amp;lt;BEARER_TOKEN&amp;gt;'
);

CREATE TEMPORARY TABLE flink_orders_flink_src (
  seq BIGINT,
  payload STRING
) WITH (
  'connector' = 'datagen',
  'rows-per-second' = '100',
  'fields.seq.kind' = 'sequence',
  'fields.seq.start' = '1',
  'fields.seq.end' = '3000',
  'fields.payload.length' = '24'
);

INSERT INTO `uc_ext_access_demo`.`tpch_managed`.`orders_flink`
SELECT
  CAST(9200000000 + seq AS BIGINT)                 AS o_orderkey,
  CAST((seq % 1500) + 1 AS BIGINT)                 AS o_custkey,
  CAST('O' AS STRING)                              AS o_orderstatus,
  CAST(MOD(seq * 7, 1000) AS DECIMAL(18,2))        AS o_totalprice,
  CURRENT_DATE                                     AS o_orderdate,
  CAST('3-MEDIUM' AS STRING)                       AS o_orderpriority,
  CAST('Clerk#external-flink-stream' AS STRING)    AS o_clerk,
  CAST(0 AS INT)                                   AS o_shippriority,
  CONCAT('streamed by external Flink @ seq=',
  CAST(seq AS STRING))                      AS o_comment
FROM flink_orders_flink_src;
-- ---------------------------------------------------------------------------
-- Demo 2 — small INSERT into the shared `orders` table (also written by
--          Spark + DuckDB). After this, DESCRIBE HISTORY orders shows
--          commits from FOUR engines — Databricks Runtime, external
--          Apache Spark, DuckDB, and Apache Flink — all coordinated by UC.
-- ---------------------------------------------------------------------------

CREATE TEMPORARY TABLE flink_orders_shared_src (
  seq BIGINT
) WITH (
  'connector' = 'datagen',
  'rows-per-second' = '10',
  'fields.seq.kind' = 'sequence',
  'fields.seq.start' = '1',
  'fields.seq.end' = '10'
);

INSERT INTO `uc_ext_access_demo`.`tpch_managed`.`orders`
SELECT
  CAST(9300000000 + seq AS BIGINT)                 AS o_orderkey,
  CAST((seq % 1500) + 1 AS BIGINT)                 AS o_custkey,
  CAST('O' AS STRING)                              AS o_orderstatus,
  CAST(MOD(seq * 11, 1000) AS DECIMAL(18,2))       AS o_totalprice,
  CURRENT_DATE                                     AS o_orderdate,
  CAST('3-MEDIUM' AS STRING)                       AS o_orderpriority,
  CAST('Clerk#external-flink-stream' AS STRING)    AS o_clerk,
  CAST(0 AS INT)                                   AS o_shippriority,
  CONCAT('inserted into shared orders by external Flink @ seq=',
  CAST(seq AS STRING))                      AS o_comment
FROM flink_orders_shared_src;&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN&gt;The connector ships on Maven Central as &lt;FONT face="courier new,courier"&gt;io.delta:delta-flink&lt;/FONT&gt; (4.2.0 at the time of writing — &lt;FONT face="courier new,courier"&gt;&lt;A href="https://central.sonatype.com/artifact/io.delta/delta-flink" target="_blank" rel="noopener"&gt;https://central.sonatype.com/artifact/io.delta/delta-flink&lt;/A&gt;&lt;/FONT&gt;). It is a thin JAR — its transitive deps (&lt;FONT face="courier new,courier"&gt;delta-kernel-*, hadoop-aws, AWS SDK bundle, parquet, ...&lt;/FONT&gt;) must also be on the Flink classpath. The companion helper setup_flink_usrlib.sh wraps mvn dependency:copy-dependencies and stages the full set under &lt;FONT face="courier new,courier"&gt;flink/docker/&amp;lt;ver&amp;gt;/usrlib/&lt;/FONT&gt; in one shot; building from source via sbt flink/assembly is documented as an alternative for master features. Setting '&lt;FONT face="courier new,courier"&gt;table.dml-sync&lt;/FONT&gt;' to '&lt;FONT face="courier new,courier"&gt;true&lt;/FONT&gt;' causes the Flink SQL client to block on the streaming &lt;FONT face="courier new,courier"&gt;INSERT&lt;/FONT&gt;, so the run terminates cleanly when the bounded datagen source completes.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;After the run, &lt;FONT face="courier new,courier"&gt;DESCRIBE HISTORY &lt;/FONT&gt;&lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;uc_ext_access_demo.tpch_managed.orders_flink&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; shows version 0 (the &lt;FONT face="courier new,courier"&gt;CREATE TABLE&lt;/FONT&gt;) followed by the Flink-attributed commit(s) — proof that Unity Catalog coordinated the external Flink write through catalog commits.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Auditing Cross-Engine Writes with &lt;/SPAN&gt;&lt;SPAN&gt;DESCRIBE HISTORY&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;The end-to-end demo seeds &lt;/SPAN&gt;&lt;SPAN&gt;orders&lt;/SPAN&gt;&lt;SPAN&gt; with a Databricks-Runtime CTAS, then has DuckDB, external Apache Spark™, and Apache Flink take turns writing to it. After that, a single &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;DESCRIBE HISTORY orders&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; from any of them shows the full history of operations log — the &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;engineInfo&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; column tells exactly which engine produced each commit.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dkushari_0-1778088020110.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26711i9C5092CCBEF7A4D1/image-size/large?v=v2&amp;amp;px=999" role="button" title="dkushari_0-1778088020110.png" alt="dkushari_0-1778088020110.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Multiple commits, four engines, one log. Unity Catalog was the coordinator for every entry — that's the cross-engine guarantee. One small note on the table above:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;The &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;Databricks-Runtime/...&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; row at version 0 came from a serverless DBSQL warehouse running the setup SQL. Anything written inside Databricks identifies itself with that Databricks runtime string in &lt;/SPAN&gt;&lt;SPAN&gt;engineInfo&lt;/SPAN&gt;&lt;SPAN&gt;; anything written from external engine is identified with the engine + connector versions (here, &lt;FONT face="courier new,courier"&gt;Apache-Spark/4.1.1 Delta-Lake/4.2.0, DuckDB, and Kernel-&amp;lt;ver&amp;gt;/DeltaSink for Flink&lt;/FONT&gt;).&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN&gt;The queries below tag every row in the &lt;/SPAN&gt;&lt;SPAN&gt;orders&lt;/SPAN&gt;&lt;SPAN&gt; table with the engine that wrote it, using the &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;o_clerk&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; column to identify each writer engine. The first query returns a per-engine count, and the second one returns a small sample of rows to show the actual records inserted by each engine.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;U&gt;Query 1:&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dkushari_1-1778088020110.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26712i7774C77CB81171A3/image-size/large?v=v2&amp;amp;px=999" role="button" title="dkushari_1-1778088020110.png" alt="dkushari_1-1778088020110.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;U&gt;Query 2:&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dkushari_4-1778089724668.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26722i12F90868A1A0C73D/image-size/large?v=v2&amp;amp;px=999" role="button" title="dkushari_4-1778089724668.png" alt="dkushari_4-1778089724668.png" /&gt;&lt;/span&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dkushari_2-1778088020110.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26713iD957BB19FB6F1202/image-size/large?v=v2&amp;amp;px=999" role="button" title="dkushari_2-1778088020110.png" alt="dkushari_2-1778088020110.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Ecosystem status and direction&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;The ecosystem continues to evolve:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;STRONG&gt;Delta Kernel remains the common building block.&lt;/STRONG&gt;&lt;SPAN&gt; New connectors only need to bridge the kernel into their engine’s I/O layer.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;STRONG&gt;Apache Flink and StreamNative Kafka Service already include catalog-commit integrations.&lt;/STRONG&gt;&lt;SPAN&gt; These systems follow the same interoperability pattern, with Delta Kernel handling the core abstraction and Unity Catalog acting as the commit coordinator.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;STRONG&gt;Attribute-based access control (ABAC) for external reads is the next governance frontier.&lt;/STRONG&gt;&lt;SPAN&gt; The goal is to extend Unity Catalog’s row- and column-level policies to queries executed by external engines against managed tables.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;&lt;SPAN&gt;Conclusion&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;With this Beta, the open lakehouse story is finally symmetric. Store your data once as a UC-managed Delta table, govern it centrally, and let every engine — Apache Spark™ in batch, Spark Structured Streaming, DuckDB, or whatever Delta Kernel-backed engine comes next — perform DML operations against the same tables. Catalog commits make it safe; M2M OAuth and &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;EXTERNAL_USE_SCHEMA&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; make it governed; Delta Kernel makes it easy to extend.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Clone the &lt;/SPAN&gt;&lt;A href="https://github.com/databricks-solutions/databricks-blogposts/tree/main/2026-05-external-access-to-unity-catalog-managed-delta-tables" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;GitHub repository&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;, and try performing DML operations from Spark or DuckDB today. Note the output of &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;DESCRIBE HISTORY&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; on a table that shows commits from Databricks Runtime, DuckDB, external Spark, and Apache Flink in the same log, demonstrating a single, interleaved transaction history where each commit is attributed to the&lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt; engineInfo&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; column, proving cross-engine write coordination under Unity Catalog.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Appendix&lt;/SPAN&gt;&lt;/H2&gt;
&lt;H3&gt;&lt;SPAN&gt;Code and execution flow&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;A full, runnable demo is available in &lt;/SPAN&gt;&lt;A href="https://github.com/databricks-solutions/databricks-blogposts/tree/main/2026-05-external-access-to-unity-catalog-managed-delta-tables" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;this GitHub repository&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;TABLE&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;File&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Purpose&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;00_setup_databricks.sql&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;FONT face="courier new,courier"&gt;DROP&lt;/FONT&gt; + &lt;FONT face="courier new,courier"&gt;CREATE&lt;/FONT&gt; catalog + schema, clone 8 TPCH tables as managed Delta, grant &lt;FONT face="courier new,courier"&gt;EXTERNAL_USE_SCHEMA&lt;/FONT&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;run_setup.py&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Driver: substitutes the SP application_id, splits + submits the SQL via the Statement Execution API.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;01_duckdb_read.py&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;DuckDB — list / &lt;FONT face="courier new,courier"&gt;SELECT&lt;/FONT&gt; / cross-table &lt;FONT face="courier new,courier"&gt;JOIN&lt;/FONT&gt; against UC managed Delta tables.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;02_duckdb_insert.py&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;DuckDB — &lt;FONT face="courier new,courier"&gt;INSERT INTO ... VALUES&lt;/FONT&gt; and &lt;FONT face="courier new,courier"&gt;INSERT INTO ... SELECT&lt;/FONT&gt; into a managed Delta table.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;03_spark_external_read.py&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;External Apache Spark™ — batch read + &lt;FONT face="courier new,courier"&gt;DESCRIBE HISTORY&lt;/FONT&gt; + time travel via &lt;FONT face="courier new,courier"&gt;VERSION AS OF&lt;/FONT&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;04_spark_external_write.py&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;External Apache Spark™ — append + &lt;FONT face="courier new,courier"&gt;CREATE TABLE AS SELECT&lt;/FONT&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;05_spark_streaming.py&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;External Apache Spark™ Structured Streaming — &lt;FONT face="courier new,courier"&gt;readStream&lt;/FONT&gt; (rate source) → &lt;FONT face="courier new,courier"&gt;writeStream.toTable()&lt;/FONT&gt; into a managed Delta table; ends with a time-travel comparison.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;06_flink_streaming.py&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;External Apache Flink — drop+create orders_flink, &lt;FONT face="courier new,courier"&gt;DELETE&lt;/FONT&gt; prior Flink-marker rows from orders, render Flink SQL using the catalog-based form (&lt;FONT face="courier new,courier"&gt;CREATE CATALOG ... WITH 'type'='unitycatalog'&lt;/FONT&gt; + &lt;FONT face="courier new,courier"&gt;INSERT INTO &amp;lt;catalog&amp;gt;.&amp;lt;schema&amp;gt;.&amp;lt;table&amp;gt;&lt;/FONT&gt;) with the OAuth bearer token substituted, then auto-detect a running Flink JobManager Docker container and exec bin/sql-client.sh -f against it. The new Kernel-based Delta Flink Connector ships on Maven Central as &lt;FONT face="courier new,courier"&gt;io.delta:delta-flink:4.2.0&lt;/FONT&gt; — sink-only, experimental.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;07_verify_cross_engine.py&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;External Spark — cross-engine &lt;FONT face="courier new,courier"&gt;DESCRIBE HISTORY&lt;/FONT&gt; showing the mix of engineInfo values across the catalog.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;run_all.py&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;One-shot pipeline runner — 9 steps: setup → duckdb read → duckdb insert → spark read → spark write → streaming → flink → verify → cleanup. Idempotent end-to-end. CLI flags: -a (all), -s (spark), -f (flink), -d (duckdb), --no-setup, --no-cleanup; combinable. At least one engine flag is required (no implicit run-all).&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;99_cleanup.sql&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;FONT face="courier new,courier"&gt;DROP SCHEMA + CATALOG IF EXISTS … CASCADE&lt;/FONT&gt;. Driven by run_cleanup.py at the end of run_all.py, or runnable standalone via the Databricks SQL editor.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;run_cleanup.py&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Driver: &lt;FONT face="courier new,courier"&gt;executes 99_cleanup.sql&lt;/FONT&gt; via the Statement Execution API. Runs as the final step of &lt;FONT face="courier new,courier"&gt;run_all.py&lt;/FONT&gt;, so an end-to-end run leaves the workspace in its pre-demo state.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;setup_flink_usrlib.sh&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;One-shot Maven helper — runs mvn dependency:copy-dependencies against &lt;FONT face="courier new,courier"&gt;io.delta:delta-flink:4.2.0&lt;/FONT&gt; and stages the connector + transitive deps (delta-kernel-*, hadoop-aws, AWS SDK bundle, parquet, ...) into a target Flink &lt;FONT face="courier new,courier"&gt;usrlib/&lt;/FONT&gt; directory. Replaces the manual sbt flink/assembly path for blog readers.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;_common.py&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Shared OAuth, Spark builder, DuckDB attach helpers.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;requirements.txt&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Pinned Python package versions.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;.env.example&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Template for workspace host + service principal credentials.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;README.md&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;End-to-end run instructions.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;H3&gt;&lt;SPAN&gt;Prerequisites to run this demo&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;Here are the prerequisites to run this demo in your own workspace:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;A Databricks workspace with Unity Catalog enabled.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Workspace enrolled in the &lt;/SPAN&gt;&lt;SPAN&gt;External Access to Unity Catalog Managed Delta Table&lt;/SPAN&gt;&lt;SPAN&gt; preview (Settings → Previews).&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;I&gt;&lt;SPAN&gt;External Data Access&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; enabled on the metastore (Governance → Metastore details).&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;A service principal with an OAuth client_id + client_secret (Workspace admin → Identity and access → Service principals → OAuth secrets).&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;&lt;FONT face="courier new,courier"&gt;EXTERNAL_USE_SCHEMA, MODIFY&lt;/FONT&gt;, &lt;/SPAN&gt;&lt;SPAN&gt;and&lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt; SELECT&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; permissions are granted to the &lt;/SPAN&gt;&lt;SPAN&gt;principal accessing data externally&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;A serverless SQL warehouse (used by the setup script to run the catalog/schema/grants DDL).&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Local machine with Python 3.11+ and Java 17+.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Apache Flink demo prerequisites:&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Java 17+, Maven (brew install maven), and Docker Desktop installed locally.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Stage the Delta Flink Connector + transitive deps from Maven Central into your Flink usrlib/ using the companion helper &lt;FONT face="courier new,courier"&gt;scripts/setup_flink_usrlib.sh&lt;/FONT&gt; — it runs mvn dependency:copy-dependencies against &lt;FONT face="courier new,courier"&gt;io.delta:delta-flink:4.2.0&lt;/FONT&gt; (&lt;A href="https://central.sonatype.com/artifact/io.delta/delta-flink" target="_self"&gt;https://central.sonatype.com/artifact/io.delta/delta-flink&lt;/A&gt;) and copies the full set of JARs (delta-kernel-*, hadoop-aws, AWS SDK bundle, parquet, ...) into the target directory. Building from source via sbt flink/assembly is documented in the upstream README (&lt;/SPAN&gt;&lt;A href="https://github.com/delta-io/delta/tree/master/flink" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;https://github.com/delta-io/delta/tree/master/flink&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;) as an alternative for master features.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Clone delta-io/delta locally to get the docker-compose recipe under flink/docker/&amp;lt;flink-version&amp;gt;/, then run &lt;FONT face="courier new,courier"&gt;setup_flink_usrlib.sh&lt;/FONT&gt; against that usrlib/ directory.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Start the local Flink cluster with docker compose up -d from flink/docker/&amp;lt;flink-version&amp;gt;/. The &lt;FONT face="courier new,courier"&gt;06_flink_streaming.py&lt;/FONT&gt; script auto-detects the running JobManager container, copies the rendered SQL into it, and runs &lt;FONT face="courier new,courier"&gt;bin/sql-client.sh -f&lt;/FONT&gt;.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;&lt;SPAN&gt;Building and running the Flink demo locally&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;The Apache Flink walkthrough above is the only engine in this post that requires a one-time Flink cluster setup beyond the Python venv. The steps below assume you have already completed the workspace setup in Prerequisites for this demo. You will also need Java 17+ and Maven, and Docker installed locally.&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;SPAN&gt; Install prereqs (one-time). On macOS:&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;LI-CODE lang="python"&gt;brew install maven&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN&gt;# Java 17+ should already be installed; otherwise:&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;brew install openjdk@17&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN&gt;# Docker Desktop: &lt;A href="https://www.docker.com/products/docker-desktop/" target="_blank" rel="noopener"&gt;https://www.docker.com/products/docker-desktop/&lt;/A&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL start="2"&gt;
&lt;LI&gt;&lt;SPAN&gt; Clone delta-io/delta locally to get the docker-compose recipe.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;LI-CODE lang="python"&gt;git clone https://github.com/delta-io/delta ~/delta&lt;/LI-CODE&gt;
&lt;OL start="3"&gt;
&lt;LI&gt;&lt;SPAN&gt; Stage the Delta Flink Connector + transitive deps from Maven Central into the Flink docker-compose usrlib/. The companion helper resolves io.delta:delta-flink:4.2.0 and its transitive deps (delta-kernel-*, hadoop-aws, AWS SDK bundle, parquet, ...) and copies them in one shot.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;LI-CODE lang="python"&gt;bash &amp;lt;path-to-blog&amp;gt;/scripts/setup_flink_usrlib.sh ~/delta/flink/docker/2.0/usrlib&lt;/LI-CODE&gt;
&lt;OL start="4"&gt;
&lt;LI&gt;&lt;SPAN&gt; Start the local Flink cluster.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;LI-CODE lang="python"&gt;cd ~/delta/flink/docker/2.0
docker compose up -d
docker compose ps&lt;/LI-CODE&gt;
&lt;OL start="5"&gt;
&lt;LI&gt;&lt;SPAN&gt; Run the Flink demo. The script renders the Flink SQL with your live OAuth bearer token, drops+creates orders_flink on Databricks, deletes prior Flink-marker rows from orders, then docker-execs the Flink SQL client against the rendered file.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;LI-CODE lang="markup"&gt;python 06_flink_streaming.py&lt;/LI-CODE&gt;
&lt;OL start="6"&gt;
&lt;LI&gt;&lt;SPAN&gt; Verify and tear down. The cross-engine verify shows &lt;FONT face="courier new,courier"&gt;DESCRIBE HISTORY&lt;/FONT&gt; orders with all four engineInfo values, and &lt;FONT face="courier new,courier"&gt;DESCRIBE HISTORY&lt;/FONT&gt; orders_flink with the Flink-attributed bulk commit.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;LI-CODE lang="python"&gt;python 07_verify_cross_engine.py
docker compose down                 # stop the local Flink cluster&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN&gt;For master builds (e.g., testing pre-release Flink connector features), the upstream &lt;FONT face="courier new,courier"&gt;sbt flink/assembly&lt;/FONT&gt; path still works — see &lt;A href="https://github.com/delta-io/delta/tree/master/flink" target="_self"&gt;https://github.com/delta-io/delta/tree/master/flink&lt;/A&gt; — but for the blog walkthrough, the Maven Central recipe above is the recommended route.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3&gt;&lt;SPAN&gt;References&lt;/SPAN&gt;&lt;/H3&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;A href="https://github.com/delta-io/delta/releases/tag/v4.2.0" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Delta Lake 4.2.0 release notes&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;A href="https://github.com/unitycatalog/unitycatalog/releases/tag/v0.4.1" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Unity Catalog 0.4.1 release notes&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;A href="https://docs.databricks.com/aws/en/external-access/unity-rest" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Databricks External Access documentation&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;A href="https://docs.databricks.com/aws/en/delta/catalog-commits" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Catalog commits docs&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;A href="https://duckdb.org/docs/current/core_extensions/unity_catalog" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;DuckDB `unity_catalog` extension docs&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;A href="https://github.com/delta-io/delta/tree/master/flink" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Delta Flink Connector&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;A href="https://streamnative.io/blog/announcing-streamnative-kafka-service-launch-partners#data-platforms-and-lakehouse-ecosystem-partners" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;StreamNative Kafka Service Launch Partners&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;A href="https://github.com/delta-io/delta/tree/master/kernel" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Delta Kernel repository&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;A href="https://duckdb.org/2026/05/07/delta-uc-updates" target="_self"&gt;&lt;SPAN&gt;DuckDB blog announcing UC integration&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;</description>
    <pubDate>Fri, 08 May 2026 11:55:14 GMT</pubDate>
    <dc:creator>dkushari</dc:creator>
    <dc:date>2026-05-08T11:55:14Z</dc:date>
    <item>
      <title>Performing DML Operations on Unity Catalog Managed Tables from External Engines</title>
      <link>https://community.databricks.com/t5/technical-blog/performing-dml-operations-on-unity-catalog-managed-tables-from/ba-p/156308</link>
      <description>&lt;P&gt;&lt;SPAN&gt;External engines can now create, read, write, and stream into UC-managed Delta tables.&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 08 May 2026 11:55:14 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/performing-dml-operations-on-unity-catalog-managed-tables-from/ba-p/156308</guid>
      <dc:creator>dkushari</dc:creator>
      <dc:date>2026-05-08T11:55:14Z</dc:date>
    </item>
  </channel>
</rss>

