Python package and CLI 1.36.0
Track deployment progress and limit refresh waits.
How to install this version
Review the changes below before installing. To install this version, activate a compatible Python virtual environment and run:
python -m pip install "relationalai==1.36.0"For the latest installation instructions, see Start building with PyRel.
New Features and Enhancements
Section titled “New Features and Enhancements”-
When you deploy a model from Python or the command line, you can now see which stage is running, which deployment steps have finished, and which were skipped because nothing changed. Deployment can finish before the initial data refresh completes.
-
When you run
rai models deploy --wait, the command no longer limits how long it waits for the initial data refresh. To stop waiting after five minutes, runrai models deploy --wait --wait-timeout 300. The--wait-timeoutoption requires--waitand a positive number of seconds. Reaching the timeout stops only the wait. It does not cancel deployment or the data refresh. -
When you inspect deployed model outputs in Snowflake, their comments now identify the concept or relationship they represent, such as
Concept: PersonorRelationship: owner owns pet. Their columns and data are unchanged.
Bug Fixes
Section titled “Bug Fixes”-
Internal Snowflake views that prepare source data for model deployment now include
_INTERNAL_in their names so you can distinguish them from your model’s published outputs. Query published outputs instead of these internal views. When you redeploy, these internal views are replaced without copying permissions granted directly to them. After redeploying, check any references to the names of these internal views and any permissions you granted on them. -
Snowflake tables that hold intermediate results while calculating your deployed model’s outputs now include
_INTERNAL_in their names. This naming change also applies to other objects used in those calculations and works even when you add a prefix or suffix to object names. If your queries reference these internal objects, update them to use published outputs instead. The_INTERNAL_label helps you recognize these objects but does not restrict access to them. -
Prescriptive objectives and constraints now raise
ValueErrorwhen aggregate calculations could count repeated values differently from the solver, preventing misleading solution checks. Affected objectives and constraints must be rewritten, with no deprecation period or automatic correction. SeeProblem.minimize,Problem.maximize, andProblem.satisfyfor supported aggregate forms. When running through SQL, aggregating totals produced by another aggregate still has known limitations. -
When you redeploy a model, eligible concepts with a parent concept or subtypes can now become Snowflake views instead of tables if deployment detects a single source. The rows returned for these concepts are unchanged. Views do not store their own copy of the data or need the former table’s refresh task, so deployment may warn about an unused refresh schedule or requested Iceberg storage.
-
When you deploy a model, you now get an error if a task that refreshes its data cannot start, instead of a success message with refreshes inactive. If the error names a missing
EXECUTE TASKpermission, ask an administrator to grant it to the role that owns the task, then redeploy. If you intend to refresh data manually instead, set bothinterval_s: 0andrun_on_deploy: falsefor every schedule inDeploymentConfig. The error does not remove objects already created during deployment. -
When you run
rai models teardown, unrelated databases that your Snowflake role can list but cannot inspect no longer normally cause the command to fail. Your role still needs permission to inspect databases used by the model or containing model metadata visible to your role. If the command cannot search for model metadata across your account, it checks all databases visible to your role instead. It cannot find model branches in databases your role cannot see. -
Model deployment now places the objects used internally to calculate graph results in the meta schema, which stores deployment state. Published graph results remain in the target schema configured for your model’s outputs. Redeploy your graph model to use this layout. If your SQL queries reference these internal objects, update them to use published graph results instead. If you use the same schema for the target and meta schemas, both kinds of objects still share that schema.
-
Shared models now preserve newly recorded floats and large integers exactly in their change history, fixing unexpected numeric type changes and redeployment errors such as
CreateData id mismatch. Coordinate client upgrades across your team before recording new history, because older client versions cannot read the new numeric format. For an affected branch, userai models pull, deploy from your original source, then userai models merge. This fix does not restore precision already lost in older history, and floats with no fractional part in that history can still be restored as integers. Positive and negative zero now receive different identifiers in the model. -
Predictive reasoning now keeps results for different entities separate, even when their predicted values match. For predictions tied to a specific time, that time also identifies the result. Review queries that rely on result IDs or counts, which can change. Each result now includes the entity the prediction is for and the time where applicable. If a result column has the same name as a field used to identify the result, PyRel raises
ValueError. This does not guarantee one result per source entity when ranking link prediction candidates. -
Snowflake model deployment now stores missing values, including numeric NaN, as SQL
NULLwhen preparing data defined directly in Python or provided as pandas DataFrames throughModel.data. For example, a query for scores greater than zero excludes an entity with a missing score, while a query without that filter can still return it. This fix applies only to deployment’s standard data preparation path, not all ways of running SQL. -
Queries of models deployed to Snowflake now return correct ranks for rows within each group when you select a related entity’s value alongside
rank. Previously, every row in a group could receive rank 1. In the queries fixed by this change, rows missing a value used to group or sort them receive no rank. -
Splitting text stored in a property with
strings.splitorstrings.split_partno longer raises invalid identifier or unsupported subquery errors in some Snowflake queries and deployed rules. If the separator isNULL, splitting returns no parts. Dynamic tables that use these split results may need a full refresh of their data. Combining splitting with aggregates such as sums or counts is still not generally supported. -
Some Snowflake queries now keep a row when an optional range of values or regular expression produces no matches, returning
NULLfor the missing result instead of dropping the row. The fix does not cover optional conditions with subqueries, using values generated by operations such as ranges to check for no match, or supplying default values for those generated results. -
Ranking distinct values in queries of models deployed to Snowflake now gives each row the correct rank, instead of giving every row the highest rank or repeating rows once per rank. Equal values share a rank, so ranking
10, 10, 20in ascending order gives1, 1, 2. In the queries fixed by this change, rows with missing values remain in the results without a rank, and later calculations such as sums or counts are no longer limited to rows included in an earlier ranking. -
Relationship declarations now preserve separate fields when one field accepts values from more than one concept type and another field follows it, including when reconstructing a shared model. Concept names containing line breaks are also recognized correctly in relationship readings, the text that declares the fields.
-
Queries using the optional direct compiler now compile successfully when filters combine checks for no match, alternative conditions, and checks for whether a value is in a list, including in rules that derive facts. This fix applies only if you already use this alternative way of translating PyRel queries for execution. Default query behavior is unchanged.
-
Debugger traces now stay separate when you explicitly deploy two models in the same Python process. Each model’s later query traces are saved in its own run directory, so they do not get mixed together in
rai debugger. Automatic deployment still uses one shared debugger run for all models in that process. -
Model outputs in Snowflake can now refresh in some cases where a rule allows any of several conditions to match, and one condition compares values from the same entity while checking another table. Previously, affected dynamic tables failed with
Unsupported subquery type cannot be evaluated inside DYNAMIC TABLE. Other Snowflake restrictions on subqueries still apply. -
Snowflake queries using
Model.not_to exclude matches now support some conditions that both match a related row and compare the selected entity’s own values with each other. Previously, these queries failed withUnsupported subquery type cannot be evaluated. -
Model outputs in Snowflake that calculate a value from two counts grouped by the same entity can now refresh successfully. The fix applies when the condition containing the calculation includes both relationships used to group the counts. Previously, affected outputs failed during refresh with
Unsupported subquery type cannot be evaluated. -
Timeout messages from
rai models deploynow distinguish a successful deployment from an unfinished wait for the first data refresh when you use--waitwith--wait-timeout. The refresh is not cancelled and may still be running. Run the exact SQL printed by the command to check the refresh status. If you call the command from a script, keep handling exit code1because the requested wait did not finish. -
Using regular expression capture groups to extract part of a match with
re.findallnow works in some Snowflake queries instead of raising an unsupported subquery error. Repeated matches keep their own captured text, so extracting minutes from10:15and11:47returns15and47. -
Unions of opposite-direction relationships now execute in covered queries of deployed models even when the branches encounter the same entity keys in a different order. For example, combining replies from one person to another with replies in the opposite direction no longer raises an unsupported-subquery error. The branches must still refer to the same entity pair.
-
Snowflake queries that filter alternative property values with fallback or
Model.unionbefore filtering the entity, for example by cost, now avoid missing or extra entities. For each entity, fallback uses the first alternative with a value, while a union includes matches from all alternatives. Each alternative must identify the same entity. The fix does not cover alternatives inside other alternatives, fixed default values, or alternatives containing only aggregate calculations. -
Snowflake queries can now sum or count grouped totals from
Model.datarows without failing with internal error370001. Group totals contribute once per source row, not once per group. -
Snowflake queries now return correct counts for each pair of entities when combining matches from alternative conditions, including a zero default for pairs with no matches.
-
Grouped counts in Snowflake queries now preserve filters when the grouping entity is reached through different relationships, preventing unrelated records from being counted.
-
Snowflake queries that combine matches from alternative conditions now return each entity pair’s own total, using a zero default specified in the query for pairs with no matches rather than mixing totals or duplicating rows. The combined matches must be grouped by the same pair selected in the query, and pairs removed by filters remain excluded. Queries with multiple summary calculations that have defaults, grouping values referred to through another variable, or no default remain outside the fix. This fix applies to the default query behavior.