コード例 #1
0
    def get_list(self, request, **kwargs):

        helper = CustomCallHelper()
        cursor = connection.cursor()

        # get filters
        indicator_id = request.GET.get('indicator_id', None)

        # get indicator type
        from indicator.models import Indicator
        current_indicator = Indicator.objects.get(id=indicator_id)

        if (current_indicator.type_data == "p"):
            aggregation_type = "AVG"
        else:
            return HttpResponse(ujson.dumps(["Indicator type not recognized"]),
                                content_type='application/json')

        #create the query
        query = 'SELECT year, r.code as region_id, ' + aggregation_type + '(id.value) as aggregation ' \
                'FROM indicator_indicatordata as id ' \
                'JOIN geodata_country as c on id.country_id = c.code ' \
                'JOIN geodata_region as r on c.region_id = r.code ' \
                'WHERE id.indicator_id = "'+indicator_id+'" ' \
                'GROUP BY year, r.code'

        # execute query
        cursor.execute(query)
        results1 = helper.get_fields(cursor=cursor)

        # query result -> json output

        options = {}

        for r in results1:

            options[r['region_id']] = r['aggregation']

        return HttpResponse(ujson.dumps(options),
                            content_type='application/json')
コード例 #2
0
    def get_list(self, request, **kwargs):

        helper = CustomCallHelper()

        country_q = helper.get_and_query(request, 'countries__in', 'c.code')
        region_q = helper.get_and_query(request, 'regions__in',
                                        'dac_region_code')
        year_q = helper.get_and_query(request, 'years__in', 'id.year')
        indicator_q = helper.get_and_query(request, 'indicators__in',
                                           'indicator_id')

        if not indicator_q:
            return HttpResponse(ujson.dumps("No indicator given"),
                                content_type='application/json')

        filter_string = '  (' + country_q + region_q + year_q + indicator_q + ')'

        if 'AND ()' in filter_string:
            filter_string = filter_string[:-6]

        cursor = connection.cursor()

        cursor.execute(
            'SELECT da.id as indicator_id, da.friendly_label, da.type_data, c.name as country_name, '
            'id.value, id.year, AsText(c.center_longlat) as loc, c.code as country_id '
            'FROM indicator_indicatordata id '
            'LEFT OUTER JOIN geodata_country c ON id.country_id = c.code '
            'LEFT OUTER JOIN indicator_indicator da ON da.id = id.indicator_id '
            'WHERE '
            'id.city_id is NULL '
            'AND %s' % (filter_string))
        cursor_max = connection.cursor()

        indicator_q = indicator_q.replace(" ) AND (", "")
        cursor_max.execute(
            'SELECT max(value) as max_value FROM indicator_indicatordata WHERE %s'
            % indicator_q)
        result_max = cursor_max.fetchone()
        desc = cursor.description
        results = [
            dict(zip([col[0] for col in desc], row))
            for row in cursor.fetchall()
        ]
        country = {}
        for r in results:

            try:
                country[r['country_id']]['years']
            except:
                loc = r['loc']
                if loc:

                    loc = loc.replace("POINT(", "")
                    loc = loc.replace(")", "")
                    loc_array = loc.split(" ")
                    longitude = loc_array[0]
                    latitude = loc_array[1]
                else:
                    longitude = None
                    latitude = None

                country[r['country_id']] = {
                    'name': r['country_name'],
                    'country_id': r['country_id'],
                    'longitude': longitude,
                    'latitude': latitude,
                    'indicator_friendly': r['friendly_label'],
                    'type_data': r['type_data'],
                    'indicator': r['indicator_id'],
                    'years': {}
                }

            year = {}
            year['y' + str(r['year'])] = r['value']
            country[r['country_id']]['years'].update(year)

        country['max_value'] = result_max[0]

        return HttpResponse(ujson.dumps(country),
                            content_type='application/json')
