0.9.5#
Released on April 4, 2025.
Security#
SSO#
The atoti.KerberosConfig.username_case_conversion and atoti.LdapConfig.username_case_conversion attributes have been added to coerce the name of users logging in to the expected case [1].
Not picking a case conversion is a source of confusion or bugs so leaving these attributes unset will raise a deprecation warning.
Database access#
atoti.tables.Tables.owners and atoti.tables.Tables.readers have been added [2].
Their impact is not limited to the Python API.
For instance, atoti.tables.Tables.readers will also control whether end users are able to see tables in Atoti Admin UI Database tab.
Dependencies#
Fixed#
Data loading#
Cloud storage#
On Windows, passing a URL to atoti.CsvLoad.path or atoti.ParquetLoad.path raised an InvalidPathException [6].
Data modeling#
Conditions#
Creating logical conditions (i.e. boolean combinations of leaf conditions such as (level["Product"] == "Phone") | (level["Country"] == "Portugal")) with more than 508 leaves raised a ValidationError because it reached the maximum nesting depth supported by the runtime type checker [7].
This was fixed by allowing the internal representation of a logical condition to group more than 2 operands.
For example, (a & b) | c | d | f | g (with a maximum depth of 2) replaces the old internal representation (((a & b) | c) | (d | f)) | g (with a maximum depth of 4).
Table columns#
Columns are strictly typed: a column with a "LocalDate" data_type can only store dates (or None if its default_value is None); it cannot store a "String" such as "NaN".
Since Java has no equivalent of pandas.NaT, the only available values to represent a special null-restricted:
"LocalDate"areLocalDate.MINandLocalDate.MAX,"LocalDateTime"areLocalDateTime.MINandLocalDateTime.MAX.
However, accessing default_value when it was set to one of these values raised a ValidationError [3].
This is fixed.
Measures#
The type annotation of
filter()’s filter parameter never allowed invertedatoti.Level.isin()conditions (e.g.~level.isin("foo", "bar")) but, by chance, these conditions actually behaved as expected at runtime.However, 0.9.4 introduced runtime validation of condition types which lead to the rejection of these conditions. This regression is fixed: the type annotation of filter accepts these conditions and they are supported at runtime [4].
Passing
isnullconditions toatoti.where()raised anUnknownUnderlyingMeasureRuntimeException[5].
Internal issue tracker references