SaveMyCert
Log in
5 of 5 free questions left today·for 30 a day
Ingest and transform data

Batch Ingestion in Fabric: Data Stores, Shortcuts, Mirroring, and Pipelines

20 min readDP-700 · Ingest and transform dataUpdated

Batch ingestion in Microsoft Fabric starts with two decisions — which store the data lands in (Lakehouse, Warehouse, Eventhouse, or a semantic model on top) and whether the data needs to move at all, because OneLake shortcuts and mirroring can make external data queryable without copying it. Only then do you pick the machinery: pipelines to copy and orchestrate, and Dataflows Gen2, Spark notebooks, T-SQL, or KQL to transform. DP-700 weights this topic heavily and probes it as a chain of choices: store, access pattern, transform tool, then the data-quality work — deduplicating, filling or filtering missing values, and handling late-arriving rows. This lesson walks the whole chain, including how shortcuts are secured and cached, what each mirroring source needs, and the PySpark, T-SQL and KQL idioms for deduplicating, aggregating and reprocessing correctly.

What you’ll learn
  • Choose between a Lakehouse, Warehouse, Eventhouse, and semantic model for a given workload and skill set, and query across them by three-part name
  • Select the right transformation tool among Dataflows Gen2, notebooks, T-SQL, and KQL
  • Create internal and external OneLake shortcuts, place them in Tables or Files correctly, and predict their delete, permission and caching behaviour
  • Reach firewalled storage with trusted workspace access and private sources with the right data gateway
  • Decide when mirroring (built-in, open, or metadata) beats shortcuts or pipeline copies, and state each source’s prerequisites
  • Ingest batch data with pipeline Copy activities, controlled ForEach concurrency, and orchestrated downstream transforms
  • Denormalize without join fan-out and pre-aggregate with additive measures
  • Handle duplicate, missing, and late-arriving data in PySpark, T-SQL, and KQL

Choosing the right Fabric data store

Choose the store by workload and by the language your team will query it with: a Lakehouse for file-based and Spark-centric engineering over Delta tables, a Warehouse for full T-SQL analytics with multi-table transactions, an Eventhouse (housing KQL databases) for high-volume telemetry, logs, and time-series queried in near real time, and a semantic model as the BI consumption layer over any of them — not a landing zone for raw data.

StoreBest forPrimary languageWrite accessFormat
LakehouseFiles plus tables, Spark transformations, medallion layers, semi-structured dataPySpark / Spark SQLSpark; SQL analytics endpoint is read-only T-SQLDelta/Parquet in OneLake
WarehouseSQL-first dimensional serving, multi-table transactions, T-SQL DMLT-SQLFull T-SQL read/writeDelta in OneLake
Eventhouse (KQL database)Streaming telemetry, logs, IoT time-series, free-text and trace explorationKQLStreaming and batch ingestionColumnar store, exposable as Delta in OneLake
Semantic modelBI serving to Power BI, measures and relationships (Direct Lake over OneLake)DAXNot a data store for ingestionModel over Delta tables

Two distinctions decide most exam questions. First, the Lakehouse's SQL analytics endpoint is read-only — if the scenario requires T-SQL INSERT/UPDATE/MERGE or stored procedures writing data, the answer is a Warehouse. Second, everything above stores or exposes data as Delta in OneLake, so choosing one store does not wall data off from the other engines — shortcuts and the shared format keep a single copy queryable everywhere.

Cross-database queries. A Warehouse can query Lakehouse tables and mirrored-database tables in the same workspace by three-part name (LakehouseName.dbo.TableName) through their SQL analytics endpoints. Those reads are read-only: a Warehouse cannot UPDATE or DELETE a Lakehouse or mirrored table, but it can read one and write the result into its own tables — INSERT INTO dbo.FactSales SELECT ... FROM Bronze.dbo.Sales is the standard way to load a Warehouse from a Lakehouse with T-SQL alone. The endpoints themselves accept views (and other read-only objects) but no CREATE TABLE AS SELECT and no DML; the SQL analytics endpoint of a mirrored database is read-only in exactly the same way.

