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

# SQL and Python

> Query your warehouses in SQL cells and use the results as dataframes in Python.

SQL cells query a connected warehouse and return a dataframe by name. Later Python cells use it like any other variable.

## SQL cells

Add a SQL cell with **Insert SQL below** in a cell's **⋯** menu, or select a cell and press <kbd>S</kbd> to turn it into SQL. The cell header has two settings:

* **Connection**: where the query runs. Pick one of the workspace's [connections](/foundations/plugins-and-connections), or **DuckDB** to query the notebook's own dataframes. DuckDB is the default.
* **Result name**: the variable the result is stored in. Other cells read the result by this name. The default, `_df`, starts with an underscore, so it stays local to the cell. Rename it to use the result elsewhere.

A query against a connection runs with that connection's credentials. Hover the connection to see whose they are. If the connection is not available in the workspace, the cell says so and fails when it runs.

Turn off **Show result** in the cell's **⋯** menu to keep the result as a variable without displaying it.

### Results

Results show as a table you can page through, filter, and sort. **Copy as CSV** copies the result.

Results are dataframes. By default Alkera uses Polars when it is installed. Change it in notebook **Settings** under **Frames as**: **Polars**, **pandas**, or whichever is installed. **Rows per SQL result** caps how many rows a query returns. Leave it empty to keep every row.

## Use results in Python

A SQL cell's result is a normal Python variable.

```python theme={null}
# A SQL cell with the result name `orders` ran against Snowflake.
import polars as pl

weekly = (
    orders
    .group_by_dynamic("ordered_at", every="1w")
    .agg(revenue=pl.col("amount").sum())
)
```

The Python cell depends on the SQL cell, so changing the query re-runs it. See [Reactivity](/notebooks/reactivity).

You can also run SQL from Python with `alkera.sql`:

```python theme={null}
orders = alkera.sql(
    "SELECT * FROM analytics.orders WHERE ordered_at >= '2026-01-01'",
    connection="Snowflake prod",
)
```

## Join across warehouses

A warehouse query cannot see another warehouse or the notebook's dataframes. To combine data from two sources, query each one in its own cell, then join the results in a **DuckDB** SQL cell or in Python.

```sql theme={null}
-- DuckDB cell. `orders` came from Snowflake, `accounts` from Postgres.
SELECT a.segment, SUM(o.amount) AS revenue
FROM orders o
JOIN accounts a USING (account_id)
GROUP BY a.segment
```

## Python cells

Python cells run any Python in the workspace's [environment](/notebooks/environment). Each cell's last expression is displayed as its output. Variables a cell defines are available to every cell that reads them.

## Markdown cells

Markdown cells hold headings, text, lists, and links. They render in place, and their headings appear in the **Outline** panel. To write Markdown from Python, use `alkera.md`.

## Related

<Columns cols={2}>
  <Card title="Reactivity" icon="arrows-rotate" href="/notebooks/reactivity">
    How SQL and Python cells stay current.
  </Card>

  <Card title="Plugins & Connections" icon="plug" href="/foundations/plugins-and-connections">
    The warehouses a SQL cell can query.
  </Card>
</Columns>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.