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

# Data explorer

> Preview tables and run guarded SELECT/WITH SQL against existing IO profiles and data integration configs.

export const ProOnly = ({button = 'Get started for free', description = 'Try our fully managed solution to access this advanced feature.', source = 'documentation', title = 'Only in Mage Pro.'}) => <div className="block my-4 px-5 py-4 overflow-hidden rounded-xl flex gap-3 border border-emerald-500/20 bg-emerald-50/50 dark:border-emerald-500/30 dark:bg-emerald-500/10">
    <div style={{
  display: 'flex',
  alignItems: 'center',
  width: '100%'
}}>
      <div className="text-sm prose min-w-0 text-emerald-900 dark:text-emerald-200" style={{
  flex: 1
}}>
        <span className="font-semibold">{title}</span>
        <p className="normal">{description}</p>
      </div>

      <div> </div>

      <div style={{
  height: 32,
  position: 'relative'
}}>
        <a target="_blank" rel="noopener noreferrer" className="group px-4 py-1.5 relative inline-flex items-center text-sm font-medium rounded-full" href={`https://cloud.mage.ai/sign-up?source=${source}`}>
          <span className="absolute inset-0 bg-primary-dark dark:bg-primary-light/10 border-primary-light/30 rounded-full dark:border group-hover:opacity-[0.9] dark:group-hover:border-primary-light/60">
          </span>

          <div className="mr-0.5 space-x-2.5 flex items-center">
            <span className="z-10 text-white dark:text-primary-light">
              {button}
            </span>

            <svg width="3" height="24" viewBox="0 -9 3 24" className="h-5 rotate-0 overflow-visible text-white/90 dark:text-primary-light">
              <path d="M0 0L3 3L0 6" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"></path>
            </svg>
          </div>
        </a>
      </div>
    </div>
  </div>;

<ProOnly source="data_explorer" />

The Data explorer app lets you inspect data from existing connections without creating
or running a pipeline. Use it to preview a table or stream, or to run a guarded
`SELECT` or `WITH` SQL query against a supported connection.

## Open Data explorer

In Mage Pro, select **Data explorer** from the sidebar, or open **Apps** and
select **Data explorer**.

The page is available at:

```text theme={"system"}
/apps/data-explorer
```

## Supported connections

Data explorer lists existing connections from:

* `io_config.yaml` SQL provider profiles.
* Saved data integration source configs.
* Saved data integration destination configs.

SQL-capable connections can run queries. SQLite and DuckDB configs are preview-only
in Data explorer V1. Connections with neither preview nor query support are shown as
unavailable so you can see why they cannot be explored instead of silently missing
them.

For supported `io_config.yaml` SQL profiles, Data explorer can browse metadata without
loading the full warehouse inventory in the initial connection list. It lazily loads
catalogs or databases, schemas, tables, and columns as each level is selected. When
metadata loads, the browser selects the first available catalog or database, schema,
and table by default, loads columns for the selected table, and keeps the selected
items highlighted. The metadata browser includes its own refresh control for the
selected connection. Schema browsing is currently supported for DuckDB, Microsoft
Fabric, MySQL, PostgreSQL, Redshift, Snowflake, SQLite, and Microsoft SQL Server IO
config profiles. Other SQL-capable IO config profiles can still preview or query data
when their connection settings are complete, but you must type the table name or SQL
query manually.

Viewers can open Data explorer and review the connection inventory. Editor access is
required to preview a table or run SQL. Saved source and destination configs follow
the permissions of the pipeline that owns the config: users only see integration
configs from pipelines they can view, and they must be able to edit the owning
pipeline before running a preview or SQL query through that config.

## Preview a table or stream

1. Select a connection from **All connections**, **IO configs**, **Sources**, or **Destinations**.
2. For `io_config.yaml` connections with metadata support, use the schema browser to
   confirm or change the selected catalog or database, schema, and table. The first
   available table is selected by default, and selecting another table fills the
   preview target and the starter SQL query.
3. For saved source or destination configs, choose a table or stream when options are
   available. The selected value becomes the preview target and the starter
   `SELECT * FROM <table_or_stream>` SQL query.
4. If the connection does not provide table options, or the schema browser does not
   load a matching table, type the table name.
5. Set a row limit.
6. Click **Preview table**.

Preview requests run a limited `SELECT * FROM <table>` query.

## Run a SQL query

