Exemple #1
0
    def sort_query(self, query, sort_info):
        """Sort query according to jsonapi 1.0

        :param Query query: sqlalchemy query to sort
        :param list sort_info: sort information
        :return Query: the sorted query
        """
        for sort_opt in sort_info:
            field = sort_opt['field']
            if sort_opt.get('relationship'):
                current_schema = self.resource.schema
                for obj in sort_opt['relationship'].split('.'):
                    current_schema = get_related_schema(current_schema, obj)

                    if not hasattr(current_schema.Meta, 'model'):
                        raise InvalidSort("In order to sort on a relationship, meta model must be defined")

                    relationship_model = current_schema.Meta.model
                    query = query.join(relationship_model)


                relationship_model = current_schema.Meta.model
                model_field = get_model_field(current_schema, sort_opt['field'])
                query = query.order_by(getattr(getattr(relationship_model, model_field), sort_opt['order'])())
            elif not hasattr(self.model, field):
                raise InvalidSort("{} has no attribute {}".format(self.model.__name__, field))
            else:
                query = query.order_by(getattr(getattr(self.model, field), sort_opt['order'])())
        return query
Exemple #2
0
    def eagerload_includes(self, query, qs):
        """Use eagerload feature of sqlalchemy to optimize data retrieval for include querystring parameter

        :param Query query: sqlalchemy queryset
        :param QueryStringManager qs: a querystring manager to retrieve information from url
        :return Query: the query with includes eagerloaded
        """
        for include in qs.include:
            joinload_object = None

            if '.' in include:
                current_schema = self.resource.schema
                for obj in include.split('.'):
                    try:
                        field = get_model_field(current_schema, obj)
                    except Exception as e:
                        raise InvalidInclude(str(e))

                    if joinload_object is None:
                        joinload_object = joinedload(field, innerjoin=True)
                    else:
                        joinload_object = joinload_object.joinedload(
                            field, innerjoin=True)

                    related_schema_cls = get_related_schema(
                        current_schema, obj)

                    if isinstance(related_schema_cls, SchemaABC):
                        related_schema_cls = related_schema_cls.__class__
                    else:
                        related_schema_cls = class_registry.get_class(
                            related_schema_cls)

                    current_schema = related_schema_cls
            else:
                try:
                    field = get_model_field(self.resource.schema, include)
                except Exception as e:
                    raise InvalidInclude(str(e))

                joinload_object = joinedload(field, innerjoin=True)

            query = query.options(joinload_object)

        return query