コード例 #3
0
    def get_list(self, request, **kwargs):
        helper = CustomCallHelper()
        city_q = helper.get_and_query(request, 'cities__in', 'city.id') or ""
        country_q = helper.get_and_query(request, 'countries__in',
                                         'country.code') or ""
        region_q = helper.get_and_query(request, 'regions__in',
                                        'region.code') or ""
        indicator_q = helper.get_and_query(request, 'indicators__in',
                                           'i.indicator_id') or ""
        category_q = helper.get_and_query(request, 'categories__in',
                                          'ind.category') or ""
        adm_division_q = request.GET.get("adm_division__in",
                                         "city,country,region") or ""
        adm_divisions = adm_division_q.split(",")

        filter_string = ' AND (' + city_q + country_q + region_q + indicator_q + category_q + ')'
        if 'AND ()' in filter_string:
            filter_string = filter_string[:-6]

        regions = {}
        countries = {}
        cities = {}
        indicators = {}
        jsondata = {}

        if "city" in adm_divisions:
            cursor = connection.cursor()
            # city filters
            cursor.execute(
                'SELECT DISTINCT i.indicator_id, i.selection_type ,ind.friendly_label, ind.category as indicator_category, city.id as city_id, city.name as city_name, country.code as country_id, country.name as country_name, region.code as region_id, region.name as region_name '
                'FROM indicator_indicatordata i '
                'JOIN indicator_indicator ind ON i.indicator_id = ind.id '
                'JOIN geodata_city city ON i.city_id=city.id '
                'LEFT OUTER JOIN geodata_country country on city.country_id = country.code '
                'LEFT OUTER JOIN geodata_region region on country.region_id = region.code '
                'WHERE 1 %s ' % (filter_string))

            desc = cursor.description
            city_results = [
                dict(zip([col[0] for col in desc], row))
                for row in cursor.fetchall()
            ]

            for r in city_results:

                region = {}
                if r['region_id']:
                    region[r['region_id']] = r['region_name']
                    regions.update(region)

                country = {}
                if r['country_id']:
                    country[r['country_id']] = r['country_name']
                    countries.update(country)

                city = {}
                if r['city_id']:
                    city[r['city_id']] = r['city_name']
                    cities.update(city)

                if r['indicator_id']:
                    if not r['indicator_id'] in indicators:
                        indicators[r['indicator_id']] = {
                            "name": r['friendly_label'],
                            "category": r['indicator_category'],
                            "selection_types": []
                        }
                    if r['selection_type'] and r[
                            'selection_type'] not in indicators[
                                r['indicator_id']]["selection_types"]:
                        indicators[
                            r['indicator_id']]["selection_types"].append(
                                r['selection_type'])

        if "country" in adm_divisions:
            # country filters
            filter_string = ' AND (' + country_q + region_q + indicator_q + category_q + ')'
            if 'AND ()' in filter_string:
                filter_string = filter_string[:-6]
            cursor = connection.cursor()
            cursor.execute(
                'SELECT DISTINCT i.indicator_id, i.selection_type, ind.friendly_label, ind.category as indicator_category, country.code as country_id, country.name as country_name, region.code as region_id, region.name as region_name '
                'FROM indicator_indicatordata i '
                'JOIN indicator_indicator ind ON i.indicator_id = ind.id '
                'JOIN geodata_country country on i.country_id = country.code '
                'LEFT OUTER JOIN geodata_region region on country.region_id = region.code '
                'WHERE 1 %s ' % (filter_string))

            desc = cursor.description
            country_results = [
                dict(zip([col[0] for col in desc], row))
                for row in cursor.fetchall()
            ]

            for r in country_results:

                region = {}
                if r['region_id']:
                    region[r['region_id']] = r['region_name']
                    regions.update(region)

                country = {}
                if r['country_id']:
                    country[r['country_id']] = r['country_name']
                    countries.update(country)

                if r['indicator_id']:
                    if not r['indicator_id'] in indicators not in indicators[
                            r['indicator_id']]["selection_types"]:
                        indicators[r['indicator_id']] = {
                            "name": r['friendly_label'],
                            "category": r['indicator_category'],
                            "selection_types": []
                        }
                    if r['selection_type'] and r[
                            'selection_type'] not in indicators[
                                r['indicator_id']]["selection_types"]:
                        indicators[
                            r['indicator_id']]["selection_types"].append(
                                r['selection_type'])

        if "region" in adm_divisions:
            # region filters
            filter_string = ' AND (' + region_q + indicator_q + category_q + ')'
            if 'AND ()' in filter_string:
                filter_string = filter_string[:-6]
            cursor = connection.cursor()
            cursor.execute(
                'SELECT DISTINCT i.indicator_id, i.selection_type ,ind.friendly_label, ind.category as indicator_category, region.code as region_id, region.name as region_name '
                'FROM indicator_indicatordata i '
                'JOIN indicator_indicator ind ON i.indicator_id = ind.id '
                'JOIN geodata_region region on i.region_id = region.code '
                'WHERE 1 %s ' % (filter_string))

            desc = cursor.description
            region_results = [
                dict(zip([col[0] for col in desc], row))
                for row in cursor.fetchall()
            ]

            for r in region_results:

                region = {}
                if r['region_id']:
                    region[r['region_id']] = r['region_name']
                    regions.update(region)

                if r['indicator_id']:
                    if not r['indicator_id'] in indicators:
                        indicators[r['indicator_id']] = {
                            "name": r['friendly_label'],
                            "category": r['indicator_category'],
                            "selection_types": []
                        }
                    if r['selection_type'] and r[
                            'selection_type'] not in indicators[
                                r['indicator_id']]["selection_types"]:
                        indicators[
                            r['indicator_id']]["selection_types"].append(
                                r['selection_type'])

        jsondata['regions'] = regions
        jsondata['countries'] = countries
        jsondata['cities'] = cities
        jsondata['indicators'] = indicators

        return HttpResponse(ujson.dumps(jsondata),
                            content_type='application/json')
