Пример #1
0
    def _slow_time_series(self,
                          start,
                          end,
                          interval='days',
                          date_field=None,
                          aggregate=None):
        ''' Aggregate over time intervals using 1 sql query for one interval '''

        num, interval = _parse_interval(interval)

        if interval not in [
                'minutes', 'hours', 'days', 'weeks', 'months', 'years'
        ] or num != 1:
            raise InvalidInterval('Interval is currently not supported.')

        method = getattr(self, 'for_%s' % interval[:-1])

        stat_list = []
        dt, end = _to_datetime(start), _to_datetime(end)
        while dt <= end:
            value = method(dt, date_field, aggregate)
            stat_list.append((
                dt,
                value,
            ))
            dt = dt + relativedelta(**{interval: 1})
        return stat_list
Пример #2
0
    def _fast_time_series(self,
                          start,
                          end,
                          interval='days',
                          date_field=None,
                          aggregate=None):
        ''' Aggregate over time intervals using just 1 sql query '''

        date_field = date_field or self.date_field
        aggregate = aggregate or self.aggregate

        num, interval = _parse_interval(interval)

        interval_s = interval.rstrip('s')
        start, _ = get_bounds(start, interval_s)
        _, end = get_bounds(end, interval_s)

        kwargs = {'%s__range' % date_field: (start, end)}

        #  TODO: maybe we could use the tzinfo for the user's location
        aggregate_data = self.qs.\
                        filter(**kwargs).\
                        annotate(d=Trunc(date_field, interval_s, tzinfo=start.tzinfo)).\
                        order_by().values('d').\
                        annotate(agg=aggregate)

        today = _remove_time(compat.now())

        def to_dt(d):
            if isinstance(d, string_types):
                return parse(d, yearfirst=True, default=today)
            return d

        data = dict((to_dt(item['d']), item['agg']) for item in aggregate_data)

        stat_list = []
        dt = start
        while dt < end:
            idx = 0
            value = 0
            for i in range(num):
                value = value + data.get(dt, 0)
                if i == 0:
                    stat_list.append((
                        dt,
                        value,
                    ))
                    idx = len(stat_list) - 1
                elif i == num - 1:
                    stat_list[idx] = (
                        dt,
                        value,
                    )
                dt = dt + relativedelta(**{interval: 1})

        return stat_list
Пример #3
0
    def _fast_time_series(self,
                          start,
                          end,
                          interval='days',
                          date_field=None,
                          aggregate=None,
                          engine=None):
        ''' Aggregate over time intervals using just 1 sql query '''

        date_field = date_field or self.date_field
        aggregate = aggregate or self.aggregate
        engine = engine or self._guess_engine()

        num, interval = _parse_interval(interval)

        start, _ = get_bounds(start, interval.rstrip('s'))
        _, end = get_bounds(end, interval.rstrip('s'))
        interval_sql = get_interval_sql(date_field, interval, engine)

        kwargs = {'%s__range' % date_field: (start, end)}
        aggregate_data = self.qs.extra(select = {'d': interval_sql}).\
                        filter(**kwargs).order_by().values('d').\
                        annotate(agg=aggregate)

        today = _remove_time(compat.now())

        def to_dt(d):
            if isinstance(d, str):
                return parse(d, yearfirst=True, default=today)
            return d.replace(tzinfo=None)

        data = dict((to_dt(item['d']), item['agg']) for item in aggregate_data)

        stat_list = []
        dt = to_dt(start)
        while dt < to_dt(end):
            idx = 0
            value = 0
            for i in range(num):
                value = value + data.get(dt, 0)
                if i == 0:
                    stat_list.append((
                        dt,
                        value,
                    ))
                    idx = len(stat_list) - 1
                elif i == num - 1:
                    stat_list[idx] = (
                        dt,
                        value,
                    )
                dt = dt + relativedelta(**{interval: 1})

        return stat_list
