> This page is for Structured Data Models Client.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/sdgm/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/sdgm/_mcp/server.

# Data Types and Semantic Types

> Understand physical data types and semantic column meaning in Kumo Relational

sdm-client assigns each column both a physical data type (`dtype`) and a semantic type (`stype`).

* The **data type** describes how values are stored, such as integers, floating-point numbers, strings, Boolean values, or timestamps.
* The **semantic type** describes how Kumo Relational interprets those values, such as an ID, numerical feature, category, text field, or timestamp.

`Schema.from_data()` and `Schema.from_source()` infer both when you build a schema. Inspect and correct them through the `Column` objects they return — assign a semantic type as a plain string.

## Inspect and correct physical types

```python
import pandas as pd

customers = pd.DataFrame({
    "customer_id": pd.Series([1, 2, 3], dtype="int64"),
    "segment": pd.Series(["small", "enterprise", "small"], dtype="string"),
    "notes": pd.Series(["prefers email", "", "new account"], dtype="string"),
    "signup_time": ["2024-01-01", "2024-02-15", "2024-03-20"],
})

print(customers.dtypes)
```

Correct physical data types in the source before building the schema:

```python
customers["signup_time"] = pd.to_datetime(customers["signup_time"])
```

## Plan semantic meaning

Automatic inference is a starting point. Carefully review identifier-like integers, free-form strings, categories, and timestamps. In the preceding example, `customer_id` must be `ID`, `segment` must be `categorical`, `notes` must be `text`, and `signup_time` must be a `timestamp`.

```python
schema["customers"]["customer_id"].stype = "ID"
schema["customers"]["segment"].stype = "categorical"
```

Each semantic type must be compatible with the column's physical data type; assigning an incompatible combination raises immediately.

## Supported semantic types

| Semantic type      | Use for                                                  | Compatible data types                                                                                       |
| ------------------ | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `ID`               | Primary keys, foreign keys, and other entity identifiers | Integer types, `string`                                                                                     |
| `numerical`        | Quantities and continuous or discrete measurements       | Integer types, floating-point types                                                                         |
| `categorical`      | Boolean values or one label from a finite set            | `bool`, integer types, floating-point types, `string`                                                       |
| `text`             | Free-form natural language whose content carries meaning | `string`                                                                                                    |
| `timestamp`        | Event times and reference times                          | `timestamp[us]` (or another precision on a hand-built schema)                                               |
| `multicategorical` | Zero or more labels associated with one row              | `string`; list-valued dtypes are declared in the schema's type vocabulary but not yet encodable — see below |
| `sequence`         | Fixed-length numerical vectors or embeddings             | `string`; list-valued dtypes are declared but not yet encodable — see below                                 |

Use `ID` for every primary key and foreign key participating in a schema relationship. Use `timestamp` for a table's time column.

> **Warning**
>
> `multicategorical` and `sequence` are valid semantic types in the schema's type vocabulary, but the client's wire encoder cannot send a column whose cells are actual Python lists — it refuses with *"a nested column is not something this client can send... Multi-label targets are not supported by these models."* If your data needs a list-valued feature or a multi-label target, that is not available yet.

> **Warning**
>
> Kumo Relational declares `text` as a semantic type but does not read it as a model feature: a `text` column is accepted and sent, not refused, but it contributes nothing to the prediction — sdm-client warns about this once per request, naming the column. `text` is not a working substitute for `multicategorical`/`sequence`. If a column's values are really labels rather than prose, type it `categorical` instead; if it is genuinely free-form text, there is currently no relational semantic type that uses its content.

## Supported physical data types

The wire encoder normalizes source-specific types into a small set of dtypes: `bool`, `int32`, `int64` (every integer width is reported as `int64`), `float32`, `float64`, `string`, and `timestamp[us]`. The exact source mapping depends on the source, such as pandas, SQLite, DuckDB, PostgreSQL, Lakebase, Snowflake, or Databricks.

| Source values                                              | Wire dtype      | Default inferred semantic type                 |
| ---------------------------------------------------------- | --------------- | ---------------------------------------------- |
| Boolean values                                             | `bool`          | `categorical`                                  |
| Integer values                                             | `int64`         | `numerical`                                    |
| Floating-point values                                      | `float64`       | `numerical`                                    |
| Strings, pandas object columns, pandas categorical columns | `string`        | `categorical` (≤ 64 distinct values) or `text` |
| Dates and timestamps                                       | `timestamp[us]` | `timestamp`                                    |

A `DECIMAL` column — common for a numeric column read from Databricks or Snowflake — travels as the number its declared type allows: a decimal with no fractional scale, holding whole numbers that fit, is sent as `int64`; one too wide for `int64` is sent as its digits in a string, keeping every one of them exactly; anything else is sent as `float64`.

Inference can select a more specific semantic type based on column names, uniqueness, cardinality, and values. For example, an integer column can be inferred as `ID`, and a string column can be inferred as `categorical` or `timestamp`.

A column's physical data type is derived from the source. To correct it, change the source column or pandas dtype before building the schema. After building the schema, you can inspect the inferred metadata and correct semantic types, as long as the replacement is compatible with the column's physical data type.

Next, [build a schema](/sdgm/kumo-relational/user-guide/build-a-relational-graph/graph-creation). Then use [Configure Table Metadata](/sdgm/kumo-relational/user-guide/build-a-relational-graph/table-definitions) to review inferred keys, timestamps, and semantic types.