Source code for fireant.slicer.slicers

import itertools

from .dimensions import DisplayDimension
from .queries import (
    DimensionChoicesQueryBuilder,
    DimensionLatestQueryBuilder,
    SlicerQueryBuilder,
)


class _Container(object):
    """
    This is a list of slicer elements, metrics or dimensions, used for accessing an element by key with a dot syntax.

    Example:

    .. code-block:: python

        slicer = Slicer(
            dimensions=[
                Dimension(key='my_dimension1')
            ]
        )
        slicer.dimensions.my_dimension1
    """
    def __init__(self, items):
        self._items = items
        for item in items:
            setattr(self, item.key, item)

            # Special case to include display definitions for filters
            if item.has_display_field:
                setattr(self, item.display.key, DisplayDimension(item))

    def __iter__(self):
        return iter(self._items)

    def __getitem__(self, item):
        return getattr(self, item)

    def __contains__(self, item):
        return hasattr(self, item)

    def __eq__(self, other):
        """
        Checks if the other object is an instance of _Container and has the same number of items with matching keys.
        """
        return isinstance(other, _Container) and \
               all([a is not None
                        and b is not None
                        and a.key == b.key
                        for a, b in itertools.zip_longest(self._items, getattr(other, '_items', ()))])


[docs]class Slicer(object): """ WRITEME """
[docs] class Dimensions(_Container): pass
[docs] class Metrics(_Container): pass
[docs] class Fields(_Container): pass
def __init__(self, table, database, joins=(), dimensions=(), metrics=(), hint_table=None, always_query_all_metrics=False): """ Constructor for a slicer. Contains all the fields to initialize the slicer. :param table: (Required) A pypika Table reference. The primary table that this slicer will retrieve data from. :param database: (Required) A Database reference. Holds the connection details used by this slicer to execute queries. :param metrics: (Required: At least one) A list of metrics which can be queried. Metrics are the types of data that are displayed. :param dimensions: (Optional) A list of dimensions used for grouping metrics. Dimensions are used as the axes in charts, the indices in tables, and also for splitting charts into multiple lines. :param joins: (Optional) A list of join descriptions for joining additional tables. Joined tables are only used when querying a metric or dimension which requires it. :param hint_table: (Optional) A hint table used for querying dimension options. If not present, the table will be used. The hint_table must have the same definition as the table omitting dimensions which do not have a set of options (such as datetime or boolean dimensions) and the metrics. This is provided to more efficiently query dimension options. :param always_query_all_metrics: (Default: False) When true, all metrics will be included in database queries in order to increase cache hits. """ self.table = table self.database = database self.joins = joins self.hint_table = hint_table self.dimensions = Slicer.Dimensions(dimensions) self.metrics = Slicer.Metrics(metrics) self.fields = Slicer.Fields(metrics + dimensions) # add query builder entry points self.data = SlicerQueryBuilder(self) self.latest = DimensionLatestQueryBuilder(self) for dimension in dimensions: dimension.choices = DimensionChoicesQueryBuilder(self, dimension) self.always_query_all_metrics = always_query_all_metrics def __eq__(self, other): return isinstance(other, Slicer) \ and self.metrics == other.metrics \ and self.dimensions == other.dimensions def __repr__(self): return 'Slicer(metrics=[{}],dimensions=[{}])' \ .format(','.join([m.key for m in self.metrics]), ','.join([d.key for d in self.dimensions]))