Пример #4
0
    def _fast_time_series(self, start, end, interval='days',
                          date_field=None, aggregates=None, engine=None):
        ''' Aggregate over time intervals using just 1 sql query '''

        date_field = date_field or self.date_field
        aggregates = self._get_aggregates(aggregates)
        engine = engine or self._guess_engine()

        num, interval = _parse_interval(interval)

        start, _ = get_bounds(start, interval.rstrip('s'))
        _, end = get_bounds(end, interval.rstrip('s'))
        interval_sql = get_interval_sql(date_field, interval, engine)

        kwargs = {'%s__range' % date_field : (start, end)}
        aggregate_data = self.qs.extra(select = {'d': interval_sql}).\
                        filter(**kwargs).order_by().values('d')
        for i, aggregate in enumerate(aggregates):
            aggregate_data = aggregate_data.annotate(**{'agg_%d' % i: aggregate})

        today = _remove_time(compat.now())
        def to_dt(d):
            if isinstance(d, basestring):
                return parse(d, yearfirst=True, default=today)
            return d

        data = dict((to_dt(item['d']), [item['agg_%d' % i] for i in range(len(aggregates))]) for item in aggregate_data)

        stat_list = []
        dt = start
        try:
            try:
                from django.utils.timezone import utc
            except ImportError:
                from django.utils.timezones import utc
            dt = dt.replace(tzinfo=utc)
            end = end.replace(tzinfo=utc)
        except ImportError:
            pass
        zeros = [0 for i in range(len(aggregates))]

        while dt < end:
            idx = 0
            value = []
            for i in range(num):
                value = map(lambda a, b: (a or 0) + (b or 0), value, data.get(dt, zeros[:]))
                if i == 0:
                    stat_list.append(tuple([dt] + value))
                    idx = len(stat_list) - 1
                elif i == num - 1:
                    stat_list[idx] = tuple([dt] + value)
                dt = dt + relativedelta(**{interval : 1})

        return stat_list
Пример #5
0
    def _fast_time_series(self, start, end, interval='days',
                          date_field=None, aggregate=None, engine=None):
        ''' Aggregate over time intervals using just 1 sql query '''

        date_field = date_field or self.date_field
        aggregate = aggregate or self.aggregate
        engine = engine or self._guess_engine()

        num, interval = _parse_interval(interval)

        start, _ = get_bounds(start, interval.rstrip('s'))
        _, end = get_bounds(end, interval.rstrip('s'))
        interval_sql = get_interval_sql(date_field, interval, engine, timezone=start.tzinfo)

        kwargs = {'%s__range' % date_field : (start, end)}
        aggregate_data = self.qs.extra(select = {'d': interval_sql}).\
                        filter(**kwargs).order_by().values('d').\
                        annotate(agg=aggregate)

        today = _remove_time(compat.now())
        def to_dt(d):
            if isinstance(d, str):
                return parse(d, yearfirst=True, default=today)
            return d.replace(tzinfo=start.tzinfo)

        data = dict((to_dt(item['d']), item['agg']) for item in aggregate_data)
        arithmetic_methods = {Min: min, Max: max, Count: operator.add}
        aggregate_method = arithmetic_methods[aggregate.__class__] if aggregate.__class__ in arithmetic_methods else operator.add

        stat_list = []
        dt = start
        if data:
            default_value = list(data.values())[0].__class__()
        else:
            default_value = 0
        while dt < end:
            idx = 0
            value = default_value
            for i in range(num):
                value = aggregate_method(value, data.get(dt, default_value))
                if i == 0:
                    if aggregate_method == min:
                        value = data.get(dt, 0)
                    stat_list.append((dt, value,))
                    idx = len(stat_list) - 1
                elif i == num - 1:
                    stat_list[idx] = (dt, value,)
                dt = dt + relativedelta(**{interval : 1})

        return stat_list
