Skip to content

Python API Release Notes

1.26.1

Python SDK


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

  • Your first rai models deploy on a new branch now works without a manual rai models pull first. rai models switch pulls the branch for you. A bare rai models pull also now defaults --path to the model.path in your raiconfig.yaml.

  • Tearing down a parent branch now removes its child branches too, instead of leaving them orphaned and unable to pull or merge. As a safeguard, rai models teardown --allow-children stops when a child has unmerged changes until you also pass --allow-unmerged. rai models list and rai doctor report now flag any branches orphaned by an earlier teardown.

  • The rai models commands now recognize when the schema you name is already your active model branch, instead of acting as if it changed. rai models switch no longer prints a false "Switched" message, rai models branch tells you to pick a different name instead of erroring, and rai models list marks your active schema with a *.

Bug Fixes

  • Fixed a bug that caused queries using union() to run slowly and, in some cases, hang indefinitely.

  • Fixed a bug that could cause aggregates grouped with per() to evaluate incorrectly when used solely as a filter and not selected in the query results.

Fixed a bug that caused aggregates grouped by an entity with a composite key to evaluate incorrectly.

  • Fixed an issue that could cause an "invalid identifier" error when deploying a model.

  • Fixed a bug that could case an "Object does not exist" error when deploying a model to a case-sensitive schema name.

  • Fixed a bug where a deploy could fail when a Snowflake view or dynamic table (an auto-refreshing Snowflake table) was created before another object it reads from.

  • Fixed a bug where deploying an unedited rai models init project could fail immediately with a "Symbol ... is already registered" error.

  • Fixed a bug that could cause redeploying a model without any changes could fail.

  • Fixed an issue that prevented model re-deploys from picking up changes to a data sources Snowflake object.

  • Fixed a model deployment bug that ignored a user-supplied Snowpark session passed to create_config(), which is supposed to override any auto-detected Snowpark session.

  • Fixed a bug that could cause rai models pull or rai models merge to generate a runnable shared_model.py file. If you encountered this bug, pull or merge again to regenerate a corrected shared_model.py.

1.26.0

Python SDK


Version 1.26.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 deploy a model from Python with model.deploy() as a programmatic alternative to the CLI. It relies on the operation log, which is off by default, so set oplog.enabled to true to turn it on.

  • If you run PyRel inside Snowpark Container Services (SPCS) and connect via OAuth, use the new host option in your Snowflake connection configuration to the container's SNOWFLAKE_HOST endpoint. OAuth tokens in your configuration are validated against this host.

  • You can now cap how long PyRel waits for a reasoner to become ready or a query to finish by setting data.poll_timeout_mins in your raiconfig to a number of minutes so it raises a clear timeout error instead of hanging forever. It is off by default and only stops your Python client, not any work already running in Snowflake.

  • If your Snowflake account cannot use hybrid tables, such as a Tri-Secret Secure account, you can now set oplog.table_type: standard in your raiconfig to provision the operation log as a standard table instead of the hybrid default. Note that changing this setting after your first deployment does not update the existing oplog table. You'll need to delete the table and re-deploy in order for it to take effect.

  • The product() aggregation function, which multiplies values together, is now supported in deployed models.

  • The rai debugger has a new Refresh Log view that shows a deployed model's install plan and refresh history as a diagram, so you can watch a refresh as it runs. You can also start it with --no-show to skip opening a browser window when you restart it.

  • PyRel now catches a conflicting implicit_properties setting when you deploy, branch, merge, or pull with the operation log enabled, raising ModelConfigMismatchError when your current setting differs from the one recorded at the model's deploy, instead of letting the conflict break the model later. This setting (part of ModelConfig) controls whether using an undeclared property creates it or raises an error. To resolve the error, match the recorded setting or pass --force to override and record the new one.

  • Improved performance for refreshing a deployed model.

  • Improved generated output table name in deployed models. For example, tables with generated names like Number_38_0_datapoints will now be saved as simply datapoints. If downstream queries or dashboards referenced the old name, update them after you redeploy.

  • Improved the error message you get when a deploy can't start because another is already in progress.