コード例 #4
0
    def get_list(self, request, **kwargs):
        helper = CustomCallHelper()
        city_q = helper.get_and_query(request, 'cities__in', 'city_id')
        country_q = helper.get_and_query(request, 'countries__in', 'c.code')
        region_q = helper.get_and_query(request, 'regions__in', 'r.code')
        year_q = helper.get_and_query(request, 'years__in', 'id.year')
        indicator_q = helper.get_and_query(request, 'indicators__in',
                                           'indicator_id')
        selection_type_q = helper.get_and_query(request, 'selection_type__in',
                                                'id.selection_type')
        limit_q = request.GET.get("limit", None)

        if limit_q:
            limit_q = int(limit_q)

        if not indicator_q and not country_q and not city_q:
            return HttpResponse(ujson.dumps("No indicator given"),
                                content_type='application/json')

        # CITY DATA
        filter_string = 'AND (' + city_q + country_q + region_q + year_q + indicator_q + selection_type_q + ')'

        if 'AND ()' in filter_string:
            filter_string = filter_string[:-6]

        cursor = connection.cursor()
        cursor.execute(
            'SELECT da.id as indicator_id, da.friendly_label, da.type_data, id.selection_type, da.category, ci.name as city_name, '
            'r.code as region_id, r.name as region_name, c.code as country_id, c.name as country_name, '
            'id.value, id.year, AsText(ci.location) as loc, ci.id as city_id '
            'FROM indicator_indicatordata id '
            'LEFT OUTER JOIN geodata_city ci ON id.city_id = ci.id '
            'LEFT OUTER JOIN geodata_country c ON ci.country_id = c.code '
            'LEFT OUTER JOIN geodata_region r ON c.region_id = r.code '
            'LEFT OUTER JOIN indicator_indicator da ON da.id = id.indicator_id '
            'WHERE id.country_id is null %s '
            'ORDER BY id.value DESC' % (filter_string))
        desc = cursor.description
        city_results = [
            dict(zip([col[0] for col in desc], row))
            for row in cursor.fetchall()
        ]

        # COUNTRY DATA
        filter_string = 'AND (' + city_q + country_q + region_q + year_q + indicator_q + selection_type_q + ')'

        if 'AND ()' in filter_string:
            filter_string = filter_string[:-6]

        cursor = connection.cursor()
        cursor.execute(
            'SELECT da.id as indicator_id, da.friendly_label, id.selection_type, da.category, da.type_data, '
            'r.code as region_id, r.name as region_name, c.code as country_id, c.name as country_name, '
            'id.value, id.year, AsText(c.center_longlat) as loc '
            'FROM indicator_indicatordata id '
            'LEFT OUTER JOIN geodata_country c ON id.country_id = c.code '
            'LEFT OUTER JOIN geodata_region r ON c.region_id = r.code '
            'LEFT OUTER JOIN indicator_indicator da ON da.id = id.indicator_id '
            'WHERE id.city_id is null %s '
            'ORDER BY id.value DESC' % (filter_string))
        desc = cursor.description
        country_results = [
            dict(zip([col[0] for col in desc], row))
            for row in cursor.fetchall()
        ]

        indicator_q = indicator_q.replace(" ) AND (", "")
        if indicator_q:
            indicator_q = "AND " + indicator_q

        cursor_max = connection.cursor()
        cursor_max.execute(
            'SELECT indicator_id, max(value) as max_value FROM indicator_indicatordata WHERE 1 %s GROUP BY indicator_indicatordata.indicator_id order by max_value DESC'
            % indicator_q)
        desc = cursor_max.description
        max_results = [
            dict(zip([col[0] for col in desc], row))
            for row in cursor_max.fetchall()
        ]

        # REGION DATA
        # NOT IMPLEMENTED YET -> WE DO NOT HAVE CENTER LOCATIONS FOR REGIONS

        geolocs = {}

        for c in country_results:

            if c['value']:
                try:
                    geolocs[c['indicator_id']]['locs'][
                        c['country_id']]['years']

                except:

                    if not c['indicator_id'] in geolocs:
                        max_value = max_results[0]['max_value']
                        geolocs[c['indicator_id']] = {
                            'indicator_friendly': c['friendly_label'],
                            'type_data': c['type_data'],
                            'indicator': c['indicator_id'],
                            'category': c['category'],
                            'selection_type': c['selection_type'],
                            'max_value': max_value,
                            'locs': {}
                        }

                    # if the amount of locs to be shown is reached, do not add the new loc
                    if limit_q:
                        if geolocs[c['indicator_id']]['locs'].__len__(
                        ) == limit_q:
                            continue

                    loc = c['loc']
                    if loc:

                        loc = loc.replace("POINT(", "")
                        loc = loc.replace(")", "")
                        loc_array = loc.split(" ")
                        longitude = loc_array[0]
                        latitude = loc_array[1]
                    else:
                        longitude = None
                        latitude = None

                    geolocs[c['indicator_id']]['locs'][c['country_id']] = {
                        'name': c['country_name'],
                        'id': c['country_id'],
                        'region_id': c['region_id'],
                        'longitude': longitude,
                        'latitude': latitude,
                        'years': {}
                    }

                geolocs[c['indicator_id']]['locs'][c['country_id']]['years'][
                    c['year']] = c['value']

        for r in city_results:

            if r['value']:
                try:
                    geolocs[r['indicator_id']]['locs'][r['city_id']]['years']
                except:

                    if not r['indicator_id'] in geolocs:
                        max_value = max_results[0]['max_value']
                        geolocs[r['indicator_id']] = {
                            'indicator_friendly': r['friendly_label'],
                            'type_data': r['type_data'],
                            'indicator': r['indicator_id'],
                            'category': r['category'],
                            'selection_type': r['selection_type'],
                            'max_value': max_value,
                            'locs': {}
                        }

                    # if the amount of locs to be shown is reached, do not add the new loc
                    if limit_q:
                        if geolocs[r['indicator_id']]['locs'].__len__(
                        ) == limit_q:
                            continue

                    loc = r['loc']
                    if loc:

                        loc = loc.replace("POINT(", "")
                        loc = loc.replace(")", "")
                        loc_array = loc.split(" ")
                        longitude = loc_array[0]
                        latitude = loc_array[1]
                    else:
                        longitude = None
                        latitude = None

                    geolocs[r['indicator_id']]['locs'][r['city_id']] = {
                        'name': r['city_name'],
                        'id': r['city_id'],
                        'country_id': r['country_id'],
                        'region_id': r['region_id'],
                        'longitude': longitude,
                        'latitude': latitude,
                        'years': {}
                    }

                geolocs[r['indicator_id']]['locs'][r['city_id']]['years'][
                    r['year']] = r['value']

        return HttpResponse(ujson.dumps(geolocs),
                            content_type='application/json')
