def test_sum_field(self):
     """
     Tests that the SumField generates correct sql
     """
     query = Query().from_table(table=Order, fields=[SumField('margin')])
     query_str = query.get_sql()
     expected_query = 'SELECT SUM(tests_order.margin) AS "margin_sum" FROM tests_order'
     self.assertEqual(query_str, expected_query,
                      get_comparison_str(query_str, expected_query))
Exemplo n.º 2
0
 def date_part_field_test(self):
     """
     Tests the different options of DatePartField objects
     """
     # test with no cast
     query = Query().from_table(
         table=Order, fields=[AllTime('time'),
                              SumField('margin')])
     expected_query = ('SELECT CAST(0 AS INT) AS time__epoch, '
                       'SUM(tests_order.margin) AS margin_sum '
                       'FROM tests_order')
     self.assertEqual(expected_query, query.get_sql())
     rows = query.select()
     self.assertEqual(1, len(rows))
     self.assertEqual(825.0, rows[0]['margin_sum'])
     self.assertEqual(0, rows[0]['time__epoch'])
Exemplo n.º 3
0
 def test_week_grouping(self):
     """
     Verifies that the week grouping query and result is correct
     """
     query = Query().from_table(
         table=Order, fields=[Week('time', auto=True),
                              SumField('margin')])
     expected_query = (
         "SELECT CAST(EXTRACT(year FROM tests_order.time) AS INT) AS time__year, "
         "CAST(EXTRACT(week FROM tests_order.time) AS INT) AS time__week, "
         "CAST(EXTRACT(epoch FROM date_trunc('week', tests_order.time)) AS INT) AS time__epoch, "
         "SUM(tests_order.margin) AS margin_sum "
         "FROM tests_order "
         "GROUP BY time__year, time__week, time__epoch "
         "ORDER BY time__epoch ASC")
     self.assertEqual(expected_query, query.get_sql())
     rows = query.select()
     self.assertEqual(1, len(rows))
     week_dt = datetime.datetime(2012, 10, 19)
     week_unix_time = unix_time(floor(week_dt, week=1))
     self.assertEqual(825.0, rows[0]['margin_sum'])
     self.assertEqual(week_unix_time, rows[0]['time__epoch'])
     self.assertEqual(2012, rows[0]['time__year'])
     self.assertEqual(42, rows[0]['time__week'])
Exemplo n.º 4
0
    def query_data(cls, widget):
        # get the columns needed
        column = widget.column
        group_by = widget.group_by if widget.group_by else None

        if isinstance(widget.content_object, XForm):
            xform = widget.content_object
        elif isinstance(widget.content_object, DataView):
            xform = widget.content_object.xform

        field = get_field_from_field_xpath(column, xform)

        if isinstance(field, basestring) and field == SUBMISSION_TIME:
            field_label = 'Submission Time'
            field_xpath = '_submission_time'
            field_type = 'datetime'
            data_type = DATA_TYPE_MAP.get(field_type, 'categorized')
        else:
            field_type = field.type
            data_type = DATA_TYPE_MAP.get(field.type, 'categorized')
            field_xpath = field.get_abbreviated_xpath()
            field_label = get_field_label(field)

        columns = [
            SimpleField(field="json->>'%s'" % unicode(column),
                        alias='"{}"'.format(column)),
            CountField(field="json->>'%s'" % unicode(column), alias='"count"')
        ]
        if group_by:
            if field_type in NUMERIC_LIST:
                column_field = SimpleField(field="json->>'%s'" %
                                           unicode(column),
                                           cast="float",
                                           alias=column)
            else:
                column_field = SimpleField(field="json->>'%s'" %
                                           unicode(column),
                                           alias=column)

            # build inner query
            inner_query_columns = \
                [column_field,
                 SimpleField(field="json->>'%s'" % unicode(group_by),
                             alias=group_by),
                 SimpleField(field="xform_id"),
                 SimpleField(field="deleted_at")]
            inner_query = Query().from_table(Instance, inner_query_columns)

            # build group-by query
            if field_type in NUMERIC_LIST:
                columns = [
                    SimpleField(field=group_by, alias='"%s"' % group_by),
                    SumField(field=column, alias="sum"),
                    AvgField(field=column, alias="mean")
                ]
            elif field_type == SELECT_ONE:
                columns = [
                    SimpleField(field=column, alias='"%s"' % column),
                    SimpleField(field=group_by, alias='"%s"' % group_by),
                    CountField(field="*", alias='"count"')
                ]

            query = Query().from_table({'inner_query': inner_query}, columns).\
                where(xform_id=xform.pk, deleted_at=None)

            if field_type == SELECT_ONE:
                query.group_by(column).group_by(group_by)
            else:
                query.group_by(group_by)

        else:
            query = Query().from_table(Instance, columns).\
                where(xform_id=xform.pk, deleted_at=None)
            query.group_by("json->>'%s'" % unicode(column))

        # run query
        records = query.select()

        # flatten multiple dict if select one with group by
        if field_type == SELECT_ONE and group_by:
            records = _flatten_multiple_dict_into_one(column, group_by,
                                                      records)
        # use labels if group by
        if group_by:
            group_by_field = get_field_from_field_xpath(group_by, xform)
            choices = get_field_choices(group_by, xform)
            records = _use_labels_from_group_by_name(group_by,
                                                     group_by_field,
                                                     data_type,
                                                     records,
                                                     choices=choices)
        return {
            "field_type": field_type,
            "data_type": data_type,
            "field_xpath": field_xpath,
            "field_label": field_label,
            "grouped_by": group_by,
            "data": records
        }