Пример #6
0
    def _fast_time_series(self, start, end, interval='days',
                          date_field=None, aggregate=None, engine=None):
        ''' Aggregate over time intervals using just 1 sql query '''

        date_field = date_field or self.date_field
        aggregate = aggregate or self.aggregate
        engine = engine or self._guess_engine()

        num, interval = _parse_interval(interval)

        start, _ = get_bounds(start, interval.rstrip('s'))
        _, end = get_bounds(end, interval.rstrip('s'))
        interval_sql = get_interval_sql(date_field, interval, engine)

        kwargs = {'%s__range' % date_field : (start, end)}
        aggregate_data = self.qs.extra(select = {'d': interval_sql}).\
                        filter(**kwargs).order_by().values('d').\
                        annotate(agg=aggregate)

        today = _remove_time(compat.now())
        def to_dt(d):
            # Fix from https://bitbucket.org/aztrock/django-qsstats-magic 
            try:
                if isinstance(d, basestring):
                    return parse(d, yearfirst=True, default=today)
                return d
            except:
                if isinstance(d, str):
                    return parse(d, yearfirst=True, default=today)
                return d            


        data = dict((to_dt(item['d']), item['agg']) for item in aggregate_data)

        stat_list = []
        dt = start
        while dt < end:
            idx = 0
            value = 0
            for i in range(num):
                value = value + data.get(dt, 0)
                if i == 0:
                    stat_list.append((dt, value,))
                    idx = len(stat_list) - 1
                elif i == num - 1:
                    stat_list[idx] = (dt, value,)
                dt = dt + relativedelta(**{interval : 1})

        return stat_list
Пример #7
0
    def _slow_time_series(self, start, end, interval="days", date_field=None, aggregate=None):
        """ Aggregate over time intervals using 1 sql query for one interval """

        num, interval = _parse_interval(interval)

        if interval not in ["minutes", "hours", "days", "weeks", "months", "years"] or num != 1:
            raise InvalidInterval("Interval is currently not supported.")

        method = getattr(self, "for_%s" % interval[:-1])

        stat_list = []
        dt, end = _to_datetime(start), _to_datetime(end)
        while dt <= end:
            value = method(dt, date_field, aggregate)
            stat_list.append((dt, value))
            dt = dt + relativedelta(**{interval: 1})
        return stat_list
    def _slow_time_series(self, start, end, interval='days',
                          date_field=None, aggregate=None):
        ''' Aggregate over time intervals using 1 sql query for one interval '''

        num, interval = _parse_interval(interval)

        if interval not in ['minutes', 'hours',
                            'days', 'weeks',
                            'months', 'years'] or num != 1:
            raise InvalidInterval('Interval is currently not supported.')

        method = getattr(self, 'for_%s' % interval[:-1])

        stat_list = []
        dt, end = _to_datetime(start), _to_datetime(end)
        while dt <= end:
            value = method(dt, date_field, aggregate)
            stat_list.append((dt, value,))
            dt = dt + relativedelta(**{interval : 1})
        return stat_list
Пример #9
0
    def _fast_time_series(self, start, end, interval="days", date_field=None, aggregate=None, engine=None):
        """ Aggregate over time intervals using just 1 sql query """

        date_field = date_field or self.date_field
        aggregate = aggregate or self.aggregate
        engine = engine or self._guess_engine()

        num, interval = _parse_interval(interval)

        start, _ = get_bounds(start, interval.rstrip("s"))
        _, end = get_bounds(end, interval.rstrip("s"))
        interval_sql = get_interval_sql(date_field, interval, engine)

        kwargs = {"%s__range" % date_field: (start, end)}
        aggregate_data = (
            self.qs.extra(select={"d": interval_sql}).filter(**kwargs).order_by().values("d").annotate(agg=aggregate)
        )

        def to_dt(d):  # leave dates as-is
            return parse(d, yearfirst=True) if isinstance(d, basestring) else d

        data = dict((to_dt(item["d"]), item["agg"]) for item in aggregate_data)

        stat_list = []
        dt = start
        while dt < end:
            idx = 0
            value = 0
            for i in range(num):
                value = value + data.get(dt, 0)
                if i == 0:
                    stat_list.append((dt, value))
                    idx = len(stat_list) - 1
                elif i == num - 1:
                    stat_list[idx] = (dt, value)
                dt = dt + relativedelta(**{interval: 1})

        return stat_list