0.9.4#
Released on February 28, 2025.
Distribution#
The name QuerySession
, unused since 0.9.0, makes a come back in this release but, this time, with a different meaning.
QuerySession
becomes the entry point to create clusters of Atoti applications [6].
atoti.Cube.restrictions
has been introduced to secure query sessions.
For the sake of symmetry, atoti.Session.security.restrictions
has moved to atoti.tables.Tables.restrictions
(the old location remains available but is deprecated).
Performance#
Client/server communication#
Most components of Session
are exposed through mappings such as Cubes
or Tables
.
As a project grows, a lot of mapping lookups will be made to iteratively define the data model or to pass arguments to methods such as atoti.Cube.query()
.
For instance, the following code will make 3 lookups:
new_measure = tt.agg.sum(
m["Foo.SUM"], # 1
scope=tt.OriginScope({
l["Bar"], # 2
l["Baz"], # 3
})
)
Each lookup makes a request to the server to check that the key exists.
This is pretty quick but, when thousands of lookups are made, this client/server communication can add up.
mapping_lookup()
allows skipping these server requests.
Cube queries#
The aggregate cache of a cube can be restricted to a subset of measures [3].
This improvement comes with a new atoti.Cube.aggregate_cache
API deprecating the previous atoti.Cube.aggregates_cache
(with an “s”) one:
- cube.aggregates_cache.capacity = 200
+ cube.aggregate_cache = tt.AggregateCache(capacity=200)
- cube.aggregates_cache.capacity = -1
+ del cube.aggregate_cache
Hierarchy creation#
Creating hierarchies from columns of a table fully joined (i.e. all their keys are mapped) to the cube’s fact table do not require “rebuilding” the cube anymore [4]. This means that no time will be lost reindexing hierarchies or performing other expensive computations.
Data modeling#
Measures#
atoti.where()
was not respecting the order of condition_to_value when the same value was assigned to multiple conditions [2].
For example, in:
m["8"] = 8
m["Test"] = tt.where(
{
m["8"] < 5: -1, # False
m["8"] >= 5: 1, # True
m["8"] < 10: -1, # True
},
default=0,
)
Test was equal to -1
because the first and last conditions, being both assigned to the same value, were merged together and that merged condition became the first one evaluating to True
.
This incorrect merging of conditions has been removed: m["8"] >= 5
is correctly detected as the first condition evaluating to True
and so Test is equal to 1
.
Table columns#
Columns with an arrray data type can be made non-nullable.
atoti.Column.default_value
’s documentation has been updated accordingly.
Data loading#
Transactions#
data_transaction()
’s tables parameter allows some data transactions to execute concurrently [1].
CSV#
The atoti.CsvLoad.true_values
and atoti.CsvLoad.false_values
attributes can be configured to parse more values than "True"
, "true"
, "False"
, and "false"
as "boolean"
[5].
Dependencies#
Internal issue tracker references