# Ibis

Query the Nominal SQL API with Ibis expressions.

Install the Ibis backend with the `ibis` extra:

```sh
pip install "nominal[ibis]"
```

## Query data

Use an existing Nominal profile, or create one with
`nom config profile add`.

```python
import ibis
from nominal.core import NominalClient

con = ibis.nominal.connect(NominalClient.from_profile("your-profile"))
print(con.list_tables())

points = con.table("points_double")
print(points.schema())

query = (
    points.filter(
        points.dataset_rid == "your-dataset-rid",
        points.channel == "your-numeric-channel",
    )
    .select("ts", "value")
    .limit(10)
)
print(con.compile(query))  # Inspect SQL without executing the query.
df = query.to_polars()
print(df)
```

## Aggregate data

Ibis backend for the Nominal SQL API.

Compiles Ibis expressions to SQL in the Nominal SQL API’s dialect and executes
them through an authenticated NominalClient, streaming results back as Arrow.

Structured channel values, such as `points_struct.value`, are returned as
JSON strings. Use `json.loads()` to parse them.

Example

```python
import ibis
from ibis import _
from nominal.core import NominalClient

client = NominalClient.from_profile("prod")
con = ibis.nominal.connect(client)
pts = con.table("points_double")
per_minute = (
    pts.filter(_.dataset_rid == "ri.catalog....", _.channel == "temperature")
    .group_by(minute=_.ts.truncate("m"))
    .agg(n=_.count(), avg=_.value.mean().round(2))
    .to_polars()
)
print(per_minute.head())
```

Timestamp columns include their UTC timezone. Naive filter datetimes are
treated as UTC; timezone-aware ones are converted to UTC.

Ibis returns `truncate()` and `bucket()` results without a timezone. Add
`.cast("timestamp('UTC')")` to get timezone-aware UTC results.

For large results, use `query.to_pyarrow_batches()` to process rows in batches
without loading the entire result into memory.

## API Reference

Module: `nominal.ibis`.

Classes

| [`Backend`](https://dev.nominal.io/python/ref/generated/nominal.ibis.Backend.md#nominal.ibis.Backend "nominal.ibis.Backend") | Ibis backend executing queries against the Nominal SQL API. |
| --- | --- |

Functions

| [`connect`](https://dev.nominal.io/python/ref/generated/nominal.ibis.connect.md#nominal.ibis.connect "nominal.ibis.connect") | Connect Ibis to the Nominal SQL API through an existing client; see [`Backend.do_connect`](https://dev.nominal.io/python/ref/generated/nominal.ibis.Backend.md#nominal.ibis.Backend.do_connect "nominal.ibis.Backend.do_connect"). |
| --- | --- |

Exceptions

| [`NominalSqlError`](https://dev.nominal.io/python/ref/generated/nominal.ibis.NominalSqlError.md#nominal.ibis.NominalSqlError "nominal.ibis.NominalSqlError") | A SQL service error, unsupported catalog type, or invalid query result. |
| --- | --- |
