> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cognite.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Read Fabric OneLake data in transformations

> Query Fabric OneLake Delta tables with ext_onelake in Transformations SQL and write results to CDF destinations.

<Warning>
  The features described in this article are in [public preview](/cdf/product_feature_status#public-preview) and may change.
</Warning>

After you [register a Fabric OneLake external data source](/cdf/integration/guides/transformation/set_up_fabric_onelake_connection), reference it in transformation SQL with `ext_onelake`, then write results to a CDF destination.

## Write the SQL

Reference the source by `externalId`:

```sql theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
-- Table directly under Tables/
SELECT *
FROM ext_onelake('my-fabric-source', 'equipment')
```

```sql theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
-- Table under Tables/{schema}/{table}
SELECT *
FROM ext_onelake('my-fabric-source', 'equipment', 'operations')
```

| Rule                   | Detail                                                |
| ---------------------- | ----------------------------------------------------- |
| Argument order         | Source `externalId`, table name, optional schema name |
| Literals only          | Each argument must be a single-quoted string literal  |
| Two or three arguments | Any other arity is an error                           |
| Read-only              | Use `ext_onelake` only as a `SELECT` source           |

For a data model destination, map columns to view properties and include `externalId`:

```sql theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
SELECT
  equipment_id                  AS externalId,
  equipment_name                AS name,
  CAST(commissioned_on AS DATE) AS commissionedDate,
  manufacturer                  AS manufacturer
FROM ext_onelake('my-fabric-source', 'equipment', 'operations')
```

## Incremental loads with is\_new

By default, each run reads the full Delta table. If a column tracks when each row last changed (`TIMESTAMP` or epoch-millisecond `LONG`), use `is_new()` so later runs process only new or changed rows. CDF stores the high-water mark; the first run processes all rows.

```sql theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
SELECT
  equipment_id   AS externalId,
  equipment_name AS name,
  manufacturer   AS manufacturer
FROM ext_onelake('my-fabric-source', 'equipment', 'operations') a
WHERE is_new('equipment_cursor', a.lastUpdatedTime)
```

| Argument       | Detail                                                                       |
| -------------- | ---------------------------------------------------------------------------- |
| Filter name    | Stable string unique within the transformation                               |
| Version column | Column reference such as `a.lastUpdatedTime` — **not** the table alias alone |

<Warning>
  Passing the table alias as the second argument — `is_new('cursor', a)` — is rejected for OneLake. That alias form is for data modeling sources (`cdf_nodes`, `cdf_edges`, `cdf_data_models`). Always pass a column for Fabric OneLake.
</Warning>

Preview runs validate the query but do not advance the watermark. For general `is_new` patterns, see [SQL patterns and best practices](/cdf/integration/guides/transformation/sql_patterns).

## Create and run the transformation

Create a transformation with a data model destination (example):

```bash theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
curl -sS -X POST "${CDF_BASE}/transformations" \
  -H "Authorization: Bearer ${CDF_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      {
        "externalId": "fabric-equipment-to-dm",
        "name": "Fabric equipment to data model",
        "query": "SELECT equipment_id AS externalId, equipment_name AS name FROM ext_onelake('\''my-fabric-source'\'', '\''equipment'\'', '\''operations'\'')",
        "destination": {
          "type": "nodes",
          "view": {
            "space": "my-model-space",
            "externalId": "Equipment",
            "version": "v1"
          },
          "instanceSpace": "my-instance-space"
        },
        "conflictMode": "upsert",
        "ignoreNullFields": true,
        "isPublic": true
      }
    ]
  }'
```

| Destination type | Use when                          |
| ---------------- | --------------------------------- |
| `nodes`          | Instances of a single view        |
| `edges`          | Relationships between instances   |
| `instances`      | A data model type via `dataModel` |

Bind session nonces and run the transformation as you do for other Transformations jobs. See [Create a transformation](/cdf/integration/guides/transformation/transformations).

## Next steps

* [Monitor Fabric OneLake transformations](/cdf/integration/guides/transformation/monitor_fabric_onelake)
* [Troubleshoot Fabric OneLake in Transformations](/cdf/integration/guides/transformation/troubleshoot_fabric_onelake)
