Skip to content

Python API Release Notes

1.32.0

Python SDK


Version 1.32.0 of the relationalai Python package is now available!

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

pip install --upgrade relationalai

Breaking Changes

  • This breaking change affects only prescriptive reasoning, which is a Public Preview feature available by request. When you create an optimization problem in your Python code, some constraints and objectives that used to be accepted now raise a clear error, so review your existing problems after you upgrade. For example, applying count directly to a decision variable is now rejected because it counts rows rather than the values the solver chooses. A few others still build but now describe a different problem. To check them, print the problem with Problem.display() and confirm the formalized constraints and objectives match what you intended.

New Features and Enhancements

  • You can now use the percentile and median aggregates to summarize your data. You can group either one with per() like any other aggregate.

  • When you deploy a model to Snowflake, you can now apply your own existing Snowflake object tags to every object the deploy creates by listing them under deployment.tags. On a redeploy, each object keeps only the tags you list.

    deployment:
      tags:
        GOVERNANCE.TAGS.COST_CENTER: engineering
    
  • You can now attach an existing Snowflake row-access policy to the tables, views, and dynamic tables a deploy creates by adding a per-output policies override under deployment.outputs. RelationalAI does not fully check the policy first, so an invalid one can still fail when the deploy runs.

    deployment:
      outputs:
        overrides:
          - objects: [ORDERS]
            policies:
              row_access_policy:
                fqn: GOVERNANCE.POLICIES.TENANT_ACCESS
                columns: [TENANT_ID]
    
  • You can now point RelationalAI at a Snowflake tag you already created for object ownership with deployment.managed_tag. A governed account can then deploy a model without the Snowflake CREATE TAG privilege. The deploying role needs APPLY on the tag and USAGE on the database and schema that hold it.

    deployment:
      managed_tag: GOVERNANCE.TAGS.RELATIONALAI_MANAGED
    
  • You can now open a rai doctor report in the rai debugger offline, without access to the Snowflake account it came from. The trace, Refresh Log, and deployment graphs all work from the unzipped report.

Bug Fixes

  • A model with a wide concept, roughly 43 or more nullable properties, that failed to deploy with a RecursionError now deploys again. This fixes a regression introduced after version 1.29.1.

  • Fixed an issue that caused some models to fail to deploy with an "object already exists" error.

  • If you place a model's metadata and operation log in a custom schema with deployment.meta_schema, RelationalAI now uses that location consistently for deploys, teardown, and branch operations. Changing the setting later does not move existing metadata, so set it before your first deploy.

  • Redeploying a model now recreates every changed Snowflake object consistently, and it preserves the grants you added to its procedures and functions. Because objects are recreated rather than altered, you may need to restore other object-level state yourself.

  • Deploying a model to Snowflake is faster, because RelationalAI now runs its two metadata setup phases in parallel.

  • Two deployment records that claim the same model identity no longer break rai models listing or teardown for the whole database. The conflicted model stays listed with a warning that explains how to repair it.

  • For models deployed to Snowflake, the variance and variance_samp aggregates no longer lose precision on whole-number input. Expressions that raise a value to a power with **, such as math.haversine, no longer fail. This does not fix geometric_mean over negative input on Snowflake, which is still unsupported.

  • For models deployed to Snowflake, comparing two entity types with == no longer errors when their identities are stored differently, for example a generated hash versus an integer identify_by key. Because the two kinds of identity can never be equal, the comparison now returns False.

  • A where() filter whose condition is a Python builtin call with a literal argument, such as abs(-1) == 2, now filters when the condition is false, as expected.

  • For models deployed to Snowflake, queries that compute several aggregate measures over the same grouping now run in a single pass instead of re-scanning the data once per measure. The results are unchanged.

  • Calling inspect() or to_df() on a define or require fragment now raises a clear error, "Cannot inspect a define" instead of crashing. A define or require adds to your model rather than running as a query, so there is nothing to inspect.

  • When a configuration file that RelationalAI discovers automatically, such as ~/.rai, the Snowflake CLI config, or a dbt config, fails to load, RelationalAI now reports the real error and names the file that failed, instead of a generic "no configuration found" message. A commented-out {{ env_var(...) }} line is also no longer evaluated, so it can no longer fail on an unset variable.

1.31.1

Python SDK


Version 1.31.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 to Snowflake now needs one less Snowflake tag. RelationalAI no longer creates or requires the RELATIONALAI_MANAGED_SCHEMA tag, which simplifies setup for administrators who pre-create tags for a restricted deploy role.

Bug Fixes

  • A model with a uniqueness requirement across two different concepts, such as require(unique(Subscription.account, Subscription.phone)), now deploys to Snowflake instead of failing with a table-creation error.

1.31.0

Python SDK


Version 1.31.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

  • You can now use the variance and variance_samp aggregates to measure how spread out your data is. variance returns the population variance and variance_samp returns the sample variance, and you can group either one with per() like any other aggregate.

1.30.4

Python SDK