Choosing a transformation tool: Dataflows Gen2, notebooks, T-SQL, or KQL

Match the tool to the transformation's complexity, the data's scale and shape, and the team's skills. Dataflows Gen2 is Power Query in Fabric: a low-code, visual tool with hundreds of connectors, right for business-analyst-friendly cleansing and mapping of light-to-moderate volumes, with output written to a Lakehouse, Warehouse, or other destinations. Notebooks (PySpark/Spark SQL) are the code-first choice for large-scale, complex transformations — custom logic, reusable functions, unit-testable code, machine-friendly formats like JSON and Parquet — and generally the most capacity-efficient option at scale. T-SQL (stored procedures and views in a Warehouse, orchestrated by pipelines) fits SQL-skilled teams doing set-based dimensional transforms on structured, already-tabular data. KQL transforms live where telemetry lives: shaping, parsing, and aggregating event data inside an Eventhouse, including materializing transformations with update policies as data streams in.

The exam phrases this as persona-plus-requirement scenarios:

  • "Citizen developers", "least code", "analysts who know Power Query" → Dataflow Gen2.
  • "Hundreds of gigabytes", "complex business logic", "data scientists", "reusable library" → notebook.
  • "Team knows T-SQL", "stored procedures", "transform inside the Warehouse" → T-SQL.
  • "Transform events as they're ingested into the Eventhouse", "parse log text" → KQL.

Two practical notes. Custom Python code shared across notebooks — a team's own wheel (.whl) or modules — reaches notebooks through a Fabric environment: upload the library to the environment, publish it, then attach the environment to the notebooks (or set it as the workspace default) so every session starts with it; an inline %pip install only lasts for one session. And timing decides between Eventstream and KQL: Eventstream transformations act on events in flight, before they land, while data already stored in an Eventhouse is reshaped with KQL — a query written into a new table with .set-or-append, or an update policy that transforms each new ingestion. The streaming lesson covers Eventstream in depth.

Remember the neighbouring skill from Domain 1: a pipeline is not a transformation engine — it copies and orchestrates. A pipeline calling a notebook or stored procedure is the standard pairing: Copy activity for movement, code for logic.

OneLake shortcuts: one copy of data, many engines

A shortcut is a pointer in OneLake that makes data stored elsewhere appear as if it lived in your Lakehouse or KQL database (the item types that can hold shortcuts; a Warehouse can be a shortcut target but cannot contain one) — no data is moved or duplicated, and reads always see the current state of the target, not a snapshot taken when the shortcut was created. Shortcuts are OneLake's answer to data sprawl: instead of every team copying the same dataset into its own workspace, one physical copy is referenced from wherever it's needed.

Shortcuts come in two families:

  • Internal (OneLake) shortcuts point at data in other Fabric items — another Lakehouse's tables or files, a Warehouse, a mirrored database, or a KQL database — across workspaces. A gold Lakehouse can shortcut to a silver Lakehouse in another workspace and query its Delta tables in place.
  • External shortcuts point at storage outside Fabric: Azure Data Lake Storage Gen2, Azure Blob Storage, Amazon S3 and S3-compatible stores, Google Cloud Storage, Dataverse, and on-premises or network stores reached through a data gateway. The data stays where it is (and where its lifecycle is managed); Fabric engines read it through the shortcut using the connection's credentials.

Tables or Files — placement decides discovery. A shortcut under a Lakehouse's Tables section must point at a Delta table; Fabric then discovers it as a table, so it is queryable from Spark SQL, the SQL analytics endpoint and Direct Lake models. A shortcut under Files can point at any files and formats, but gets no table discovery — even if the target folder holds a perfectly good Delta table, it does not appear as a table in Spark SQL or the SQL analytics endpoint; you read it by path (for example spark.read.format("delta").load("Files/...")). If a team needs a shared table to show up as a table, the shortcut belongs in Tables.

