Skip to content

Python API Release Notes

1.30.1

Python SDK


Version 1.30.1 of the relationalai Python package is now available!

To upgrade, activate your virtual environment and run the following command:

pip install --upgrade relationalai

New Features and Enhancements

  • When you deploy a model, RelationalAI now checks the generated SQL first and stops with a clear error instead of letting the deploy succeed and then potentially fail later on its first refresh. The check is on by default. Set deployment.validate_sql to false to skip it.

  • You can now deploy a model that contains a prescriptive Problem, and have Snowflake solve it on each scheduled refresh without keeping a Python session open. It runs under a Snowflake identity you configure with the new deployment.pat_user and deployment.pat_warehouse settings.

Bug Fixes

  • Deployed model outputs that filter rows with a match or union inside where() now evaluate that filter for each current row. This fixes a bug that could cause affected outputs to include extra rows or return no rows.

1.30.0

Python SDK


Version 1.30.0 of the relationalai Python package is now available!

To upgrade, activate your virtual environment and run the following command:

pip install --upgrade relationalai

Bug Fixes

  • When querying a deployed model in Snowflake, aggregates inside a union() could fail with Unsupported subquery type cannot be evaluated. Aggregates now compute over their whole group instead of a single row. This applies to count(), sum, max, and avg, including when grouped with .per().

1.29.1

Python SDK


Version 1.29.1 of the relationalai Python package is now available!

To upgrade, activate your virtual environment and run the following command:

pip install --upgrade relationalai

New Features and Enhancements

  • Deploying a model with rai models deploy is now faster. PyRel creates your tables, views, and dynamic tables at the same time instead of one by one, while still respecting how they depend on one another. It's on by default and produces the same result, so you don't need to change anything.

Bug Fixes

  • Filters that compare a value to Python None now keep the correct rows instead of silently dropping the ones where the value is missing, in both Model.where with == None or != None, and Concept.filter_by(prop=None).

  • Models with rules that divide numbers with decimal places now deploy instead of failing with a numeric-precision error.

  • Sharing a model through rai models pull or rai models merge now regenerates a more accurate shared_model.py. It keeps parts of your model that earlier versions could drop or silently break, such as joins between different number types, counts of a column or property, and concepts that extend Any or AnyEntity.

  • The PyRel debugger's Trace tab again shows the steps PyRel runs to build your model. A recent change had collapsed them into a single "no changes" row.

1.29.0

Python SDK


Version 1.29.0 of the relationalai Python package is now available!

To upgrade, activate your virtual environment and run the following command:

pip install --upgrade relationalai

New Features and Enhancements

  • Queries that use path() to find paths in a graph now compile and run faster, especially patterns that repeat a step a bounded number of times with .repeat(min, max). In one benchmark, compiling a large repeated pattern dropped from over a minute to under a second, with no change to results.

  • Display strings for constraints and objectives now work when the model runs in Snowflake: the prescriptive reasoner renders them inside the model instead of in the Python client. The rendered text is available as a display_string property. Call install_display_strings() on a Problem before you deploy it (interactive use installs it automatically on the first display()).

  • Deploying a model that schedules automatic refreshes with rai models deploy now warns you when the Snowflake role that owns the refresh tasks lacks the account-level EXECUTE TASK privilege. Before, the deploy reported success but the refresh never ran, so the tables stayed empty with no explanation. The warning names the role and the exact grant needed to fix it.

Bug Fixes

  • In a deployed model, several aggregate queries that used to fail with the message Unsupported subquery type cannot be evaluated or return wrong results now work correctly. This includes grouped aggregates (.per()), aggregates capped with aggregates.limit, and aggregates used inside a not_() check.

  • In a deployed model, rank() now groups rows correctly when the same definition also contains an unrelated aggregate that uses a fallback value. Before, every row could land in its own group, so the rank was 1 for every row. This produced silently wrong results with no error.

  • After you deploy with op log recording turned off, rai models list and the related branch, switch, and teardown commands now work as expected.

  • rai models deploy --wait now makes a new model version visible to other users of the model as soon as its Snowflake objects are installed, rather than after the first data refresh finishes.

  • Deploying a model no longer fails when a concept has multiple identifying properties and one of them has no values. That property now deploys as an empty table.

  • When you set deployment.outputs.reasoner on a model that also defines a prescriptive Problem, the deploy no longer skips outputting the problem. It keeps the solver's outputs in place, routes only the outputs it can, and warns about the ones it left alone.

  • Querying a model in a Snowflake notebook no longer shows stray error cards (such as [Invalid iteration] Cannot iterate over Chain objects.) underneath a query that actually succeeded. These came from the notebook inspecting PyRel objects left in the namespace. Real errors from your own code still appear.

  • Calling AnyEntity.ref() no longer raises an UnresolvedType error and now works as expected.

  • Deploying a model whose objects are Snowflake dynamic tables and that also uses the logic reasoner no longer shows warnings about dynamic tables or rebuilds them as regular tables.