コード例 #5
0
    def get_list(self, request, **kwargs):

        # get group by and aggregation pars
        group_by_key = request.GET.get(
            "group_by",
            None)  # valid : country, region, year, sector, reporting org
        aggregation_key = request.GET.get("aggregation_key", "iati-identifier")
        group_field = request.GET.get(
            "group_field", "start_actual"
        )  # used for year filtering, valid : start_planned, start_actual, end_planned, end_actual, defaults to start_actual
        if group_by_key in {'commitment', 'disbursement', 'incoming-fund'}:
            group_field = "t.value_date"

        aggregation_element_dict = {
            'iati-identifier': {
                'select': 'a.id',
                'type': 'count',
                'from_addition': ''
            },
            'reporting-org': {
                'select': 'a.reporting_organisation_id',
                'type': 'count',
                'from_addition': ''
            },
            'title': {
                'select': 't.title',
                'type': 'count',
                'from_addition':
                'JOIN iati_title as t on a.id = t.activity_id '
            },
            'description': {
                'select':
                'd.description',
                'type':
                'count',
                'from_addition':
                'JOIN iati_description as d on a.id = d.activity_id '
            },
            'commitment': {
                'select': 't.value',
                'type': 'sum',
                'from_addition':
                'JOIN iati_transaction as t on a.id = t.activity_id ',
                'where_addition': 'AND t.transaction_type_id = "C" '
            },
            'disbursement': {
                'select': 't.value',
                'type': 'sum',
                'from_addition':
                'JOIN iati_transaction as t on a.id = t.activity_id ',
                'where_addition': 'AND t.transaction_type_id = "D" '
            },
            'incoming-fund': {
                'select': 't.value',
                'type': 'sum',
                'from_addition':
                'JOIN iati_transaction as t on a.id = t.activity_id ',
                'where_addition': 'AND t.transaction_type_id = "IF" '
            },
            'location': {
                'select': 'l.activity_id',
                'type': 'count',
                'from_addition':
                'JOIN iati_location as l on a.id = l.activity_id '
            },
            'policy-marker': {
                'select':
                'pm.policy_marker_id',
                'type':
                'count',
                'from_addition':
                'JOIN iati_activitypolicymarker as pm on a.id = pm.activity_id '
            },
            'total-budget': {
                'select': 'a.total_budget',
                'type': 'sum',
                'from_addition': ''
            },
            # 'recipient-country': {'select': 'a.id', 'type': 'count', 'from_addition': ''},
            # 'recipient-region': {'select': 'a.id', 'type': 'count', 'from_addition': ''},
            # 'year': {'select': 'a.id', 'type': 'count', 'from_addition': ''},
            # 'sector': {'select': 'a.id', 'type': 'count', 'from_addition': ''},
        }

        group_by_element_dict = {
            'recipient-country': {
                'select':
                'rc.country_id',
                'from_addition':
                'JOIN iati_activityrecipientcountry as rc on a.id = rc.activity_id '
            },
            'recipient-region': {
                'select':
                'rr.region_id',
                'from_addition':
                'JOIN iati_activityrecipientregion as rr on a.id = rr.activity_id '
            },
            'year': {
                'select': 'YEAR(' + group_field + ')',
                'from_addition': ''
            },
            'sector': {
                'select':
                'acts.sector_id',
                'from_addition':
                'JOIN iati_activitysector as acts on a.id = acts.activity_id '
            },
            'reporting-org': {
                'select':
                'a.reporting_organisation_id',
                'from_addition':
                'JOIN iati_organisation as o on a.reporting_organisation_id = o.code '
            },
            'participating-org': {
                'select':
                'po.name',
                'from_addition':
                'JOIN iati_activityparticipatingorganisation as po on a.id = po.activity_id '
            },
            'policy-marker': {
                'select':
                'pm.policy_marker_id',
                'from_addition':
                'JOIN iati_activitypolicymarker as pm on a.id = pm.activity_id '
            },
        }

        # check if call is cached using validator.is_cached
        # check if call contains flush, if it does the call comes from the cache updater and shouldn't return cached results
        validator = Validator()
        cururl = request.META['PATH_INFO'] + "?" + request.META['QUERY_STRING']

        if not 'flush' in cururl and validator.is_cached(cururl):
            return HttpResponse(validator.get_cached_call(cururl),
                                content_type='application/json')

        helper = CustomCallHelper()
        cursor = connection.cursor()

        # get filters
        reporting_organisations = helper.get_and_query(
            request, 'reporting_organisation__in',
            'a.reporting_organisation_id')
        recipient_countries = helper.get_and_query(request, 'countries__in',
                                                   'rc.country_id')
        recipient_regions = helper.get_and_query(request, 'regions__in',
                                                 'rr.region_id')
        total_budgets = helper.get_and_query(request, 'total_budget__in',
                                             'a.total_budget')
        sectors = helper.get_and_query(request, 'sectors__in',
                                       'acts.sector_id')

        if aggregation_key in aggregation_element_dict:
            aggregation_info = aggregation_element_dict[aggregation_key]
            aggregation_key = aggregation_info["select"]
            aggregation_type = aggregation_info["type"]
            aggregation_from_addition = aggregation_info["from_addition"]
            aggregation_where_addition = ""
            if "where_addition" in aggregation_info:
                aggregation_where_addition = aggregation_info["where_addition"]
        else:

            return HttpResponse(ujson.dumps({
                "error":
                "Invalid aggregation key, see included list for viable keys.",
                "valid_aggregation_keys":
                list(aggregation_element_dict.keys())
            }),
                                content_type='application/json')

        if group_by_key in group_by_element_dict:
            group_by_info = group_by_element_dict[group_by_key]
            group_select = group_by_info["select"]
            group_from_addition = group_by_info["from_addition"]
        else:
            return HttpResponse(ujson.dumps({
                "error":
                "Invalid group by key, see included list for viable keys.",
                "valid_group_by_keys":
                list(group_by_element_dict.keys())
            }),
                                content_type='application/json')

        # make sure group key and aggregation key are set
        if not group_by_key:
            return HttpResponse(ujson.dumps(
                "No field to group by. add parameter group_by (country/region/etc.. see docs)"
            ),
                                content_type='application/json')
        if not aggregation_key:
            return HttpResponse(ujson.dumps(
                "No field to aggregate on. add parameter aggregation_key (iati-identifier/reporting-org/etc.. see docs)"
            ),
                                content_type='application/json')

        #create the query
        query_select = 'SELECT ' + aggregation_type + '(' + aggregation_key + ') as aggregation_field, ' + group_select + ' as group_field, o.name   as org_name '
        query_from = 'FROM iati_activity as a ' + aggregation_from_addition + group_from_addition
        query_where = 'WHERE 1 ' + aggregation_where_addition
        query_group_by = 'GROUP BY ' + group_select

        # fill where part
        filter_string = 'AND (' + reporting_organisations + recipient_countries + recipient_regions + total_budgets + sectors + ')'
        if filter_string == 'AND ()':
            filter_string = ""
        else:
            if 'AND ()' in filter_string:
                filter_string = filter_string[:-6]

        query_where += filter_string

        # optimalisation for simple (all) queries
        if not filter_string and query_from == 'FROM iati_activity as a ':
            if (group_by_key == "country"):
                query_select = 'SELECT count(activity_id) as aggregation_field, country_id as group_field '
                query_from = "FROM iati_activityrecipientcountry "
                query_group_by = "GROUP BY country_id"

            elif (group_by_key == "region"):
                query_select = 'SELECT count(activity_id) as aggregation_field, region_id as group_field '
                query_from = "FROM iati_activityrecipientregion "
                query_group_by = "GROUP BY region_id"

            elif (group_by_key == "sector"):
                query_select = 'SELECT count(activity_id) as aggregation_field, sector_id as group_field '
                query_from = "FROM iati_activitysector "
                query_group_by = "GROUP BY sector_id"

        # execute query

        cursor.execute(query_select + query_from + query_where +
                       query_group_by)
        results1 = helper.get_fields(cursor=cursor)

        # query result -> json output

        options = {}

        for r in results1:

            options[r['group_field']] = [r['aggregation_field'], r['org_name']]

        return HttpResponse(ujson.dumps(options),
                            content_type='application/json')