Eventhouse data in a Lakehouse. A KQL database's tables become shortcut-able Delta data once you turn on OneLake availability (at database or table level): the Eventhouse then also writes a Delta representation to OneLake, and a Lakehouse Tables shortcut to it lets Spark and the SQL analytics endpoint query the same data without a copy pipeline.

Managing shortcuts: what deletes what.

ActionEffect on the target data
Delete the shortcut itselfNone — only the pointer is removed
Delete files or folders inside the shortcutThey are deleted at the target, if the identity used has write permission there
Rename, move or delete the targetThe shortcut breaks — it does not follow the target, so it must be recreated or repointed

Choose a shortcut when the source is already analytics-ready (Delta/Parquet files, another team's gold tables) and freshness should be "whatever the source has right now." It is instant to create, costs no storage, and removes an entire copy pipeline from your estate.

Shortcut security, firewalled storage, and caching

A shortcut never bypasses authorization: every read is checked at the target. How it is checked depends on the family. An internal shortcut passes the calling user's identity to the target item, so the user must hold permission on the target, not just on the Lakehouse that contains the shortcut. The exception is a delegated path: T-SQL queries in delegated identity mode and Direct Lake over SQL pass the item owner's identity instead, while user identity mode and Direct Lake over OneLake pass the caller's. An external shortcut reads with the credentials stored in its connection (an organizational account, service principal, workspace identity, key or SAS token), so anyone who can use the shortcut reads with that connection's rights.

For internal shortcuts, the level of target permission matters:

  • Sharing a Lakehouse with no extra boxes ticked grants only Read — the user can see the item and its metadata, but that alone does not let Spark or OneLake read its files and tables through a shortcut.
  • Reading the data through Spark or the OneLake APIs needs Read all Apache Spark data (ReadAll), membership of a OneLake security role that covers the folders or tables, or a workspace role on the target workspace.
  • Read all SQL endpoint data covers T-SQL queries through the SQL analytics endpoint, a different path from Spark.

Firewalled storage accounts. When an ADLS Gen2 or Blob storage account blocks public network access, a shortcut reaches it through trusted workspace access. It needs four things: a workspace identity for the Fabric workspace; a resource instance rule on the storage account that trusts that workspace (added with an ARM template or PowerShell, not the portal's network blade); a workspace on an F SKU capacity; and a Storage Blob Data role (Reader, Contributor or Owner) on the storage account for the principal the connection authenticates as. Trusted workspace access serves a documented set of Fabric paths — OneLake shortcuts, pipelines, import-mode semantic models, the T-SQL COPY statement and AzCopy; Spark code that reads the storage account directly, without a shortcut, uses a managed private endpoint instead.

Shortcut caching. Reading the same remote files repeatedly costs cross-cloud egress and latency. Shortcut caching is a workspace-level OneLake setting that keeps copies of files read through Amazon S3, S3-compatible, Google Cloud Storage and on-premises gateway shortcuts. You set a retention period of 1 to 28 days; a cached file is served from OneLake while it is still current at the source, and files larger than 1 GB are not cached. It changes cost and speed only — reads still reflect the source.

Mirroring: near-real-time replicas of operational databases

Mirroring continuously replicates an operational database into OneLake as Delta tables, giving you a near-real-time, analytics-ready copy with no pipelines to build or schedule. You configure it once against a supported source and Fabric takes an initial snapshot, then applies the source's ongoing inserts, updates and deletes to the replica automatically. Built-in sources include Azure SQL Database, Azure SQL Managed Instance, SQL Server, Azure Database for PostgreSQL, Azure Cosmos DB and Snowflake, with newer sources such as Oracle, Google BigQuery and SAP added over time (some in preview — check the current list).

How changes are captured depends on the source, so there is no single "change feed" rule:

  • SQL Server 2016–2022 mirrors through change data capture, and SQL Server 2025 through its change feed. An on-premises instance, or one behind a firewall, is reached through an on-premises data gateway (or a virtual network data gateway when the server sits in an Azure VNet).
  • Azure Cosmos DB mirroring uses neither the change feed nor the analytical store. Its prerequisite is continuous backup on the account, and replication does not consume request units — the transactional workload is untouched. That is the key contrast with the alternatives: a Copy job, a pipeline Copy activity or the Spark connector all read the container through its API and spend its RUs on every run.

Two variants extend the idea. Open mirroring covers sources with no built-in connector: your application or a partner tool writes change files (Parquet with a row-marker column saying insert, update, delete or upsert) into the mirrored database's landing zone, and Fabric applies them to Delta tables. Metadata mirroring (for example, an Azure Databricks catalog) mirrors the catalog's structure and reads the tables through shortcuts rather than copying them.

What you get is a mirrored database item whose tables are ordinary Delta tables in OneLake: query them through its SQL analytics endpoint with T-SQL, shortcut them into a Lakehouse for Spark, read them from a Warehouse by three-part name, and build Direct Lake semantic models on them. The replica is one-way and read-only — you cannot write back through it — and it is not a backup of the source: deletes at the source are replicated too.

Mirroring solves a specific problem: operational databases are not query-friendly analytical sources. Before mirroring, the standard answer was an incremental pipeline with watermarks and merges; mirroring replaces that whole apparatus for supported sources and offloads analytical queries from the operational system. Scenarios signal it with phrases like "replicate an Azure SQL Database into Fabric with minimal effort," "near real time without building pipelines," or "analysts need current Cosmos DB data without impacting the app." If the source is a file store rather than a database, mirroring is the wrong tool — that's shortcut territory; if the data needs heavy reshaping on the way in, mirroring alone isn't enough — you still transform downstream, typically with Spark over shortcuts to the mirrored tables.

Shortcut, mirror, or copy? Picking an access pattern

The three access patterns answer one question differently: where does the physical data live, and who keeps it current? A shortcut leaves data at the source and reads it live; mirroring maintains a continuously updated replica in OneLake; a pipeline copy takes a point-in-time snapshot you own and schedule.

AspectOneLake shortcutMirroringPipeline copy
Data movementNone — virtual referenceContinuous replication into OneLakePhysical copy on each run
FreshnessAlways current (reads the source)Near real timeAs of last run
Source typesOneLake items, ADLS Gen2, Blob, S3, GCS, Dataverse, gateway storesSupported databases (Azure SQL, SQL Server, PostgreSQL, Cosmos DB, Snowflake, ...) plus open mirroring for any source that can write change filesBroadest — hundreds of connectors
Transformation on the way inNoneNone (replica matches source)Yes — copy plus downstream transforms
Ongoing effortNoneNone after setupYou own schedules, watermarks, failures
Best whenData already analytics-ready in an accessible storeOperational DB needed fresh in OneLake without pipelinesSource unsupported by the other two, or you need shaping, isolation, or history at ingestion

Scenario. A retailer's sales run in Azure SQL Database, clickstream files land in ADLS Gen2 as Parquet, and a legacy on-premises system exports CSVs nightly. The DP-700 answer: mirror the Azure SQL Database (fresh operational data, zero pipelines), shortcut the ADLS Gen2 clickstream (already analytics-ready files, no copy needed), and run a pipeline copy for the legacy CSVs (a file export rather than a database, so it needs a copy and shaping into Delta on the way in, through an on-premises data gateway). One solution, three patterns, each earning its place.

Ingesting data with pipelines

Pipelines are Fabric's batch ingestion and orchestration workhorse: the Copy activity moves data from hundreds of sources into a Lakehouse, Warehouse, or Eventhouse at scale, and control-flow activities (ForEach, Lookup, If, Notebook, Stored procedure, Dataflow) sequence the work around it. A typical ingestion pipeline looks up configuration, iterates a list of source tables with ForEach, runs a parameterized Copy per table into bronze, then invokes a notebook or stored procedure to transform onward — with schedules or event triggers starting the run.

Copy activity choices the exam cares about:

  • Destination and format. Landing in Lakehouse Files keeps raw fidelity (any format); landing in Tables writes Delta and is immediately queryable. Bronze-layer designs usually land files or append-only Delta and defer conforming to Spark.
  • Full vs incremental copies. A source query filtered on a watermark column (driven by Lookup activities against a control table) turns Copy into an incremental extractor; the simpler Copy job item packages common full and incremental copy patterns without building the pipeline scaffolding yourself.
  • Parameterization. One pipeline with parameters for source, schema, and table beats dozens of cloned pipelines — pass values from ForEach over a metadata list.
  • ForEach concurrency. With Sequential ticked, ForEach runs one iteration at a time. Clear it to run iterations in parallel, and set Batch count to cap how many run at once — the setting to use when a source allows only a few concurrent connections or queries.
  • Reaching private sources. An on-premises database or file share needs an on-premises data gateway installed on a machine that can reach it. A virtual network data gateway runs inside an Azure VNet for sources in (or privately linked to) that VNet; it reaches on-premises systems only if the VNet already has VPN or ExpressRoute connectivity to them — without that hybrid link, the on-premises gateway is the answer.

Keep the division of labor straight: pipelines move and orchestrate but do not transform row internals — that's the job of the notebook, stored procedure, or Dataflow they call. When a scenario says "copy 200 tables nightly and then run transformations," the shape of the answer is a metadata-driven pipeline with ForEach plus Copy, followed by orchestrated transform activities.

Transforming with PySpark, T-SQL, and KQL: denormalize, group, aggregate

The same core transformations — joining, reshaping, aggregating — express naturally in all three languages, and DP-700 expects you to read each. Denormalization means joining normalized tables into wider ones so analytical queries stop paying repeated join costs; it's the standard silver-to-gold step that also feeds dimensional models.

Joining orders to customers, then aggregating revenue by segment:

PySpark:
  wide = orders.join(customers, "customer_id", "left")
  result = (wide.groupBy("segment")
    .agg(sum("amount").alias("revenue"),
         countDistinct("order_id").alias("orders")))

T-SQL:
  SELECT c.segment, SUM(o.amount) AS revenue,
         COUNT(DISTINCT o.order_id) AS orders
  FROM dbo.orders AS o
  LEFT JOIN dbo.customers AS c
    ON o.customer_id = c.customer_id
  GROUP BY c.segment;

KQL:
  orders
  | lookup kind=leftouter customers on customer_id
  | summarize revenue = sum(amount),
              orders = dcount(order_id) by segment

Join fan-out. Denormalizing is only safe when the dimension is unique on the join key; otherwise each fact row matches several dimension rows and totals inflate. The classic case is an SCD Type 2 dimension, which keeps several versions of each customer. Choose the join by the question the gold table answers: current attributes → join only the current version (IsCurrent = 1); attributes as they were at the time → a point-in-time join where the fact date falls between ValidFrom and ValidTo. A filter on ValidFrom alone still matches every earlier version and fans out.

Filtering around aggregation. WHERE filters rows before grouping; HAVING filters groups after aggregation ("segments with revenue over 1 million"). In PySpark, that is a filter() before or after the agg(); in KQL, a where before or after summarize.

Pre-aggregating to a reporting grain. Sums and counts are additive — daily totals roll up to monthly totals by adding them. Averages, ratios and distinct counts are not: averaging daily averages gives the wrong monthly average whenever days have different row counts. A gold table pre-aggregated by day should therefore store the sum and the count, and let the report compute average = sum ÷ count at any level.

Language-mapping cues worth memorizing: PySpark's groupBy().agg(), T-SQL's GROUP BY, and KQL's summarize ... by are the same operation; KQL's lookup/join replaces SQL joins; KQL pipes read top-to-bottom as a data flow. Choose the language by where the data lives and who maintains the code (the tool-choice rules earlier), not by capability — all three group, join, window, and aggregate. One practical Fabric note: if the transform must write to a Lakehouse table, it runs in Spark, because the Lakehouse's T-SQL surface is read-only; T-SQL DML transforms belong in a Warehouse.

Handling duplicate, missing, and late-arriving data

Data-quality handling is a silver-layer responsibility: bronze keeps what arrived, silver makes it trustworthy. The exam tests the idiom in each language plus the design pattern behind each problem.

Duplicates. Exact duplicates fall to PySpark's dropDuplicates(["order_id"]), T-SQL DISTINCT or KQL's distinct. "Keep the latest version per key" needs ranking, because dropDuplicates keeps an arbitrary row per key — sorting with orderBy first does not guarantee which one survives. Rank instead:

  • T-SQL: ROW_NUMBER() OVER (PARTITION BY order_id ORDER BY modified_at DESC), keep rn = 1.
  • PySpark: the same with row_number() over Window.partitionBy("order_id").orderBy(col("modified_at").desc()), then filter rn == 1.
  • KQL: summarize arg_max(modified_at, *) by order_id.
FunctionTies on the ORDER BY valueRows kept by "= 1"
row_number()Numbered 1, 2, 3 in an arbitrary orderExactly one per key — deterministic only if the ordering includes a unique tie-breaker (for example modified_at DESC, ingest_id DESC)
rank() / dense_rank()Tied rows share the same rankEvery tied row — duplicates survive

Idempotent loads with MERGE. The durable fix is to MERGE on the business key so reruns and overlapping extracts can't create duplicates. Reduce the batch to one row per key first: a Delta or T-SQL MERGE with a WHEN MATCHED update or delete fails when several source rows match the same target row. For immutable events that retries may resend, an insert-only MERGE — only WHEN NOT MATCHED THEN INSERT on the event ID — adds new events and silently ignores ones already loaded, without rewriting existing rows. It does not deduplicate within the batch, though: two copies of a new event in the same batch are both inserted, so the batch must still be reduced to one row per key first.

Missing values. First decide the semantics — is null "unknown," "zero," "not applicable," or "bad record"? It matters because SUM, AVG and their PySpark and KQL equivalents ignore nulls: if a null quantity really means zero, leaving it null makes the average higher than it should be. Then act:

  • Fill defaults where the meaning is known: fillna() / na.fill(), COALESCE, KQL coalesce().
  • Drop rows only for hard requirements, and say which columns: PySpark's na.drop() (or dropna()) defaults to dropping a row when any column is null, so pass subset=["order_id", "customer_id"] to drop only rows missing a mandatory value.
  • Quarantine failures to an errors table for review rather than silently discarding them.
  • For a legitimately missing foreign key, map it to an Unknown member row in the dimension (for example key -1). An inner join would drop those facts and shrink totals; a left join keeps them but leaves NULL keys that reports group as blank.

Late-arriving data. Rows can arrive after their period was already processed — a sale dated yesterday landing after last night's run. Batch designs handle this with a lookback window: each run reprocesses the last N days, so stragglers reconcile. Scope the write to match: Delta's replaceWhere overwrites only the affected date range, whereas a full overwrite rewrites the whole table and a plain append duplicates the reprocessed days. When data can be much later than any fixed window, derive the affected dates from the rows ingested since the last run (their event dates) and reprocess just those partitions. When the late arrival is a fact referencing an unseen dimension member, use the inferred-member pattern from the loading-patterns lesson. The common thread: because reconciliation applies the same rows again, every one of these designs only works if the load is idempotent.

Tip. This is DP-700's largest single topic and it's tested as chained decisions: 'choose the store' questions hinging on the read-only SQL analytics endpoint (Lakehouse and mirrored database) vs Warehouse T-SQL DML and cross-database INSERT ... SELECT; 'choose the tool' questions keyed to personas and timing (Power Query analysts → Dataflow Gen2; large-scale complex logic → notebook with an environment for custom libraries; data already in an Eventhouse → KQL, events in flight → Eventstream); and 'shortcut vs mirror vs copy' questions keyed to the source type and its constraints. Expect shortcut behaviour details — Tables vs Files discovery, delete semantics, caller identity at the target, trusted workspace access for firewalled storage, caching — and mirroring prerequisites per source (continuous backup and no RU use for Cosmos DB, a gateway for on-premises SQL Server, open mirroring for unsupported sources). Pipeline items test ForEach concurrency and gateway choice. Code-reading items map GROUP BY, groupBy().agg() and summarize across languages, and data-quality items turn on deterministic dedupe (row_number with a tie-breaker, arg_max), MERGE failing on duplicate source keys, null-aware aggregates, na.drop subsets, Unknown members, SCD2 join fan-out, and replaceWhere-scoped lookback reprocessing.

Key takeaways
  • Store choice is workload plus language: Lakehouse for Spark and files, Warehouse for full T-SQL DML and multi-table transactions, Eventhouse for telemetry queried with KQL, semantic model as the BI layer — and the Lakehouse SQL analytics endpoint is read-only. A Warehouse can read Lakehouse and mirrored tables by three-part name and INSERT ... SELECT the result into its own tables, but cannot modify them.
  • Tool choice follows persona and scale: Dataflows Gen2 for low-code Power Query users, notebooks for large or complex code-first transforms, T-SQL for Warehouse-centric SQL teams, KQL for shaping event data in an Eventhouse.
  • Shortcuts are zero-copy pointers that read the target live: only Tables-section shortcuts to Delta data are discovered as tables; deleting the shortcut leaves the data, but deleting files inside it deletes them at the target; internal shortcuts authorize the calling user at the target.
  • Firewalled ADLS Gen2/Blob needs trusted workspace access (workspace identity, resource instance rule, F SKU, Storage Blob Data role); shortcut caching (1-28 days, S3/S3-compatible/GCS/gateway, files up to 1 GB) cuts egress.
  • Mirroring keeps a one-way, read-only Delta replica of supported databases with no pipelines; the capture mechanism differs by source (Cosmos DB needs continuous backup and uses no RUs), open mirroring takes change files for any other source, and an on-premises SQL Server needs a data gateway.
  • Pick the access pattern by ownership of freshness: shortcut = read the source live, mirror = managed replica, pipeline copy = scheduled snapshot you control and can transform on the way in.
  • Pipelines copy and orchestrate but don't transform row internals — a metadata-driven ForEach + parameterized Copy (Sequential off, Batch count capped for fragile sources) feeding notebooks or stored procedures is the canonical batch design.
  • GROUP BY, groupBy().agg(), and summarize ... by are the same operation; WHERE filters rows before grouping and HAVING filters groups after; store sums and counts (not averages) in pre-aggregated tables; join SCD2 dimensions on the current or point-in-time version to avoid fan-out.
  • Dedupe with row_number (with a unique tie-breaker) or arg_max, never dropDuplicates after orderBy or rank with ties; reduce the batch before MERGE; remember aggregates ignore nulls; scope lookback rewrites with replaceWhere.

Frequently asked questions

When should I choose a Lakehouse over a Warehouse in Fabric?

Choose a Lakehouse when you need Spark-based transformation, storage of raw files alongside tables, or semi-structured data — it's the natural home of the medallion architecture. Choose a Warehouse when the team works in T-SQL and needs to write with it: INSERT, UPDATE, MERGE, stored procedures, and multi-table transactions. The deciding detail in many exam questions is that a Lakehouse's SQL analytics endpoint is read-only — T-SQL writes require a Warehouse.

What is the difference between a OneLake shortcut and mirroring?

A shortcut is a virtual pointer: the data stays in its source (another OneLake item, ADLS Gen2, S3, Dataverse), nothing is copied, and reads see the source's current state. Mirroring physically replicates a supported database (Azure SQL Database, SQL Server, Cosmos DB, Snowflake and others) into OneLake as read-only Delta tables and keeps the replica current automatically; open mirroring extends this to any source that can write change files. Shortcut when the data is already analytics-ready files or tables; mirror when the source is an operational database you want fresh in OneLake without building pipelines.

Do OneLake shortcuts copy data or affect its security?

Shortcuts never copy data — they reference it in place, so there is one physical copy no matter how many workspaces shortcut to it, and reads always see the target's current state. Security is evaluated at the target: an internal shortcut normally passes the calling user's identity, so the user needs permission on the target item (T-SQL in delegated identity mode and Direct Lake over SQL pass the item owner's identity instead), and an external shortcut reads with its connection's credentials. Deleting a shortcut removes only the pointer, but deleting files or folders inside a shortcut deletes them at the target when the identity has write permission, and renaming or moving the target breaks the shortcut.

Which transformation tool should a team with only Power Query skills use?

Dataflows Gen2 — it is Power Query running in Fabric, with a visual, low-code editor, a large connector library, and output destinations including Lakehouses and Warehouses. It suits business analysts doing cleansing, mapping, and light reshaping at light-to-moderate volume. When transformations become very large-scale or logic-heavy, the exam's expected pivot is to Spark notebooks, which handle scale and complex custom code more efficiently.

How do you keep only the latest version of each record when a batch contains duplicates?

Rank rows per business key by a recency column and keep the top one: T-SQL uses ROW_NUMBER() OVER (PARTITION BY key ORDER BY modified_at DESC) filtered to rn = 1, PySpark uses row_number() over the same window, and KQL uses summarize arg_max(modified_at, *) by key. Add a unique tie-breaker to the ordering so the result is deterministic; rank() would keep every tied row, and dropDuplicates after orderBy keeps an arbitrary row. Then MERGE the reduced batch on the business key, so re-running a batch can never introduce duplicates — MERGE fails if several source rows match one target row.

What does it mean to handle late-arriving data in a batch design?

Rows sometimes arrive after the load that should have included them — a transaction dated yesterday landing today. Batch designs absorb this with a lookback window: each run reprocesses the last several days and writes only that range, for example with Delta's replaceWhere or a MERGE, so stragglers reconcile without duplicating or rewriting the whole table. For very late data, derive the affected dates from the rows ingested since the last run. When a late fact references a dimension member you haven't loaded yet, insert an inferred placeholder member and complete it later. All of these depend on the load being idempotent.

How do I create a OneLake shortcut to a storage account behind a firewall?

Use trusted workspace access. Create a workspace identity for the Fabric workspace, add a resource instance rule to the ADLS Gen2 or Blob storage account that trusts that workspace (deployed with an ARM template or PowerShell), make sure the workspace runs on an F SKU capacity, and give the principal the shortcut's connection authenticates as a Storage Blob Data role on the account. The shortcut then works without opening the firewall. Spark code that reads the account directly, without a shortcut, uses a managed private endpoint instead.

Does mirroring Azure Cosmos DB into Fabric use request units?

No. Cosmos DB mirroring requires continuous backup on the account and replicates without using the change feed or the analytical store, and it does not consume the container's request units, so the application's workload is unaffected. Copying the same data with a Copy job, a pipeline Copy activity or the Spark connector reads the container through its API and spends request units on every run, which is why mirroring is preferred when analysts need current operational data.

Source

This lesson covers the "Ingest and transform data" domain of the official DP-700 exam guide. Vendors revise their guides — check the source for the current version.

Test yourself on this topic
Practice now

Sign up free to mark lessons complete, bookmark topics and track your exam readiness.

Spotted a mistake in this lesson?