Backends for browsing aggregates of various data sources
SQL backend uses SQLAlchemy for generating queries. It supports all databases that the SQLAlchemy supports such as:
To create a SQL workspace use:
workspace = cubes.create_workspace("sql", model, url="postgres://localhost/database")
Create workspace for model with configuration in dictionary options. This method is used by the slicer server.
The options are:
Required (one of the two, engine takes precedence):
Optional:
Options for denormalized views:
Create a workspace. For description of options see create_workspace()
Returns a browser for a cube.
Extracts dimension values at certain level into a separate table. The new table name will be composed of dimension_prefix, dimension name and suffixed by dimension level. For example a product dimension at category level with prefix dim_ will be called dim_product_category
Attributes:
Extract multiple dimensions from a snowflake. See extract_dimension() for more information. grain is a dictionary where keys are dimension names and values are levels, if level is None then all levels are considered.
Creates an aggregate table. If dimensions is None then all cube’s dimensions are considered.
Arguments:
Creates a denormalized view named view_name of a cube. If view_name is None then view name is constructed by pre-pending value of denormalized_view_prefix from workspace options to the cube name. If no prefix is specified in the options, then view name will be equal to the cube name.
Options:
Validate physical representation of model. Returns a list of dictionaries with keys: type, issue, object.
Types might be: join or attribute.
The join issues are:
The attribute issues are:
SnowflakeBrowser is a SQL-based AggregationBrowser implementation that can aggregate star and snowflake schemas without need of having explicit view or physical denormalized table.
Attributes:
Tuning:
Limitations:
Return aggregated result.
Arguments:
Query tuning:
Result is paginated by page_size and ordered by order.
Number of database queries:
Notes:
Get a single fact with key key_value from cube.
Number of SQL queries: 1.
Return all facts from cell, might be ordered and paginated.
Number of SQL queries: 1.
Returns details for path in dimension. Can be used for multi-dimensional “breadcrumbs” in a used interface.
Number of SQL queries: 1.
Change the browser’s locale
Validate physical representation of model. Returns a list of dictionaries with keys: type, issue, object.
Types might be: join or attribute.
The join issues are:
The attribute issues are:
Return values for dimension with level depth depth. If depth is None, all levels are returned.
Number of database queries: 1.
Object providing context for constructing queries. Puts together the mapper and physical structure. mapper - which is used for mapping logical to physical attributes and performing joins. metadata is a sqlalchemy.MetaData instance for getting physical table representations.
Object attributes:
Note
To get results as a dictionary, you should zip() the returned rows after statement execution with:
labels = [column.name for column in statement.columns] ... record = dict(zip(labels, row))
This is little overhead for a workaround for SQLAlchemy behaviour in SQLite database. SQLite engine does not respect dots in column names which results in “duplicate column name” error.
Return a statement for summarized aggregation. whereclause is same as SQLAlchemy whereclause for sqlalchemy.sql.expression.select(). attributes is list of logical references to attributes to be selected. If it is None then all attributes are used. drilldown has to be a dictionary. Use levels_from_drilldown() to prepare correct drill-down statement.
Returns list of aggregation functions (sqlalchemy) on measure columns. The result columns are labeled as measure + _ = aggregation, for example: amount_sum or discount_min.
measure has to be Attribute instance.
If measure has no explicit aggregations associated, then sum is assumed.
Return a Condition tuple for a boundary condition. If bound is 1 then path is considered to be upper bound (operators < and <= are used), otherwise path is considered as lower bound (operators > and >= are used )
Return a column object for attribute. locale is explicit locale to be used. If not specified, then the current browsing/mapping locale is used for localizable attributes.
Returns list of columns.If expand_locales is True, then one column per attribute locale is added.
Constructs conditions for all cuts in the cell. Returns a named tuple with keys:
Returns a Condition tuple (attributes, conditions, group_by) dimension dim point at path. It is a compound condition - one equality condition for each path element in form: level[i].key = path[i]
Return a statement (see class description for more information) for denormalized view. whereclause is same as SQLAlchemy whereclause for sqlalchemy.sql.expression.select(). attributes is list of logical references to attributes to be selected. If it is None then all attributes are used. condition_attributes contains list of attributes that are not going to be selected, but are required for WHERE condition.
Set expand_locales to True to expand all localized attributes.
Returns statement for dimension details. attributes should be a list of attributes from one dimension that is one branch (master-detail) of a star/snowflake.
Return a statement for selecting a single fact based on key_value
Create partial expression on a fact table with joins that can be used as core for a SELECT statement. join is a list of joins returned from mapper (most probably by Mapper.relevant_joins())
If include_fact is True (default) then fact table is considered as starting point. If it is False The first detail table is considered as starting point for joins. This might be useful when getting values of a dimension without cell restrictions.
Returns a join expression for attributes
Returns list of logical attribute labels from list of columns or column labels.
This method and additional internal references were added because some database dialects, such as Exasol, can not handle dots in column names, even when quoted.
Returns a SQL statement which is ordered according to the order. If the statement contains attributes that have natural order specified, then the natural order is used, if not overriden in the order.
dimension_levels is list of considered dimension levels in form of tuples (dimension, levels). For each level it’s sort key is used.
Returns paginated statement if page is provided, otherwise returns the same statement.
Return a condition for a hierarchical range (from_path, to_path). Return value is a Condition tuple.
Return a SQLAlchemy Table instance. If table was already accessed, then existing table is returned. Otherwise new instance is created.
If schema is None then browser’s default schema is used.
Note
cubes.QueryContext does not serve to it’s original purpose anymore and will be verylikely meerged with the browser.
This backend is just for backend development demonstration purposes.
Demo backend browser. This backend is serves just as example of a backend. Uses another Slicer server instance for doing all the work. You might use it as a template for your own browser.
Attributes:
Custom backend is just a subclass of cubes.AggregationBrowser class.
Requirements for the backned:
Requirements for the AggregationBrowser.aggregate() function:
If the backend is intended to be used by the Slicer server, then backend should be placed in its own module. The module should contain a method create_workspace(model, config) which returns a workspace object. config is a configuration dictionary taken from the config file (see below). The workspace object should implement browser_for_cube(cube, locale) which returns an AggregationBrowser subclass.
The create_workspace() can be compared to create_engine() in a database abstraction framework and the browser_for_cube() can be compared to engine.connect() to get a connection from a pool.
The configuration for create_workspace() comes from slicer .ini configuration file in section [workspace] and is provided as dict object.