atoti.Session.data_model_transaction()#

Session.data_model_transaction(*, allow_nested=True)#

Create a data model transaction to batch multiple data model changes.

Start the transaction with a with statement. The changes will be visible from other clients (e.g. Atoti UI) once the transaction is closed.

Data model transactions offer “read-your-writes” behavior: changes made inside the transaction are visible to the following statements.

Note

Data model transactions cannot be mixed with data loading operations.

Attention

Data model transactions are work in progress:

  • atomicity and isolation are not guaranteed yet;

  • only measure-related changes are supported for now.

Parameters:

allow_nested (bool) –

Whether to allow starting this transaction inside an already running one.

When False, an error will be raised if this transaction is started while another transaction is already running, regardless of that outer transaction’s value of allow_nested. The benefit of passing False is that changes made in this transaction are guaranteed, if not rolled back, to be visible to the statements outside the transaction. The drawback is that it prevents splitting transaction steps in small composable functions.

When nested transactions are allowed, changes made by inner transactions contribute transparently to the outer transaction.

Return type:

AbstractContextManager[None]

Example

>>> fact_table = session.create_table(
...     "Base",
...     keys={"ID"},
...     types={"ID": "String", "Quantity": "int"},
... )
>>> cube = session.create_cube(fact_table)
>>> h, l, m = cube.hierarchies, cube.levels, cube.measures
>>> with session.data_model_transaction():
...     m["Quantity - 1"] = m["Quantity.SUM"] - 1
...
...     m["Quantity + 1"] = m["Quantity.SUM"] + 1
...     m["Quantity + 1"].description = "Just slightly off"
...     m["Quantity + 1"].folder = "Test"
...
...     m["Quantity + 2"] = m["Quantity + 1"] + 1
...     m["Quantity + 2"].formatter = "INT[# ###]"
>>> fact_table += ("123xyz", 1)
>>> cube.query(
...     m["Quantity.SUM"],
...     m["Quantity - 1"],
...     m["Quantity + 1"],
...     m["Quantity + 2"],
... )
  Quantity.SUM Quantity - 1 Quantity + 1 Quantity + 2
0            1            0            2           3

With nested transactions allowed:

>>> def add_foo(cube_name, /, *, session):
...     cube = session.cubes[cube_name]
...     m = cube.measures
...     with session.data_model_transaction():
...         m["foo"] = 2_000
...         m["foo"].formatter = "INT[# ###]"
>>> with session.data_model_transaction():
...     add_foo(cube.name, session=session)
...     m["foo + 1"] = m["foo"] + 1

With nested transactions not allowed:

>>> def add_foo_and_query_it(cube_name, /, *, session):
...     cube = session.cubes[cube_name]
...     m = cube.measures
...     with session.data_model_transaction(allow_nested=False):
...         m["foo"] = 2_000
...         m["foo"].formatter = "INT[# ###]"
...     return cube.query(m["foo"])
>>> add_foo_and_query_it(cube.name, session=session)
     foo
0  2000
>>> with session.data_model_transaction():
...     add_foo_and_query_it(cube.name, session=session)
Traceback (most recent call last):
    ...
RuntimeError: Cannot start this transaction inside another transaction since nesting is not allowed.

See also

data_transaction().