1. Select a SQL-capable connection.
2. Enter one `SELECT` or `WITH` query.
3. Set a row limit.
4. Click **Run query**.

Data explorer accepts one `SELECT` or `WITH` statement at a time. Mutating statements
such as `INSERT`, `UPDATE`, `DELETE`, `DROP`, locking clauses such as `FOR UPDATE` or
`FOR SHARE`, and multi-statement SQL are rejected. Data explorer also rejects
`SELECT` or `WITH` queries that call known unsafe functions with side effects, such as
functions that update sequences, terminate sessions, sleep, read server-local files,
or execute provider-specific system commands. The server also clamps row limits to
protect the workspace from accidentally large previews.

These safeguards are not the same as database-enforced read-only execution for every
provider. PostgreSQL and Redshift preview and query execution start a database
read-only transaction before running the query and roll it back afterward. Metadata
browsing uses server-generated `SELECT` queries with provider timeout settings.
Metadata discovery, preview, and query execution are also bounded by server-side
deadlines. For providers with native timeout controls, Data explorer passes those
settings to the driver or query job. If a provider call exceeds the relevant deadline,
Data explorer attempts provider-native cancellation where available, closes or stops
the bounded execution operation, and returns a timeout error. Other supported
providers rely on statement validation, restricted-function checks, provider timeout
or lock-timeout settings where available, bounded server execution deadlines, and
row-limit enforcement.
For those providers, use credentials that already have the least privileges needed
for exploration.

```sql theme={"system"}
SELECT *
FROM analytics.orders
ORDER BY created_at DESC
LIMIT 100;
```

## Review results

After a preview or query succeeds, Data explorer shows the returned rows in a table.
Use the column headers to sort the returned rows, or open a column filter to narrow
the rows shown in the current result. These sort and filter controls apply only to
the returned sample. To filter the full source table, add the filter to the SQL query.
Returned row counts describe the loaded preview window, not the total number of
rows in the source table. To answer full-table cardinality questions, run an exact
`COUNT(*)` query against the selected table or filtered query.

When a tabular result is available, click **Expand results** to hide the connection,
schema, and query browser and give the results table more space. Click **← Back**
to restore the explorer panels. Data explorer remembers this layout
preference for future result tables.

## API

The UI uses the `data_explorations` API resource.

| Action                    | Method | Endpoint                 | Required role |
| ------------------------- | ------ | ------------------------ | ------------- |
| List connection inventory | `GET`  | `/api/data_explorations` | Viewer        |
| Browse IO config metadata | `POST` | `/api/data_explorations` | Editor        |
| Preview or query data     | `POST` | `/api/data_explorations` | Editor        |

`GET /api/data_explorations` returns each connection with fields such as `uuid`,
`label`, `kind`, `provider`, `profile`, `pipeline_uuid`, `block_uuid`, `supports_sql`,
`supports_preview`, `supports_metadata`, `table_options`, and redacted `metadata`.

To browse schema metadata for a supported IO config connection, send a nested
`data_exploration` payload with `action_type: "metadata"`:

```json theme={"system"}
{
  "data_exploration": {
    "action_type": "metadata",
    "connection": {
      "uuid": "io_config:postgres:default"
    },
    "metadata_type": "tables",
    "schema": "public",
    "limit": 200
  }
}
```

Metadata requests accept `metadata_type` values of `databases`, `schemas`, `tables`,
or `columns`. Table metadata requires `schema`; column metadata requires both
`schema` and `table`. The optional `database` field is used by providers that need a
catalog or database qualifier, such as Snowflake. Metadata limits are clamped
separately from preview and query row limits.

To preview or query data, send a nested `data_exploration` payload:

```json theme={"system"}
{
  "data_exploration": {
    "action_type": "query",
    "connection": {
      "uuid": "io_config:postgres:default"
    },
    "query": "SELECT * FROM analytics.orders",
    "limit": 100
  }
}
```

Responses include `success`, `columns`, `rows`, `metadata`, and `error_message`.
For query responses, `metadata.returned_row_count` is the number of rows returned
in the preview window, `metadata.preview_limit_reached` indicates whether the
window reached the requested limit, and `metadata.row_count` can be `null` when
the API did not run an exact count. Treat `metadata.row_count` as full-result
cardinality only when `metadata.row_count_mode` reports that an exact or estimated
count is available.
Connection metadata and error messages are redacted so credentials are not exposed in
the response.
