0.8.38
New Features and Enhancements
Section titled “New Features and Enhancements”- Minor improvements to performance and stability.
Stay updated with the latest changes and improvements in our Python API.
rai init
CLI command that caused it to fail when saving the configuration file with the error [Errno 2] No such file or directory: ''
.
DATETIME
columns in their result set to return empty results when called.
Added the data_freshness_mins
configuration key, supported in both raiconfig.toml
and Config
objects.
This key sets the maximum allowed staleness (in minutes) for Snowflake table data used by the model. If the data is older, the corresponding data stream is synced on the next query, with a spinner shown in notebooks and REPLs while the new data is prepared for the model.
UninitializedPropertyException
error message. The word “rename” was misspelled as “ranamed.”
Fixed a bug in the imports:list
CLI command that failed to report quarantined streams in certain cases.
The command now correctly displays quarantined streams in the output.
Fixed a bug when using relationalai
in a Snowflake notebook that failed to fall back to the configured Snowflake role if no role was specified in current Snowflake session.
Fixed a bug in the Uninitialized property
error message that would display the same property name multiple times if it was used in multiple places in the program.
The error message now shows the property name only once.
Updated the click
dependency for the CLI to version <=8.1.8
to avoid compatibility issues.
To make sure you have the correct version of click
installed, reinstall the relationalai
library with the following command:
python -m pip install --upgrade --force-reinstall --upgrade-strategy eager relationalai
Columns in source Snowflake tables or views with names that begin with an underscore (_
) are now supported.
The properties generated by these columns are prefixed with col
.
For example, if your source table as a column named _id, the generated property is named
col_id`.
If you select a property that begins with an underscore in a query, a warning is raised to inform you that the column was renamed.
save_config()
.
Fixed a bug with the progress spinners shown in notebooks and the terminal that caused RAI engine status updates to be hidden. The spinners now correctly show the status of the configured RAI engine.
Fixed a bug with properties automatically created from columns of Snowflake tables or views that caused the column name to be imported incorrectly if the name contained special characters.
Improved support for Snowflake notebooks.
When using a Snowflake notebook, the Model
constructor now automatically picks up your Snowflake session so that you don’t need to explicitly provide those values or manually get the session and pass it to the constructor:
# NEW
import relationalai as rai
# The session is automatically picked up from the Snowflake notebook, so the# following creates a model using the current session and the default RAI# configuration values.model = rai.Model("MyModel")
Previously, you needed to import the snowflake.snowpark
package and manually get the session:
# OLD
import relationalai as raifrom snowflake.snowpark.context import get_active_session
session = get_active_session()model = rai.Model("MyModel", connection=session)
Fixed a bug in exported stored procedures that could cause source data to be unavailable to the stored procedure.
Fixed a bug that caused properties automatically created from Snowflake tables or views to be multi-valued instead of single-valued.
Improved the error message that sometimes appears when a RAI program is executed against an engine that is outdated.
The error message used to suggest that the user run the api.update_libraries()
SQL command, which is deprecated.
Now, the error message suggests passing use_package_manager=True
to the Model
constructor to automatically update the libraries used by the model.
Note that use_package_manager
is set to True
by default, so this situation should only occur in practice if you’ve explicitly set it to False
in the past.
Changed our package dependencies to ensure the snowflake-snowpark-python
has a minimum version of 1.30.0
in order to avoid a thread-safety issue that could potentially cause queries to return the wrong results.
To upgrade your package and ensure that you have not only the latest version of relationalai
but also a compatible version of snowflake-snowpark-python
, run the following command:
pip install --upgrade --force-reinstall --upgrade-strategy eager relationalai8 ```
Fixed a typo in the SnowflakeImportMissingException
error message that incorrectly suggested using the rai imports:create
CLI command, which doesn’t exist.
The error now correctly suggest using the rai imports:stream
command.
Minor improvements to performance and stability.
Added the ability to set the name of an exported stored procedure by passing a fully-qualified name to the Model.export()
decorator.
For example:
# Export a stored procedure name `my_db.my_schema.my_procedure`.@model.export('my_db.my_schema.my_procedure')def foo(): # Your procedure code here pass
# When the decorator argument only specifies the db and schema, the procedure# name is set to the function name, so the following exports a stored procedure# named `my_db.my_schema.foo`.@model.export('my_db.my_schema')def foo(): # Your procedure code here pass
Fixed a bug that sometimes cause UninitializedPropertyException
errors in exported stored procedures for properties with names that begin with graphlib
.
Fixed a bug that sometimes caused rai init
to fail generate a raiconfig.toml
file with appropriate default values.
trying to auto-create the engine and we failed
or Failed to connect to DB
.
Now, the error message tells you which required configuration keys are missing.Fixed a bug that sometimes caused exported stored procedures to fail with an UninitializedPropertyException
with several properties whose names begin with graphlib
were uninitialized.
Fixed a bug that prevented missing configuration keys in a Config
object from falling back to values in a raiconfig.toml
file.
Uninitialized property
errors when using Snowflake tables or views with primary and foreign key constraints in their schema as the source of a Type
object.
Added support for fully-qualified named with double quotes in the Model.export()
method.
For example, the following code exports a stored procedure named my_db.my_schema."my procedure"
:
@model.export('my_db."my_schema"')def my_procedure(): # Your procedure code here pass
Added support for Snowflake tables and views whose names contain double quotes when passing the fully-qualified name to the Type
constructor’s source
parameter.
For example, the following code creates a Type
object with entities sourced from a table named my_db.my_schema."my table"
:
MyType = Type("MyType", source='my_db.my_schema."my table"')
Improved the error message that sometimes appears when a query cannot be decrypted because the cryptography
library is not installed.
Previously, the error message was:
library `cryptography.hazmat` missing; please install
Now, the error message is:
Please open the navigation-bar dropdown labeled *Packages* and select `cryptography` under the *Anaconda Packages* section, and then re-run your query.
Fixed a bug that caused some queries to fail with the error AttributeError: Row object has no attribute data_type
.
Other minor bug fixes.
Improved the error message displayed when a property is used as both a single-valued and multi-valued property.
Previously, the error message was:
Trying to use a property 'property_name' as both singular and multi-valued.
Now, the error message is:
Trying to use a property 'property_name' as both singular and multi-valued. This often happens when multiple types have a property with the same name, but one is single-valued and the other is multi-valued. See https://relational.ai/build/guides/core-concepts#setting-object-properties for more information.
Type
was queried prior to being used in any rule.
Graph visualizations are now supported in Snowflake notebooks!
To display a graph visualization in a Snowflake notebook, call Graph.visualize()
chained with .display(inline=True)
:
my_graph.visualize().display(inline=True)
Added a new days_to_int()
function to the std.dates
module that converts a period of days
to an integer.
This is useful when you need to convert the difference of two dates to an integer so that you can do arithmetic with it:
import relationalai as raifrom relationalai.std.dates import date, days_to_int
InstanceProperty.choose()
.
This could cause incorrect values to be included in query results.
Type.add()
method.
cryptography
dependency version to allow for more flexibility in the versions of cryptography
that can be used with the RAI Python API.ensure_change_tracking
was set to True
in the Model
constructor.
FilterAsValue
error to incorrectly raised in Snowflake notebooks.
InvalidLoop
warnings in Jupyter Notebooks that suggest the user add dynamic=True
to their model.query()
call, even though dynamic=True
was already present.
The warnings are no longer generated.
Fixed a bug that prevented properties with decimal numeric values from being used in graph visualizations.
For example, using a property with a decimal value as an edge label would cause the visualization to fail with the error TypeError: Object of type Decimal is not JSON serializable
.
Now, properties with decimal values are serialized as floats before being used in the visualization.
Fixed a bug that prevented errors and warning from being displayed with calling the Graph.fetch()
and Graph.visualize()
methods.
Now, errors and warnings are displayed as expected.
Fixed a bug that allowed SQL stored procedures created with the Model.export()
decorator to be executed using the CDC engine.
Now, these procedures can only be executed using user engines.
Refer to the Engine Selection section of the Model.export()
documentation for more information on which engines are used exported procedures.
Removed the requirement to specify return value type hints in functions wrapped with the Model.export()
decorator.
This simplifies creating stored procedures with a large number of output columns.
For example:
# Old syntax:@model.export("sandbox.public")def get_adults_by_age(age: int) -> Tuple[str, int]: # <-- Return type hints adult = Adult(age=age) return adult.name, adult.age
# New syntax:@model.export("sandbox.public")def get_adults_by_age(age: int) # <-- No return type hints adult = Adult(age=age) return adult.name, adult.age
Removed the engine creation step from the rai init
command.
This change simplifies the initialization process by removing an unnecessary step, since engines are automatically created for each user when they run their first query.
Improved error messages for queries that get aborted, either by a user cancelling the transaction or from some other issue. The error message is formatted more clearly and includes the reason that the transaction was aborted.
debug.jsonl
file to be created even if the debug
configuration key was set to false
.
Now, debug.jsonl
is only written to when the debug
key is set to true
.
.louvain()
method now raises a DirectedGraphNotSupported
exception instead of a DirectedGraphNotApplicable
exception when called from a directed graph.Made improvements to the RAI debugger:
Made significant improvements to general query performance.
Improved the error message for the .eigenvector_centrality()
method when called from a directed graph.
The message now suggests using .pagerank()
instead, which is supported for directed graphs.
Introduced an experimental solver library for optimization workloads. This library is not yet documented and is subject to frequent and unannounced API changes. If you would like to try out this feature, please contact customer support at support@relational.ai.
weight
property.
Now, edges without the weight
property are assigned the default_weight
value specified in the Graph
constructor.
You may use the new rai engines:suspend CLI command to manually suspend an engine from the RAI CLI.
For example, the following suspends an engine named my_engine
:
rai engines:suspend --name my_engine
See Engine Suspension for more information.
Version information is now displayed in the RAI CLI help menu next to the welcome message:
$ rai
--------------------------------------------------
Welcome to RelationalAI (0.7.3)
rai [options] command
--profile - which config profile to use (default: default)
init - Initialize a new project version - Print version info debugger - Open the RAI debugger
...
Additionally, messages about new versions of the RAI Python API are displayed in help for all commands whenever a new version is available.
Added an option to the interactive rai init CLI command to specify the engine size when configuring your RAI engine.
Prior to this release, the engine size was automatically set to the default value specified by the engine_size
key in your raiconfig.toml
file, or HIGHMEM_X64_S
if the key was missing or you do not have a raiconfig.toml
file.
Now, the configured default value is selected but can specify a different engine size during initialization.
Added a new wait_for_stream_sync
configuration key to the raiconfig.toml
file that allows you to specify whether to wait for a data stream to synchronize before executing a query.
The default value is true
, which means that queries will wait for change tracking data to be processed before executing.
If you set the value to false
, the query will execute immediately but the results may not reflect the most recent changes to the source data.
Made several improvements to the RAI debugger:
Added support for loading debug.jsonl
files exported during one RAI debugger session into a new debugger session by dragging and dropping the file into the debugger UI.
Added a settings option to strip sensitive data, such as result set samples, from exported data. This is turned on by default and can be disabled using the toggle switch in the settings menu by clicking on the gear icon in the top right-hand corner of the debugger UI.
Improved logging output when exporting a debug.jsonl
file to enable better support when sharing the file with RAI.
Improved the error message when creating a stream using rai imports:stream
when the model specified in the --model
parameter does not exist.
The error message now includes instructions for creating the model:
--- Model 'MyModel' not found ------------------------------
The model 'MyModel' does not exist. You can create it byrunning a program containing the following:
model = relationalai.Model("MyModel")
-------------------------------------------------------------
rai imports:delete
would report Error deleting import: engine is suspended
even though the import was successfully deleted.
You may now resume suspended engines from the RAI CLI using the new rai engines:resume
command.
For example, the following resumes an engine named my_engine
:
rai engines:resume --name my_engine
You may now specify the --auto_suspend_mins
option when creating an engine with the rai engines:create
CLI command.
For example, the following creates an engine named my_engine
that auto-suspends after 30 minutes of inactivity:
rai engines:create --name my_engine --size HIGHMEM_X64_S --auto_suspend_mins 30
Note that the --auto_suspend_mins
parameter is optional and defaults to 60
minutes.
If your raiconfig.toml
file contains an auto_suspend_mins
key, the value of that key will be used as the default.
Error reporting for queries with the format="snowpark"
option has been improved.
All errors are now reported.
Previously, some errors were suppressed.
Error messages for multi-factor authentication issues have been improved to provide more context, such as when a connection fails due to Duo security settings.
A new experimental
module has been added that contains experimental features:
The experimental.inspect.watch()
function may be used to do “print debugging” of expressions in a rule or query.
For example:
import relationalai as raifrom relationalai.std import aggregatesfrom relationalai.experimental.inspect import watch
model = rai.Model("MyModel")Person = model.Type("Person")Adult = model.Type("Adult")
with model.rule(): Person.add(id=1).set(name="Jane", age=12) Person.add(id=2).set(name="John", age=21)
with model.rule(): person = Person() person.age >= 18 # Print "is adult" with the person's name and age # when the rule is evaluated. watch("is adult", person, person.name, person.age) person.set(Adult)
with model.query() as select: adult = Adult() num_adults = aggregates.count(adult) response = select(num_adults)
print(response.results)
The above program produces the following output:
v1 v2 v3 v40 is adult g4rDjPY1HHWkEikWQXw+3Q John 21
result0 1
Note that a query that triggers the rule containing the watch()
function must be executed in order to see the output.
The experimental.paths
module contains functions and classes for finding and working with paths in a graph.
If you would like to try out this feature, please contact support at support@relational.ai.
Documentation for features in experimental
is coming soon.
@export()
to contain multiple return
statements.Fixed a bug that prevented you from using names of aggregation functions, like count
, min
, or max
, as property names for entities in a model.
Fixed a bug that caused an engine’s auto_suspend_mins
setting to be reset to 60
minutes after being auto-resumed.
Fixed a bug that made it impossible to export a SQL stored procedure if the query produced a column with only NULL
values.
Fixed several bugs in the RAI debugger:
Fixed a bug that occasionally caused ConnectionResetError: Cannot write to closing transport
errors.
Fixed a bug that caused the wrong Python code to be displayed when viewing a model’s rules.
Fixed a bug that prevented profiling stats from updating while a query is executing.
too many values to unpack
error when setting format="snowpark"
in a Model.query()
context.
The save_config()
function now returns None
instead of a string with the full TOML file contents. This prevents sensitive information from being displayed in notebook and REPL outputs.
You will now see a warning message when initializing a model if an engine with the same name as the engine
configuration key exists but has a different size than the one specified by the engine_size
key.
To silence this warning, you may do one of the following:
engine_size
configuration key from your configuration.engine_size
to match the size of the existing engine.The operation for fetching query results from the RAI Native App is now automatically retried on failure due to a transient error.
imports:list
CLI command now displays the status Not Available
instead of throwing an error if an import’s STATUS
field is null.
Snowflake Notebooks on Container Runtime are now supported! Container Notebooks offer a more flexible environment than Warehouse Notebooks:
You can install the relationalai
package using pip install relationalai
instead of uploading the package as a ZIP file.
This requires enabling an external access integration for PyPI, and lets you install other third-party packages, as well.
ZIP file uploads are still supported if you do not want to enable external access to PyPI.
You do not need to enable external access integration for downloading query results to the notebook, like you do for Warehouse Notebooks.
Data streams are now automatically created for you on Snowflake tables and views passed to the source
parameter of the model.Type()
constructor.
Existing data streams will be recreated the first time you query a model using 0.6.0
.
See Migrating Models to 0.6.0
for more information.
You can set the new ensure_change_tracking
configuration key to automatically enable change tracking on tables or views passed to the model.Type()
constructor’s source
parameter.
The default value is False
, which means that table and view owners must manually enable change tracking on their objects.
Engines auto-created by the Python API are configured by default to suspend after 60 minutes of inactivity.
You can override this default by specifying the auto_suspend_mins
configuration key in your raiconfig.toml
file.
Suspended engines are automatically resumed when Python queries are executed.
See Engine Suspension for more information on suspended engines.
A convenience function save_config()
has been added for creating a raiconfig.toml
file from a notebook environment.
The Graph.visualize()
function now throws an UnsupportedVisualizationError
if called in an environment, like a Snowflake notebook, that does not support visualization.
Fixes a bug that caused an UninitializedPropertyException
to be thrown when a type that has never been added to is queried.
Fixes a bug that displayed the message Failed to connect to ws://0.0.0.0:8080/ws/program. Running with debug sink disabled.
when the RAI debugger is not running.
Several methods of the graphs.Compute
class have been changed or removed:
.is_triangle()
no longer returns an Expression
object that produces True
or False
values.
Instead, it filters arguments for combinations of three nodes that form a triangle.
This behavior is consistent with how other functions, like .is_reachable()
, work.
.louvain()
now throws a DirectedGraphNotApplicable
error if called from a directed graph.
The default values for the max_levels
and max_sweeps
parameters of the .louvain()
and .infomap()
methods have been changed:
max_levels
has changed from 4
to 1
.max_sweeps
has changed from 8
to 20
.You may now call the following methods from a weighted graph:
Previously, these returned empty results for weighted graphs. Because they now support weighted graphs, the following methods have been removed:
.weighted_cosine_similarity()
.weighted_degree_centrality()
.weighted_distance()
.weighted_jaccard_similarity()
Methods for computing degree statistics have been removed:
.avg_degree()
.avg_indegree()
.avg_outdegree()
.max_degree()
.max_indegree()
.max_outdegree()
.min_degree()
.min_indegree()
.min_outdegree()
You can compute these statistics using the .degree()
method and an aggregation function:
from relationalai.std import aggregates
def avg_degree(graph): node = graph.Node() degree = graph.compute.degree(node) return aggregates.avg(degree)
Internal node hashes for graphs are now stable. Algorithms sensitive to node order will now produce consistent results across different runs.
All output fields for the rai imports:setup
CLI command are now displayed in snake_case
.
Previously, some were displayed in camelCase
while others were displayed in snake_case
.
The --pool
parameter for the rai engines:create
CLI command has been removed.
Engine compute pools are fully managed by the RAI Native App.
0.6.0
The first time you query an existing model after upgrading to 0.6.0
, data streams used by the model will be recreated.
New data streams appear in the api.data_streams
view with a RAI_DATABASE
column containing the name pyrel_root_db
.
Once the new data streams are created, you can safely delete the old data streams using the api.delete_data_stream()
procedure by passing your model’s name and the fully-qualified name of the table or view associated with the old data stream.
CALL relationalai.api.delete_data_stream('my_model', '<db>.<schema>.<table_or_view>');