Migrate to structured-data-models-client
structured-data-models-client (imported as sdm_client) is NVIDIA’s open-source client for structured-data foundation model NIMs, serving both Kumo Relational and Kumo Tabular from one package. This page covers moving Kumo Relational usage from kumo-relational-client 1.0 to structured-data-models-client 1.0.
Update package names
What you install is not what you import. The five distributions are structured-data-models-client, -api, -pql, -connectors, and -relational-engine; the modules are sdm_client, sdm_api, predictive_query, sdm_connectors, and sdm_relational_engine. They are released together on one version and pin each other exactly.
Update imports and the client class
The model is now an argument to one predict() method, not a method name — client.relational(graph) is gone. Gathering the request (materialize()) is now a separate, explicit step from sending it (predict()).
Graph becomes Schema
relational.Graph is renamed Schema, and it is the same type Kumo Tabular uses — one table is the degenerate case, not a second system.
Connector-backed (in-place) sampling is back, under Schema.from_source
Earlier releases of structured-data-models-client temporarily dropped warehouse-sampled graphs; Schema.from_source restores them as of 1.0.0. If you built against a pre-release snapshot that only had Schema.from_data, revisit any workaround that read whole tables into memory — you likely don’t need it anymore:
Only materialize()’s sampled rows leave the source. DatabricksSource, SnowflakeSource, PostgresSource, DuckDBSource, and SQLiteSource cover the connector pages under Connect Data Sources, each with its own backend-specific connection. DatabricksSource and SnowflakeSource also convert a metric view or semantic view directly with source.semantic_model(name).
If you still only have DataFrames, Schema.from_data() is unchanged — read a table first with sdm_connectors.read(), then build the schema from the result.
run_mode is gone
Set num_context_samples on materialize() instead.
Batching is now automatic — batch_size and num_retries are gone
predict(..., batch_size="max", num_retries=3) used to auto-split a large job into batches. materialize() now does this for you: pass up to 100,000 entities and it gathers them as up to 100 calls, each sent by predict() and merged into one result. See Batch Prediction. You only chunk indices yourself past the 100,000-entity ceiling, which is a different, much higher threshold than the earlier 1,000-per-call limit.
SDMClient(max_retries=...) still retries a transient transport failure per call.
predict_task() has no relational equivalent yet
Supplying your own labeled context directly, bypassing PQL, is not currently supported for the relational model — the direct Request() builder is refused for model=KumoRelational() even with related_tables=. See Predict with Custom Context.
Ranking now requires candidates=, and runs as one call per candidate
A candidate your sampled context can’t answer is left out of every row rather than failing the whole ranking — see Prediction Results. Consider the “rank over a table of pairs” pattern instead, which runs as one classification request, batched if needed, regardless of candidate count.
Result field names changed
See Prediction Results for the current field-by-field mapping.
Dtype / Stype are strings now
ViewConversionWarning and graph.conversion_messages are replaced by schema.conversion_notes, populated when the schema came from source.semantic_model(...).
end_time_column is gone
Table has only time_column. If your workflow relied on end_time_column to represent row validity intervals, that is not currently supported.
Explanation support depends on your deployment
The upcoming explainability API uses result.explanations.gradients for per-entity gradients and result.explanations.columns for labelled-context cohorts.
The singular result.explanation property is deprecated.
The client does not generate a natural-language summary.
See Prediction Explainability for the compatible-deployment requirement and examples.
Databricks Model Serving has a new entry point
There is no for_snowflake_serving in structured-data-models-client.
Update the model identifier
The only accepted model identifier is still kumo-relational:
Update error handling
RelationalError becomes StructuredDataError. UnknownModelError, UnsupportedRequestError, and MissingExtraError are subclasses with the same intent as before. See Python SDK API.
What is unchanged
- The PQL grammar, including
WHERE,ASSUMING,FORECAST N TIMEFRAMES, andRANK TOP K(still capped at 20 candidates ranked). - Task kinds: classification, binary/multiclass classification, regression, forecasting, and temporal link prediction are all still supported.
- The underlying Universal TFM REST contract — see NIM REST API.
- Automatic removal of context rows that would answer the question being scored.
After updating, run a representative prediction for each task type and verify the task-dependent result shapes described in Prediction Results. The client’s own changelog and stability contract are the canonical source for anything this page doesn’t cover.