Bug Fixes

  • Fixed a model deployment bug where a model that used Model.Enum() failed to deploy with the errorValueError: No SQL type for column 'x'.

  • Fixed a bug where ranking or limiting rows over a concept with a composite key in a query or definition would fail with an invalid identifier error.

  • PyRel now internally sorts entities with composite keys differently than it used to. You may see results for queries that involve rank() or top() return rows where the rank is tied in a slightly different order.

  • Fixed a model deployment bug where calling re.findall() or strings.split() on a Table column produced extra rows in the output table.

  • Fixed a bug where a query computed two count(...).per(key) values over the same text key, one for values in a list and one for values not in it. The in-list count silently returned NULL on every row. Both counts now return the correct number.

  • Fixed a bug that caused some aggregations over properties that are set for some entities but not others to include values from entities that should have been excluded.

  • Fixed a model deployment issue that caused some models to fail with aSQL object_name collision error when deployed.

  • Fixed a bug where an unresolved chained reference in a query (a multi-step property or relationship lookup that was never given a value) could silently produce incorrect query results. PyRel now raises an error.

  • Fixed a bug in the prescriptive reasoner where a count or a summed objective (a total or a tally aggregated over rows) could silently drop rows that shared a value, so the solver optimized the wrong total. For example, with costs of 5, 5, and 7, the two 5s collapsed into one, giving 12*x instead of 17*x. Each row now contributes its own term.

  • The prescriptive reasoner now rejects a non-numeric value, such as a text or date property, used where a number is expected, with a clear error when you build the problem. Before, the problem built successfully and failed only during the solve, with a confusing internal error.

  • Fixed several problems with tearing down a deployed model using rai models teardown. Leftover local state could be wrongly reused on a later redeploy, and a partial teardown could not be completed by re-running it. Teardown now cleans up reliably and can be safely re-run after a partial failure.

  • Fixed a bug where rai models teardown and rai models merge could act on a malformed schema. Both commands now always reject a malformed or ambiguous schema name with a clear error.

1.25.0

Python SDK


Version 1.25.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 tear down a deployed model from Python with model.teardown(), which is the cleanup counterpart to model.deploy(), so you can remove a model you no longer need without leaving your script or notebook.

    Called with no arguments, model.teardown() only shows what it would remove and deletes nothing. When you pass force=True, the call actually performs the teardown. This drops the model's deployed schema in Snowflake, along with its meta schema and operation log, which is the same thing the rai models teardown CLI command does:

    model.teardown()            # preview: lists what would be dropped, drops nothing
    model.teardown(force=True)  # drop the deployed model for real
    

    Teardown cannot be undone, so check the preview before you use force=True. Your local model files, including the generated shared_model.py, are left in place.

  • Running rai doctor report now shows which shared_model.py file it used, as a new "Shared model file" entry in the report summary. This lets you confirm PyRel picked up the file you expected, which matters when a stray copy in a parent directory could otherwise be used without you noticing.