コード例 #6
0
    def get_list(self, request, **kwargs):

        # check if call is cached using validator.is_cached
        # check if call contains flush, if it does the call comes from the cache updater and shouldn't return cached results
        validator = Validator()
        cururl = request.META['PATH_INFO'] + "?" + request.META['QUERY_STRING']

        if not 'flush' in cururl and validator.is_cached(cururl):
            return HttpResponse(validator.get_cached_call(cururl),
                                content_type='application/json')

        helper = CustomCallHelper()
        cursor = connection.cursor()

        # get filters
        reporting_organisations = helper.get_and_query(
            request, 'reporting_organisation__in',
            'a.reporting_organisation_id')
        recipient_countries = helper.get_and_query(request, 'countries__in',
                                                   'rc.country_id')
        recipient_regions = helper.get_and_query(request, 'regions__in',
                                                 'rr.region_id')
        total_budgets = helper.get_and_query(request, 'total_budget__in',
                                             'a.total_budget')
        sectors = helper.get_and_query(request, 'sectors__in',
                                       'acts.sector_id')

        from_countries = False
        from_regions = False
        from_sectors = False

        if recipient_countries:
            from_countries = True
        if recipient_regions:
            from_regions = True
        if sectors:
            from_sectors = True

        # get group by pars
        group_by = request.GET.get(
            "group_by",
            None)  # valid : country, region, year, sector, reporting org
        field = request.GET.get(
            "group_field", "start_actual"
        )  # used for year filtering, valid : start_planned, start_actual, end_planned, end_actual, defaults to start_actual

        if not group_by:
            return HttpResponse(ujson.dumps(
                "No field to group by. add parameter group_by (country/region/etc.. see docs)"
            ),
                                content_type='application/json')

        #create the query
        query_select = 'SELECT count(a.id) as activity_count, '
        query_from = 'FROM iati_activity as a '
        query_where = 'WHERE 1 '
        query_group_by = 'GROUP BY '

        # fill select and group by
        if (group_by == "country"):
            query_select += 'rc.country_id as group_field '
            query_group_by += 'rc.country_id '
            from_countries = True

        elif (group_by == "region"):
            query_select += 'r.region_id as group_field '
            query_group_by += 'r.region_id '
            from_regions = True

        elif (group_by == "year"):
            query_select += 'YEAR(a.' + field + ') as group_field '
            query_group_by += 'YEAR(a.' + field + ') '

        elif (group_by == "sector"):
            query_select += 'acts.sector_id as group_field '
            query_group_by += 'acts.sector_id '
            from_sectors = True

        elif (group_by == "reporting_organisation"):
            query_select += 'a.reporting_organisation_id as group_field '
            query_group_by += 'a.reporting_organisation_id '

        # fill from part
        if from_countries:
            query_from += "JOIN iati_activityrecipientcountry as rc on a.id = rc.activity_id "
        if from_regions:
            query_from += "JOIN iati_activityrecipientregion as rr on a.id = rr.activity_id "
        if from_sectors:
            query_from += "JOIN iati_activitysector as acts on a.id = acts.activity_id "

        # fill where part
        filter_string = 'AND (' + reporting_organisations + recipient_countries + recipient_regions + total_budgets + sectors + ')'
        if filter_string == 'AND ()':
            filter_string = ""
        else:
            if 'AND ()' in filter_string:
                filter_string = filter_string[:-6]

        query_where += filter_string

        # optimalisation for simple (all) queries
        if not filter_string:
            # fill select and group by
            if (group_by == "country"):
                query_select = 'SELECT count(activity_id) as activity_count, country_id as group_field '
                query_from = "FROM iati_activityrecipientcountry "
                query_group_by = "GROUP BY country_id"

            elif (group_by == "region"):
                query_select = 'SELECT count(activity_id) as activity_count, region_id as group_field '
                query_from = "FROM iati_activityrecipientregion "
                query_group_by = "GROUP BY region_id"

            elif (group_by == "sector"):
                query_select = 'SELECT count(activity_id) as activity_count, sector_id as group_field '
                query_from = "FROM iati_activitysector "
                query_group_by = "GROUP BY sector_id"

        # execute query

        cursor.execute(query_select + query_from + query_where +
                       query_group_by)
        results1 = helper.get_fields(cursor=cursor)

        # query result -> json output

        options = {}

        for r in results1:

            options[r['group_field']] = r['activity_count']

        return HttpResponse(ujson.dumps(options),
                            content_type='application/json')
