Documentation Index
Fetch the complete documentation index at: https://docs.activeviam.com/llms.txt
Use this file to discover all available pages before exploring further.
This feature is not part of the community edition: it needs to be unlocked.
This will walk you through the basics of DirectQuery by creating an application on Snowflake.
We’ll see how to:
- Connect to an external database
- Create a data model based on this external database
- Use this data model in a cube
>>> import atoti as tt
>>> session = tt.Session.start()
Connecting to the external database
Once we have a session, we can connect to the external database:
>>> from atoti_directquery_snowflake import ConnectionConfig
>>> connection_config = ConnectionConfig(
... url=f"jdbc:snowflake://{os.environ['SNOWFLAKE_ACCOUNT_IDENTIFIER']}.snowflakecomputing.com/?user={os.environ['SNOWFLAKE_USERNAME']}&database=TEST_RESOURCES&schema=TESTS",
... password=os.environ["SNOWFLAKE_PASSWORD"],
... )
>>> external_database = session.connect_to_external_database(connection_config)
The choice of the type of connection is what differs between the various supported databases.
For example, you can switch to atoti_directquery_clickhouse.ConnectionConfig to connect to Clickhouse instead of Snowflake.
Discovering the external tables
We can list the various tables available on the Snowflake server:
>>> # The method below is private and susceptible to change in patch releases.
>>> external_database.tables._filter(schema_name="TUTORIAL")
Building the data model
We can see the 2 tables of interest to us, add them to the session, and join them:
>>> from atoti_directquery_snowflake import TableConfig
>>> sales_table = session.add_external_table(
... external_database.tables["TEST_RESOURCES", "TUTORIAL", "SALES"],
... config=TableConfig(keys={"SALE_ID"}),
... )
>>> products_table = session.add_external_table(
... external_database.tables["TEST_RESOURCES", "TUTORIAL", "PRODUCTS"],
... config=TableConfig(keys={"PRODUCT_ID"}),
... )
>>> sales_table.join(
... products_table, sales_table["PRODUCT"] == products_table["PRODUCT_ID"]
... )
Note that at any point, you can inspect the external table definition, as well as its definition as interpreted by Atoti.
>>> # Table definition in the external database:
>>> external_database.tables["TEST_RESOURCES", "TUTORIAL", "SALES"]
>>> # Table definition in the Atoti session:
>>> sales_table
Creating the cube
The cube, its hierarchies and measures can be defined as we would do on a session with an in-memory database:
>>> cube = session.create_cube(sales_table)
>>> h, l, m = cube.hierarchies, cube.levels, cube.measures
>>> h["CATEGORY"] = [l["CATEGORY"], l["SUB_CATEGORY"]]
>>> del h["SUB_CATEGORY"]
>>> m["Max Price"] = tt.agg.max(sales_table["UNIT_PRICE"])
Running a query
Let’s make sure everything works, by running a query:
>>> cube.query(m["Max Price"], levels=[l["SHOP"]])
Max Price
SHOP
shop_0 210.00
shop_1 300.00
shop_2 300.00
shop_3 210.00
shop_4 300.00
shop_5 150.00
Refreshing the data
If the external database receives updates, some elements retrieved by DirectQuery will be out-of-date.
You can manually trigger a refresh of the session to restore synchronization:
>>> # The method below is private and susceptible to change in patch releases.
>>> session._synchronize_with_external_database()
Going further
See DirectQuery for the list of supported databases.