Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for the generated aliases #159

Merged
merged 1 commit into from
Jul 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion fireant/formats.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import pandas as pd

INFINITY = "Infinity"
NULL_VALUE = 'null'

NO_TIME = time(0)

Expand All @@ -33,7 +34,7 @@ def coerce_type(value):
except:
pass

if 'null' == value:
if NULL_VALUE == value:
return None
if 'True' == value:
return True
Expand Down
25 changes: 17 additions & 8 deletions fireant/slicer/operations.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import numpy as np
import pandas as pd

from fireant.utils import format_key
from .metrics import Metric


Expand Down Expand Up @@ -78,26 +79,30 @@ def __repr__(self):

class CumSum(_Cumulative):
def apply(self, data_frame):
df_key = format_key(self.arg.key)

if isinstance(data_frame.index, pd.MultiIndex):
levels = self._group_levels(data_frame.index)

return data_frame[self.arg.key] \
return data_frame[df_key] \
.groupby(level=levels) \
.cumsum()

return data_frame[self.arg.key].cumsum()
return data_frame[df_key].cumsum()


class CumProd(_Cumulative):
def apply(self, data_frame):
df_key = format_key(self.arg.key)

if isinstance(data_frame.index, pd.MultiIndex):
levels = self._group_levels(data_frame.index)

return data_frame[self.arg.key] \
return data_frame[df_key] \
.groupby(level=levels) \
.cumprod()

return data_frame[self.arg.key].cumprod()
return data_frame[df_key].cumprod()


class CumMean(_Cumulative):
Expand All @@ -106,14 +111,16 @@ def cummean(x):
return x.cumsum() / np.arange(1, len(x) + 1)

def apply(self, data_frame):
df_key = format_key(self.arg.key)

if isinstance(data_frame.index, pd.MultiIndex):
levels = self._group_levels(data_frame.index)

return data_frame[self.arg.key] \
return data_frame[df_key] \
.groupby(level=levels) \
.apply(self.cummean)

return self.cummean(data_frame[self.arg.key])
return self.cummean(data_frame[df_key])


class _Rolling(_BaseOperation):
Expand Down Expand Up @@ -141,11 +148,13 @@ def rolling_mean(self, x):
return x.rolling(self.window, self.min_periods).mean()

def apply(self, data_frame):
df_key = format_key(self.arg.key)

if isinstance(data_frame.index, pd.MultiIndex):
levels = self._group_levels(data_frame.index)

return data_frame[self.arg.key] \
return data_frame[df_key] \
.groupby(level=levels) \
.apply(self.rolling_mean)

return self.rolling_mean(data_frame[self.arg.key])
return self.rolling_mean(data_frame[df_key])
18 changes: 10 additions & 8 deletions fireant/slicer/queries/builder.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import pandas as pd
from pypika import (
Order,
)
from typing import (
Dict,
Iterable,
)