Deprecations and Removals

  • Problem.display() no longer accepts part= or where=. Passing either now raises a TypeError. To filter what you see, first render the display text with install_display_strings(), then read the new display_string property from the constraint (or other expression) you want, just like any other field:

    problem.install_display_strings()
    # capacity_constraint is a constraint you defined when building the problem
    model.select(capacity_constraint.name, capacity_constraint.display_string).where(capacity_constraint.name == "cap_3")
    

    Output is now sorted as plain text instead of natural number order, so x_1, x_2, x_10 now appears as x_1, x_10, x_2.

  • all_different now takes a single argument.

1.28.0

Python SDK


Version 1.28.0 of the relationalai Python package is now available!

To upgrade, activate your virtual environment and run the following command:

pip install --upgrade relationalai

New Features and Enhancements

  • PyRel now records your model's change history automatically every time you deploy to Snowflake with rai models deploy. This history is called the op log, and it's what makes rai models branch, pull, and merge work, so those commands now work right away with no setup. To turn recording off, set oplog.enabled: false in raiconfig.yaml.

  • When you deploy a model, a concept and its subconcepts (declared with extends=) can now be built by different reasoners at the same time. For example, one subconcept can load straight from a Snowflake table while another is derived by rules. Querying the parent concept returns rows from all of its subconcepts together. Previously, every subconcept had to use the same reasoner.

  • Instead of writing separate SQL queries to explore a Snowflake database table by table, you can now run rai explore schema to capture its full structure (column types, primary and foreign key candidates, and value distributions) as a single JSON file. This helps when you're building a semantic model from an existing database and want to understand it first. It supports Snowflake sources only for now.

    For example:

    rai explore schema --database DEMO_TELCO --schema RAW --out schema.json
    
  • You can now define more than one decision problem on the same model, each as its own Problem. Once a model has more than one, give each Problem a unique name using the name parameter so PyRel can tell them apart, and match each one to the same problem every time you redeploy.

  • You can now use aggregates.string_join in models deployed to Snowflake. Use index= to control the order the values are joined in, or leave it out to join them in ascending order by value.

Bug Fixes

  • If your deployed model's target schema also holds tables or views you didn't create with PyRel, tearing down the model no longer removes them. rai models teardown now deletes only the objects RelationalAI created, and never drops the schema itself, even with --force. If RelationalAI created the schema, teardown reports it separately, along with the SQL needed to remove it.

  • Deploying a model no longer crashes with ExtractionError: Property owner must be user schema object when it adds a property to a built-in concept. This came up in many common models, such as any model that uses the graph or prescriptive reasoner, or that simply calls Error.new(message=...). If you set oplog.enabled: false only to work around this crash, you can now remove that setting.

  • In a deployed model, grouped aggregate queries now return correct results when a grouped aggregate (using .per()) shares a variable with another aggregate or lookup in the same rule. Some of these queries previously returned wrong rows, too few rows, or were rejected. Only deployed models were affected.

  • In a deployed model, an aggregate combined with a fallback value using | (for example, count(C).per(C.grp) | 0) now returns one correct row per group. Before, it could return wrong rows, or the deploy could fail on Snowflake with Unsupported subquery type cannot be evaluated. Only deployed models were affected.

  • A query that uses union() to express an OR condition across differently filtered joins no longer fails to deploy to Snowflake with Unsupported subquery type cannot be evaluated.

  • In a deployed model, a concept with a property derived from another of its own properties no longer fails to deploy when nothing else in the model creates that concept. It now deploys with zero rows, which matches the fact that nothing populates it.

  • A model no longer fails to deploy to Snowflake with an error like invalid identifier '__VAR_N' when a filtered, grouped aggregate is used to classify an existing entity, such as model.where(R(x), c := per(x).count(y), c > 1).define(Flag(x)).

  • A model with a concept that uses implicit identity no longer silently drops rows when the same data is read more than once during deploy. No model changes are needed. Redeploying applies the fix.

  • Compiling a model with a large union(), such as hundreds of filter fragments feeding one rule, is now much faster. A compile that used to take over a minute now finishes in a few seconds.

  • If your deployment role can't change Snowflake log or trace levels, deploying no longer shows a false Deploy Step Skipped warning when your role already inherits a sufficient level from the account, database, or schema. The warning still appears when the level really is too low, which you can fix by granting your role the MODIFY LOG LEVEL and MODIFY TRACE LEVEL privileges.