コード例 #7
0
    def get_list(self, request, **kwargs):

        # get group by and aggregation pars
        group_by_key = request.GET.get('group_by', None)
        aggregation_key = request.GET.get('aggregation_key', 'iati-identifier')
        group_field = request.GET.get('group_field', 'start_actual')
        query = request.GET.get('query', '')

        if group_by_key in {'commitment', 'disbursement', 'incoming-fund'}:
            group_field = 't.value_date'

        aggregation_element_dict = {
            'iati-identifier': {
                'select': 'a.id',
                'type': 'count',
                'from_addition': ''
            },
            'reporting-org': {
                'select': 'a.reporting_organisation_id',
                'type': 'count',
                'from_addition': ''
            },
            'title': {
                'select': 't.title',
                'type': 'count',
                'from_addition':
                'JOIN iati_title as t on a.id = t.activity_id '
            },
            'description': {
                'select':
                'd.description',
                'type':
                'count',
                'from_addition':
                'JOIN iati_description as d on a.id = d.activity_id '
            },
            'commitment': {
                'select': 't.value',
                'type': 'sum',
                'from_addition':
                'JOIN iati_transaction as t on a.id = t.activity_id ',
                'where_addition': 'AND t.transaction_type_id = "C" '
            },
            'disbursement': {
                'select': 't.value',
                'type': 'sum',
                'from_addition':
                'JOIN iati_transaction as t on a.id = t.activity_id ',
                'where_addition': 'AND t.transaction_type_id = "D" '
            },
            'expenditure': {
                'select': 't.value',
                'type': 'sum',
                'from_addition':
                'JOIN iati_transaction as t on a.id = t.activity_id ',
                'where_addition': 'AND t.transaction_type_id = "E" '
            },
            'incoming-fund': {
                'select': 't.value',
                'type': 'sum',
                'from_addition':
                'JOIN iati_transaction as t on a.id = t.activity_id ',
                'where_addition': 'AND t.transaction_type_id = "IF" '
            },
            'location': {
                'select': 'l.activity_id',
                'type': 'count',
                'from_addition':
                'JOIN iati_location as l on a.id = l.activity_id '
            },
            'policy-marker': {
                'select':
                'pm.policy_marker_id',
                'type':
                'count',
                'from_addition':
                'JOIN iati_activitypolicymarker as pm on a.id = pm.activity_id '
            },
            'total-budget': {
                'select': 'a.total_budget',
                'type': 'sum',
                'from_addition': ''
            },
        }

        group_by_element_dict = {
            'recipient-country': {
                'select':
                'rc.country_id',
                'from_addition':
                'JOIN iati_activityrecipientcountry as rc on a.id = rc.activity_id '
            },
            'recipient-region': {
                'select':
                'r.name, rr.region_id',
                'from_addition':
                'JOIN iati_activityrecipientregion as rr on a.id = rr.activity_id '
                'join geodata_region as r on rr.region_id = r.code '
            },
            'year': {
                'select': 'YEAR(' + group_field + ')',
                'from_addition': ''
            },
            'sector': {
                'select':
                'acts.sector_id',
                'from_addition':
                'JOIN iati_activitysector as acts on a.id = acts.activity_id '
            },
            'reporting-org': {
                'select': 'a.reporting_organisation_id',
                'from_addition': ''
            },
            'participating-org': {
                'select':
                'po.name',
                'from_addition':
                'JOIN iati_activityparticipatingorganisation as po on a.id = po.activity_id '
            },
            'policy-marker': {
                'select':
                'pm.policy_marker_id',
                'from_addition':
                'JOIN iati_activitypolicymarker as pm on a.id = pm.activity_id '
            },
            'r.title': {
                'select': 'r.title',
                'from_addition':
                'JOIN iati_result as r on a.id = r.activity_id ',
                'where_addition': ' AND r.title = %(query)s '
            },
        }

        helper = CustomCallHelper()
        cursor = connection.cursor()

        # get filters
        reporting_organisations = helper.get_and_query(
            request, 'reporting_organisation__in',
            'a.reporting_organisation_id')
        recipient_countries = helper.get_and_query(request, 'countries__in',
                                                   'rc.country_id')
        recipient_regions = helper.get_and_query(request, 'regions__in',
                                                 'rr.region_id')
        total_budgets = helper.get_and_query(request, 'total_budget__in',
                                             'a.total_budget')
        sectors = helper.get_and_query(request, 'sectors__in',
                                       'acts.sector_id')

        if aggregation_key in aggregation_element_dict:
            aggregation_info = aggregation_element_dict[aggregation_key]
            aggregation_key = aggregation_info["select"]
            aggregation_type = aggregation_info["type"]
            aggregation_from_addition = aggregation_info["from_addition"]
            aggregation_where_addition = ""
            if "where_addition" in aggregation_info:
                aggregation_where_addition = aggregation_info["where_addition"]
        else:
            return HttpResponse(ujson.dumps({
                "error":
                "Invalid aggregation key, see included list for viable keys.",
                "valid_aggregation_keys":
                list(aggregation_element_dict.keys())
            }),
                                content_type='application/json')

        if group_by_key in group_by_element_dict:
            group_by_info = group_by_element_dict[group_by_key]
            group_select = group_by_info["select"]
            group_from_addition = group_by_info["from_addition"]
            if "where_addition" in group_by_info and query:
                aggregation_where_addition = aggregation_where_addition.join(
                    group_by_info["where_addition"])
        else:
            return HttpResponse(ujson.dumps({
                "error":
                "Invalid group by key, see included list for viable keys.",
                "valid_group_by_keys":
                list(group_by_element_dict.keys())
            }),
                                content_type='application/json')

        # make sure group key and aggregation key are set
        if not group_by_key:
            return HttpResponse(ujson.dumps(
                "No field to group by. add parameter group_by (country/region/etc.. see docs)"
            ),
                                content_type='application/json')

        if not aggregation_key:
            return HttpResponse(ujson.dumps(
                "No field to aggregate on. add parameter aggregation_key "),
                                content_type='application/json')

        query_select = ''.join([
            'SELECT ', aggregation_type, '(', aggregation_key,
            ') as aggregation_field, ', group_select, ' as group_field '
        ])

        query_from = ''.join([
            'FROM iati_activity as a ', aggregation_from_addition,
            group_from_addition
        ])

        query_where = ''.join(['WHERE 1 ', aggregation_where_addition])

        query_group_by = ''.join(['GROUP BY ', group_select])

        # fill where part
        filter_string = ''.join([
            'AND (', reporting_organisations, recipient_countries,
            recipient_regions, total_budgets, sectors, ')'
        ])

        if filter_string == 'AND ()':
            filter_string = ""
        elif 'AND ()' in filter_string:
            filter_string = filter_string[:-6]

        query_where += filter_string

        if not filter_string and query_from == 'FROM iati_activity as a ':
            if group_by_key == "country":
                query_select = 'SELECT count(activity_id) as aggregation_field, country_id as group_field '
                query_from = "FROM iati_activityrecipientcountry "
                query_group_by = "GROUP BY country_id"

            elif group_by_key == "region":
                query_select = 'SELECT count(activity_id) as aggregation_field, region_id as group_field '
                query_from = "FROM iati_activityrecipientregion "
                query_group_by = "GROUP BY region_id"

            elif group_by_key == "sector":
                query_select = 'SELECT count(activity_id) as aggregation_field, sector_id as group_field '
                query_from = "FROM iati_activitysector "
                query_group_by = "GROUP BY sector_id"

        cursor.execute(
            query_select + query_from + query_where + query_group_by, {
                "query": query,
            })
        results1 = helper.get_fields(cursor=cursor)

        options = []
        for r in results1:
            options.append(r)

        return HttpResponse(ujson.dumps(options),
                            content_type='application/json')