Bug Fixes

  • Fixed a bug where a query that placed a union(...) next to another filter in the same where(...) could return incorrect results.

    For example, the status == "open" filter below was ignored for one region, so results could include orders that were not open. The filter now applies to both branches of the union:

    where(
        Order.status == "open",
        union(Order.region == "US", Order.region == "EU"),
    ).select(Order.id).to_df()
    
  • Fixed a bug that could cause an "invalid identifier" error when you deployed a model to Snowflake.

  • Fixed a bug that could crash Snowflake's SQL compiler with an out-of-memory error when deploying a model.

  • Fixed a bug that caused a Snowflake "invalid regular expression" or "named groups not supported" error when calling re.sub, re.search, or re.match on certain patterns, such as re.sub(r"\D", "", text).

  • Reading table rows into a concept no longer exposes the internal __row_id_* fields it uses to tell identical rows apart. They previously appeared as public properties when you inspected your model, and are now kept internal.

  • When rai models deploy fails, you now see a short, readable error message instead of a long Python traceback. It also exits with a nonzero exit code, so scripts and CI pipelines can detect the failure and stop instead of continuing as if the deploy worked. This also applies to --wait, which is the option that keeps the command running until the deploy finishes.

  • The first deploy of a large model no longer fails with an OplogAppendTooLargeError, which used to stop the deploy with no way around it when it needed to write more than about 900 KB at once to the model's operation log. The operation log is the running record of changes PyRel keeps for a deployed model. The deploy now completes with no change to your model.

  • A model no longer fails to deploy with an [Unground Variable] error when a concept is identified by both a reference to another concept and a plain-value field from the same source table, for example a LineItem identified by its Order and a line number.

  • Running rai models pull more than once on a shared live branch, one that several people deploy to and pull from, now gives consistent results. Before, a second pull could quietly change the model definition you ended up with, so collaborators could drift out of sync. To get the fix, upgrade every collaborator to 1.25.0 before anyone runs the first pull, because afterward an older version of PyRel can no longer write to that branch.

  • In the rai debugger, you can now expand a compiler pass for one block of a deployed model without the same pass opening in every other block, so the view stays focused on the block you are inspecting.

1.24.0

Python SDK


Version 1.24.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 warns you when your raiconfig.yaml file contains a key it doesn't recognize, so a typo no longer passes unnoticed. For example, misspelling account as accont raises a warning that names the unknown key and suggests the closest valid one. Valid configuration produces no warnings, and existing files keep working because this is a warning, not an error.

  • The inspect module for examining a model's concepts, relationships, tables, enums, and definitions without an engine connection is now included in the API reference. The module shipped in an earlier release. This change makes its documentation discoverable on the docs site and in your IDE.

  • The spcs_privatelink_zone connection option is now documented and included as a commented setting in the rai init config template. Set it when you enable Direct Access on a Snowflake PrivateLink account. Omit the leading wildcard from that value.

  • The rai debugger now groups a deployed model's compiler passes by block, instead of showing one flat list, so you can tell blocks apart and compare the same pass across them. A new Group by pass toggle flips the view to show every block nested under each pass.

