def add_bucket_field_to_query(self, q, q_entities, field, field_entity): # Get min, max if not provided. field_min = 0 field_max = 0 if not field.has_key("min") or not field.has_key("max"): field_min, field_max = self.get_field_min_max(field) # Override calculated min/max if values were provided. if field.has_key("min"): field_min = field.get("min") if field.has_key("max"): field_max = field.get("max") num_buckets = field.get("num_buckets", 10) # Get bucket width. bucket_width = (field_max - field_min) / num_buckets # Get bucket field entities. # Bit of a trick here: we use field_max - bucket_width because normally last bucket gets all values >= field_max. # Here we use one less bucket, and then filter. This essentially makes the last bucket include values <= field_max. bucket_entity = func.width_bucket(field_entity, field_min, field_max - bucket_width, num_buckets - 1) q = q.filter(field_entity <= field_max) bucket_label_entity = ( cast(field_min + (bucket_entity - 1) * bucket_width, String) + " to " + cast(field_min + bucket_entity * bucket_width, String) ) bucket_label_entity = bucket_label_entity.label(field["label"]) q_entities.add(bucket_label_entity) return q, bucket_label_entity
def add_bucket_grouping_to_query(self, q, q_entities, entity, mapped_entity): # Get min, max if not provided. entity_min = 0 entity_max = 0 if (not entity.has_key('min') or not entity.has_key('max')): entity_min, entity_max = self.get_entity_min_max(entity) # Override calculated min/max if values were provided. if entity.has_key('min'): entity_min = entity.get('min') if entity.has_key('max'): entity_max = entity.get('max') num_buckets = entity.get('num_buckets', 10) entity_range = entity_max - entity_min bucket_width = (entity_max - entity_min)/float(num_buckets) # Get bucket field entities. # Can use the line below in case db doesn't have width_bucket function. #bucket_id_entity = func.greatest(func.round( (((mapped_entity - entity_min)/entity_range) * num_buckets ) - .5) + 1, num_buckets).label(self.get_bucket_id_label(entity)) bucket_id_entity = func.width_bucket(mapped_entity, entity_min, entity_max, num_buckets).label(self.get_bucket_id_label(entity)) q_entities.add(bucket_id_entity) bucket_label_entity = case( [(bucket_id_entity == num_buckets + 1, '[' + cast( entity_max, String) + ', ...)')], else_ = '[' + cast(entity_min + bucket_width * (bucket_id_entity - 1), String ) + ', ' + cast(entity_min + bucket_width * (bucket_id_entity), String) + ')' ).label(entity['label']) q_entities.add(bucket_id_entity) q_entities.add(bucket_label_entity) q = q.group_by(column(bucket_id_entity._label), column(bucket_label_entity._label)) return q