Version 1.30.4 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

  • You can now use the geometric_mean aggregate to average rates and ratios, and group it with per() like any other aggregate. It expects non-negative numbers.

  • Run the new rai config check command to catch configuration mistakes before they cause errors later. It checks that your configured reasoners have valid names and sizes for your Snowflake account's cloud.

  • Queries in a deployed model that read from a Snowflake source table now run faster automatically. RelationalAI no longer sorts the table when your query doesn't use its row order.

  • Aggregates over a relationship chain, such as min(Customer.transaction.pay_date).per(Customer), now run faster automatically. RelationalAI no longer adds an unnecessary join.

Bug Fixes

  • You can now deploy a model into a Snowflake schema named after a SQL reserved word, such as ORDER or SCHEMA. Before this release, the deploy failed with an error saying the object did not exist.

  • You can now deploy a model with a Snowflake role that only has USAGE on a schema your administrator created for you, with its tags already in place. RelationalAI no longer creates an account-wide management schema.

  • If your deploy role can't create a schema it needs, the deploy now stops early with a clear error that gives you the exact grants and CREATE SCHEMA statements to run, instead of failing partway through.

  • Redeploying a model now keeps the Snowflake grants and compatible object and column tags you applied to its tables. Before this release, a redeploy could drop them.

  • math.haversine now returns the correct distance. Before this release, it returned a wrong value, so recompute any distances you calculated with it.

  • A select whose only content is a single function call on a literal, such as select(parse_number("abc", 19, 0)), now returns one row with a null value when the call produces nothing, instead of no rows. If any of your logic treats an empty result as a signal, review it, since these queries now return a null row you can handle with null-safe logic.

  • When you deploy a model, a rule whose condition matches no rows no longer adds any facts. Before this release, a rule that defined two or more fixed facts added them anyway, leaving facts in your model that shouldn't be there.

  • When you deploy a model, a grouped aggregate whose default value sits behind an unreachable branch no longer duplicates rows. Before this release, it could return two rows per group instead of one.

  • Deploying, branching, and pulling a model through its op log is more reliable. A model that uses a standard-library function, such as parse_float, now loads consistently in any Python session, and a model that sets the preserve_column_case deployment option no longer regenerates invalid Python.

1.30.3

Python SDK


Version 1.30.3 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

  • You can now sign in to Snowflake two new ways. Pass your private key to JWTAuth in memory with a new private_key field instead of saving it to a file, or inject your own Snowpark session into create_config with snowflake_session=.

  • Refreshing a deployed model is now faster when some of its outputs are independent of each other, because those outputs refresh in parallel instead of waiting for unrelated ones. This happens automatically.

  • The rai debugger can now show how long each part of a refresh took, so you can find the slow ones. Open a finished refresh run and select View Timeline to see the whole refresh and its parts laid out on a timeline.

  • Added the floats module to the public std namespace, making its functions available like other standard-library modules. You can now use std.floats.float() to convert a value to a float, or std.floats.parse_float() to turn a string into a float.

Bug Fixes

  • An aggregate like a count or sum now respects a union filter, or a unary relationship, applied to it in where(). Before this release, the aggregate ignored that filter and ran over every row, so it could return a wrong total or count with no error.

  • aggregates.limit now returns only the number of rows you asked for when you order it by the grouping keys of another aggregate in the same query. Before this release, it ignored the limit in that case and returned every row.

  • A query that aggregates over a cycle of relationships, such as A knows B, B knows C, and C knows A, now returns a result. Before this release, a query like this could fail to complete, because the reasoner could not settle on a way to order it and gave up instead of returning a result.

  • Deploying a model that reads a relationship on a concept with a composite key now works. Before this release, the deploy could fail or the relationship could come back empty.

  • Deploying a model no longer fails when one of its output column names contains a hyphen, a space, or a reserved word. Before this release, the refresh stopped with an invalid identifier error.

  • Filtering by calling a relationship with a value, such as order.status("open"), now raises a clear AmbiguousRelationshipRead error when the name matches more than one relationship, and tells you to compare with == instead, as in order.status == "open". Before this release, it failed with a confusing internal error.

  • Deploying a model no longer prints warnings that did not mean anything was wrong. A warning still appears when you force an output to a Snowflake object type it cannot use, and tells you how to fix it: set the output to table or remove the override.

  • Redeploying a healthy model that sets deployment.suspend_after_mins no longer suspends the refresh tasks it just created, so the model keeps refreshing after a deploy. The tasks still auto-suspend once the configured number of minutes has passed since the deploy.

  • Deploying a model while someone is querying it no longer fails at the final step with an error asking you to pull and retry. Those queries write harmless background metadata that used to block the deploy, which now finishes on its own.

  • A deploy that is rejected before it applies its changes no longer leaves the model's schema behind in Snowflake for you to clean up, because RelationalAI now creates Snowflake objects only when the deploy goes ahead.

  • Deploying into a schema or with ownership tags that already exist now reuses them instead of failing to re-create them, and errors only if creating something genuinely fails.