Bug Fixes

  • Queries now run in Snowflake Workspace notebooks instead of crashing. Before this release, any query in that environment failed with OSError: [Errno 95] Operation not supported because PyRel tried to write its trace and log files to the notebook's locked-down filesystem. Queries now run and return results there with no configuration needed.

  • Models that use model.Enum(...) to map a messy raw column onto a fixed set of allowed values now deploy to Snowflake and refresh correctly. This is a common data-cleaning pattern, but on versions 1.22.0 and 1.23.0 it failed to deploy. The only workaround was to drop the enum and store the value in a plain string property instead, which gave up both the fixed set of allowed values and the type safety it provides. That workaround is no longer needed.

    For example, the model below defines a Region enum, then tags every site whose raw region text matches a known spelling with the canonical Region.Americas value:

    Region = model.Enum("Region", ["Americas", "EMEA", "APAC"])
    Site.region = model.Property(f"{Site} has region {Region}")
    
    # Sites whose raw region text is one of these spellings become Region.Americas.
    model.where(Site.region_raw.in_(["amer", "americas", "north america"])).define(
        Site.region(Region.Americas)
    )
    

    You would add a similar definition for EMEA and APAC. On 1.22.0 and 1.23.0 this model failed to deploy to Snowflake, but it now deploys and refreshes cleanly.

  • A composite-key entity is one identified by more than one key. When your model is deployed to Snowflake, PyRel now builds faster, simpler SQL for reading several properties of such an entity. This is SQL that PyRel generates itself, both when it deploys or refreshes your model. It used to re-read the entity's table once for every property, which was slower. Single-key entities are unaffected.

  • When a definition sets a property whose value is a composite-key entity, that property's values are now saved correctly when the model is deployed to Snowflake and refreshed. For example, a property might link each product to its supplier, where a supplier is identified by a company name and a country. Before this release, the refresh reported success but silently dropped rows, so a definition that later read the property saw incomplete data.

  • Setting a property on an entity that is identified partly by another composite-key entity now works as expected when the model is deployed to Snowflake, instead of failing with a NotImplementedError. For example, a shipment might be identified by a date and a route, where the route is itself identified by two cities.

  • Reading a property that points from one entity to another no longer adds an all-NULL row for entities that have no value when the model is deployed to Snowflake. For example, if a property links each employee to their manager, an employee with no manager is now left out instead of appearing as a blank row.

  • Defining a table source from a schema that lists two keys that name the same physical Snowflake column now behaves predictably. Snowflake treats names like a and A as one column, so PyRel collapses the two keys into one column when they share a type, or raises a clear error when their types differ, instead of silently adding a phantom column to the Table object.

  • Refreshing a deployed model that reads from a Snowflake source table whose name requires quoting now succeeds instead of failing during refresh. This includes names with a space, like DB.SCHEMA."SOURCE B".

  • rai models pull on a live branch now rejects a merge that would create a cycle in column types with a clear ConflictError that names the cycle, instead of quietly producing a broken model that fails later. Such a cycle happens when, for example, table T1 is typed by T2 while T2 is typed by T1.

  • Redeploying a model with rai models deploy is more reliable: a model containing two identical definitions no longer fails to deploy, and annotations on a newly added concept or relation now apply on the first deploy. Reordering definitions, and concepts that extend a built-in type, also no longer produce spurious changes on redeploy.

  • Recovering an interrupted model merge is now reliable: re-running a merge after a conflict no longer duplicates concepts already promoted to the parent, the resume information survives an intervening pull or deploy, and model status now shows when a merge is mid-recovery.

  • The error message shown when your shared_model.py file has been edited since the last pull or deploy now accurately describes what --force does: it pushes your local edits to the shared model and regenerates the file while keeping a backup, rather than discarding your edits.

  • Branch safeguard messages during a pull now distinguish a missing sync baseline from a branch that is genuinely behind, report the actual synchronized position, and make clear that a pull with no model changes still updates your local state.

  • rai doctor report now includes your model's local-state directory in the diagnostic bundle when your connection sets rai_app_name but no explicit database, instead of leaving it out.

  • Direct Access connections that use JWT-based key-pair authentication now automatically retry when the app's service endpoint becomes stale during token exchange, so the connection can recover on its own.

  • Regenerating a shared model through a pull, merge, or deploy now preserves DECIMAL and other number column types, instead of demoting them to a plain concept.

1.23.1

Python SDK


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

  • A new project you create with rai models init now deploys to Snowflake without you having to add a refresh schedule by hand. Before this release, rai models deploy failed on a brand-new project with an Unscheduled Outputs error, because the generated raiconfig.yaml didn't say how often to refresh the deployed tables and views. The config now includes a default refresh schedule with interval_s: 0, which refreshes the outputs each time you deploy but not on a fixed interval, so the deploy succeeds.

Bug Fixes

  • If you haven't filled in your Snowflake connection details yet, PyRel now stops with a clear error message naming the values you need to fill in, instead of a confusing raw Snowflake error. For example, a new project's raiconfig.yaml might still have the placeholder account: myorg-myaccount. PyRel runs this check the first time it opens a Snowflake connection, so you see the message early, whether you run a script, run a query, or deploy your model.

  • The rai debugger can now open the logs from large programs without freezing. The debugger also has a new Collapse all button that closes every open section at once, and opening one section no longer expands the other sections with the same name.

  • Pulling or merging a shared model now correctly rebuilds models that earlier releases could rebuild incorrectly. When you run rai models pull or rai models merge, PyRel regenerates the shared model's code from your team's changes. Before this release, pull and merging a shared a model could sometimes result in models that failed to build.

  • You can now call solve() again on the same prescriptive Problem while asking for fewer of its optional sensitivity and conflict results. Before this release, re-solving without a sensitivity or conflict result you had requested earlier raised an error. Now the re-solve succeeds. On current RelationalAI platform versions, it also clears the results you no longer request, so you don't see stale numbers from an earlier solve. You still can't switch between a plain solve and a sensitivity or conflict solve on the same Problem. Create a new Problem for that.