Model providers create cubes.Cube and cubes.Dimension objects from a metadata or an external description.
To implement a custom model provider subclass the cubes.ModelProvider class. It is required that the __init__ method calls the super’s __init__ with the metadata argument.
Required methods to be implemented:
Optional:
See also
Model Reference, Model Providers Reference, cubes.ModelProvider, cubes.StaticModelProvider, cubes.create_cube(), cubes.create_dimension()
To provide a cube implement cube(name) method. The method should raise NoSuchCubeError when a cube is not provided by the provider.
To set cube’s dimension you can either set dimension’s name in linked_dimensions or directly a Dimension object in dimensions. The rule is:
Note
It is recommended to use the linked_dimensions name list. The dimensions is considered an advanced feature.
Example of a provider which provides just a simple cube with date dimension and a measure amount and two aggregates amount_sum and record_count. Knows three cubes: activations, churn and sales:
from cubes import ModelProvider, create_cube
class SimpleModelProvider(ModelProvider):
def __init__(self, metadata=None):
super(DatabaseModelProvider, self).__init__(metadata)
self.known_cubes = ["activations", "churn", "sales"]
def list_cubes(self):
cubes = []
for name in self.known_cubes:
info = {"name": name}
cubes.append(info)
return cubes
def cube(self, name):
if not name in self.known_cubes:
raise NoSuchCubeError("Unknown cube '%s'" % name, name)
metadata = {
"name": name,
"linked_dimensions": ["date"],
"measures": ["amount"],
"aggregats": [
{"name": "amount_sum", "measure": "amount", "function": "sum"},
{"name": "record_count", "function": "count"}
]
}
return create_cube(metadata)
The above provider assumes that some other object providers the date dimension.
Some providers might require a database connection or an API credentials that might be shared by the data store containing the actual cube data. In this case the model provider should implement method requires_store() and return True. The provider’s initialize_from_store() will be called back at some point before first cube is retrieved. The provider will have store instance variable available with cubes.Store object instance.
Example:
from cubes import ModelProvider, create_cube
from sqlalchemy import sql
import json
class DatabaseModelProvider(ModelProvider):
def requires_store(self):
return True
def initialize_from_store(self):
self.table = self.store.table("cubes_metadata")
self.engine = self.store.engine
def cube(self, name):
self.engine.execute(select)
# Let's assume that we have a SQLalchemy table with a JSON string
# with cube metadata and columns: name, metadata
condition = self.table.c.name == name
statement = sql.expression.select(self.table.c.metadata,
from_obj=self.table,
where=condition)
result = list(self.engine.execute(statement))
if not result:
raise NoSuchCubeError("Unknown cube '%s'" % name, name)
cube = json.loads(result[0])
return create_cube(cube)