What's New in Version 1.18.0
Version 1.18.0 of the relationalai Python package is now available!
To upgrade, activate your virtual environment and run the following command:
pip install --upgrade relationalaiNew Features and Enhancements
Section titled “New Features and Enhancements”-
rai doctor reportnow generates a deterministicdiagnosis.mdsummary and shows the same diagnosis in the debugger report browser. Before 1.18.0, you had to inspect the collected artifacts yourself to identify likely configuration, Snowflake, deploy, schema-cache, trace, or collection problems. -
PyRel now fails fast on undefined config references instead of ignoring them or failing later at runtime. For example, a typo in
active_profilesuch asactive_profile: localmnow raises a clear validation error during config loading.
Bug Fixes
Section titled “Bug Fixes”-
Fixed
math.clip()so it returns the clipped value instead ofNULLwhen the input falls below, within, or above the requested bounds. -
Fixed how reasoner names are generated. If you don’t set custom reasoner names in your configuration, provisioning could previously fail when your username starts with a digit because the generated reasoner name was invalid. PyRel now sanitizes the generated name automatically, for example by turning
12345intouser_12345. -
Fixed nested
select()values insideunionand match branches, and fixed aggregates over scalar subquery values, so those query shapes return the expected rows instead of raising internal compiler or validation errors. -
Fixed
rank()queries that also return a related value in the same result. Those queries now return the expected table and useNULLwhen the related value is missing instead of failing validation. -
PyRel now raises an
Ambiguous concept usageerror when one rule reuses the same concept name as both a variable and a concept type in the same line. For example, the following code now raises an error instead of silently misinterpreting the second line:from relationalai.semantics import Model, Stringm = Model("ambiguous")A = m.Concept("A")B = m.Concept("B", extends=[A])C = m.Concept("C", extends=[A])D = m.Concept("D", extends=[B, C])A.id = m.Property(f"{A} is identified by {String}")A.identify_by(A.id)m.define(A.new(m.data([{"id": "w"},{"id": "x"},{"id": "y"},{"id": "z"},]).to_schema()))m.define(B(A)).where(A.id.in_(["w", "x", "z"]))m.define(C(A)).where(A.id.in_(["w", "y", "z"]))# Unambiguous: B is a variable in both places.m.define(D(B)).where(C(B))# Ambiguous: B is variable in D(B) but a concept type in B(C).m.define(D(B)).where(B(C)) # now raises "Ambiguous concept usage"Previously, PyRel would silently define every entity of type
Bas aDin this case because the type expressionB(C)doesn’t constrain the variableBin.define()in any way.