import pandas as pd
from fireant.utils import immutable
from pypika import (
Order,
from fireant.utils import (
format_key,
immutable,
)

from .database import fetch_data
from .finders import (
find_and_group_references_for_dimensions,
Expand Down Expand Up @@ -108,7 +110,7 @@ def orderby(self, element: SlicerElement, orientation=None):
The directionality to order by, either ascending or descending.
:return:
"""
self._orders += [(element.definition.as_(element.key), orientation)]
self._orders += [(element.definition.as_(format_key(element.key)), orientation)]

@property
def query(self):
Expand Down Expand Up @@ -235,9 +237,9 @@ def fetch(self, limit=None, offset=None, hint=None, force_include=()) -> pd.Seri
query = query.hint(hint)

dimension = self._dimensions[0]
definition = dimension.display_definition.as_(dimension.display_key) \
definition = dimension.display_definition.as_(format_key(dimension.display_key)) \
if dimension.has_display_field \
else dimension.definition.as_(dimension.key)
else dimension.definition.as_(format_key(dimension.key))

if force_include:
include = self.slicer.database.to_char(dimension.definition) \
Expand Down
14 changes: 7 additions & 7 deletions fireant/slicer/queries/database.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import time

import pandas as pd
import time
from typing import Iterable

from fireant.database.base import Database
from fireant.formats import NULL_VALUE
from fireant.utils import format_key
from .logger import (
query_logger,
slow_query_logger,
Expand All @@ -13,8 +14,6 @@
Dimension,
)

NULL_VALUE = 'null'


def fetch_data(database: Database, query: str, dimensions: Iterable[Dimension]):
"""
Expand Down Expand Up @@ -55,15 +54,16 @@ def clean_and_apply_index(data_frame: pd.DataFrame, dimensions: Iterable[Dimensi
if not dimensions:
return data_frame

dimension_keys = [d.key for d in dimensions]
dimension_keys = [format_key(d.key)
for d in dimensions]

for i, dimension in enumerate(dimensions):
if isinstance(dimension, ContinuousDimension):
# Continuous dimensions are can never contain null values since they are selected as windows of values
# With that in mind, we leave the NaNs in them to represent Totals.
continue

level = dimension.key
level = format_key(dimension.key)
data_frame[level] = fill_nans_in_level(data_frame, dimension, dimension_keys[:i]) \
.apply(lambda x: str(x) if not pd.isnull(x) else None)

Expand All @@ -87,7 +87,7 @@ def fill_nans_in_level(data_frame, dimension, preceding_dimension_keys):
:return:
The level in the data_frame with the nulls replaced with empty string
"""
level = dimension.key
level = format_key(dimension.key)

if dimension.is_rollup:
if preceding_dimension_keys:
Expand Down
21 changes: 12 additions & 9 deletions fireant/slicer/queries/makers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from functools import partial

from fireant.utils import flatten
from pypika import JoinType

from fireant.utils import (
flatten,
format_key,
)
from .finders import (
find_joins_for_tables,
find_required_tables_to_join,
Expand Down Expand Up @@ -150,7 +153,7 @@ def make_slicer_query_with_references(database, base_table, joins, dimensions, m
dimensions=non_totals_dimensions,
metrics=metrics,
filters=filters) \
.as_('base')
.as_('$base')

container_query = database.query_cls.from_(original_query)

Expand Down Expand Up @@ -181,7 +184,7 @@ def make_slicer_query_with_references(database, base_table, joins, dimensions, m
non_totals_dimensions,
metrics,
ref_filters) \
.as_(alias)
.as_(format_key(alias))

join_criterion = make_reference_join_criterion(ref_dimension,
non_totals_dimensions,
Expand All @@ -196,9 +199,9 @@ def make_slicer_query_with_references(database, base_table, joins, dimensions, m
else:
container_query = container_query.from_(ref_query)

ref_dimension_definitions.append([offset_func(ref_query.field(dimension.key))
ref_dimension_definitions.append([offset_func(ref_query.field(format_key(dimension.key)))
if ref_dimension == dimension
else ref_query.field(dimension.key)
else ref_query.field(format_key(dimension.key))
for dimension in dimensions])

ref_terms += make_terms_for_references(references,
Expand All @@ -217,7 +220,7 @@ def make_slicer_query_with_references(database, base_table, joins, dimensions, m


def make_terms_for_metrics(metrics):
return [metric.definition.as_(metric.key)
return [metric.definition.as_(format_key(metric.key))
for metric in metrics]


Expand All @@ -240,12 +243,12 @@ def make_terms_for_dimension(dimension, window=None):
window(dimension.definition, dimension.interval)
if window and hasattr(dimension, 'interval')
else dimension.definition
).as_(dimension.key)
).as_(format_key(dimension.key))

# Include the display definition if there is one
return [
dimension_definition,
dimension.display_definition.as_(dimension.display_key)
dimension.display_definition.as_(format_key(dimension.display_key))
] if dimension.has_display_field else [
dimension_definition
]
Expand Down
15 changes: 8 additions & 7 deletions fireant/slicer/queries/references.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
reference_key,
reference_term,
)
from fireant.utils import format_key
from ..dimensions import Dimension
from ..intervals import weekly

Expand Down Expand Up @@ -44,7 +45,7 @@ def make_terms_for_references(references, original_query, ref_query, metrics):
original_query,
ref_query)

terms += [ref_metric(metric).as_(reference_key(metric, reference))
terms += [ref_metric(metric).as_(format_key(reference_key(metric, reference)))
for metric in metrics]

return terms
Expand Down Expand Up @@ -73,7 +74,7 @@ def make_dimension_terms_for_reference_container_query(original_query,

terms = []
for dimension, ref_dimension_definition in zip(dimensions, ref_dimension_definitions):
term = _select_for_reference_container_query(dimension.key,
term = _select_for_reference_container_query(format_key(dimension.key),
dimension.definition,
original_query,
ref_dimension_definition)
Expand All @@ -83,9 +84,9 @@ def make_dimension_terms_for_reference_container_query(original_query,
continue

# Select the display definitions as a field from the ref query
ref_display_definition = [definition.table.field(dimension.display_key)
ref_display_definition = [definition.table.field(format_key(dimension.display_key))
for definition in ref_dimension_definition]
display_term = _select_for_reference_container_query(dimension.display_key,
display_term = _select_for_reference_container_query(format_key(dimension.display_key),
dimension.display_definition,
original_query,
ref_display_definition)
Expand All @@ -95,7 +96,7 @@ def make_dimension_terms_for_reference_container_query(original_query,


def make_metric_terms_for_reference_container_query(original_query, metrics):
return [_select_for_reference_container_query(metric.key, metric.definition, original_query)
return [_select_for_reference_container_query(format_key(metric.key), metric.definition, original_query)
for metric in metrics]


Expand Down Expand Up @@ -180,13 +181,13 @@ def make_reference_join_criterion(ref_dimension: Dimension,
join_criterion = None

for dimension in all_dimensions:
ref_query_field = ref_query.field(dimension.key)
ref_query_field = ref_query.field(format_key(dimension.key))

# If this is the reference dimension, it needs to be offset by the reference interval
if ref_dimension == dimension:
ref_query_field = offset_func(ref_query_field)

next_criterion = original_query.field(dimension.key) == ref_query_field
next_criterion = original_query.field(format_key(dimension.key)) == ref_query_field

join_criterion = next_criterion \
if join_criterion is None \
Expand Down
10 changes: 7 additions & 3 deletions fireant/slicer/references.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from pypika import functions as fn
from pypika.queries import QueryBuilder
from fireant import utils


class Reference(object):
Expand Down Expand Up @@ -107,15 +108,18 @@ def reference_term(reference: Reference,
:return:
"""

def original_field(metric):
return original_query.field(utils.format_key(metric.key))

def ref_field(metric):
return ref_query.field(metric.key)
return ref_query.field(utils.format_key(metric.key))

if reference.delta:
if reference.delta_percent:
return lambda metric: (original_query.field(metric.key) - ref_field(metric)) \
return lambda metric: (original_field(metric) - ref_field(metric)) \
* \
(100 / fn.NullIf(ref_field(metric), 0))

return lambda metric: original_query.field(metric.key) - ref_field(metric)
return lambda metric: original_field(metric) - ref_field(metric)

return ref_field
12 changes: 8 additions & 4 deletions fireant/slicer/widgets/datatables.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
formats,
utils,
)
from fireant.utils import format_key
from .base import (
TransformableWidget,
)
Expand Down Expand Up @@ -70,9 +71,10 @@ def _render_dimensional_metric_cell(row_data: pd.Series, metric: Metric):
for key, next_row in row_data.groupby(level=-1):
next_row.reset_index(level=-1, drop=True, inplace=True)

df_key = format_key(metric.key)
level[key] = _render_dimensional_metric_cell(next_row, metric) \
if isinstance(next_row.index, pd.MultiIndex) \
else _format_metric_cell(next_row[metric.key], metric)
else _format_metric_cell(next_row[df_key], metric)

return level

Expand Down Expand Up @@ -128,7 +130,7 @@ def transform(self, data_frame, slicer, dimensions, references):
"""
dimension_display_values = extract_display_values(dimensions, data_frame)

metric_keys = [reference_key(metric, reference)
metric_keys = [format_key(reference_key(metric, reference))
for metric in self.items
for reference in [None] + references]
data_frame = data_frame[metric_keys]
Expand Down Expand Up @@ -241,14 +243,16 @@ def _data_row(self, dimensions, dimension_values, dimension_display_values, refe
row = {}

for dimension, dimension_value in zip(dimensions, utils.wrap_list(dimension_values)):
row[dimension.key] = _render_dimension_cell(dimension_value, dimension_display_values.get(dimension.key))
df_key = format_key(dimension.key)
row[dimension.key] = _render_dimension_cell(dimension_value, dimension_display_values.get(df_key))

for metric in self.items:
for reference in [None] + references:
key = reference_key(metric, reference)
df_key = format_key(key)

row[key] = _render_dimensional_metric_cell(row_data, metric) \
if isinstance(row_data.index, pd.MultiIndex) \
else _format_metric_cell(row_data[key], metric)
else _format_metric_cell(row_data[df_key], metric)

return row
Loading