def query(self, entity, limit=None, offset=0, limit_fields=None, order_by=None, desc=False, filters={}, substring_filters=[], search_related=False, related_field_names=None, **kw): if '_id' in filters: try: filters['_id'] = ObjectId(filters['_id']) except InvalidId: pass if search_related: # Values for related fields contain the text to search filters = self._modify_params_for_related_searches(entity, filters, view_names=related_field_names, substrings=substring_filters) filters = self._modify_params_for_relationships(entity, filters) for field in substring_filters: if self.is_string(entity, field): filters[field] = {'$regex': re.compile(re.escape(filters[field]), re.IGNORECASE)} iter = entity.query.find(filters) if offset: iter = iter.skip(int(offset)) if limit is not None: iter = iter.limit(int(limit)) if order_by is not None: if not isinstance(order_by, (tuple, list)): order_by = [order_by] if not isinstance(desc, (tuple, list)): desc = [desc] sorting = [(field, DESCENDING if sort_descending else ASCENDING) for field, sort_descending in zip_longest(order_by, desc)] iter.sort(sorting) count = iter.count() return count, iter.all()
def query(self, entity, limit=None, offset=0, limit_fields=None, order_by=None, desc=False, filters={}, substring_filters=[], search_related=False, related_field_names=None, **kw): if '_id' in filters: try: filters['_id'] = ObjectId(filters['_id']) except InvalidId: pass if search_related: # Values for related fields contain the text to search filters = self._modify_params_for_related_searches(entity, filters, view_names=related_field_names, substrings=substring_filters) filters = self._modify_params_for_relationships(entity, filters) for field in substring_filters: if self.is_string(entity, field): filters[field] = {'$regex': re.compile(re.escape(filters[field]), re.IGNORECASE)} count = entity.query.find(filters).count() pipeline = [] if filters: pipeline.append({'$match': filters}) discarded = [] if order_by is not None: if not isinstance(order_by, (tuple, list)): order_by = [order_by] if not isinstance(desc, (tuple, list)): desc = [desc] sorting = SON() for sort_by, sort_descending in zip_longest(order_by, desc): sort_order = DESCENDING if sort_descending else ASCENDING if self.is_relation(entity, sort_by): relationship = getattr(entity, sort_by) join = relationship.join my_foreign_key = relationship._detect_foreign_keys(relationship.mapper, join.rel_cls, False) rel_foreign_key = relationship._detect_foreign_keys(mapper(relationship.related), join.own_cls, False) related_col_name = mapper(relationship.related).collection.m.collection_name embedded_results_field = '__%s_%s' % (related_col_name, uuid.uuid4().hex) discarded.append(embedded_results_field) if my_foreign_key: pipeline.append({'$lookup': { 'from': related_col_name, 'localField': my_foreign_key[0].name, 'foreignField': '_id', 'as': embedded_results_field }}) else: pipeline.append({'$lookup': { 'from': related_col_name, 'localField': '_id', 'foreignField': rel_foreign_key[0].name, 'as': embedded_results_field }}) sorting['%s.%s' % ( embedded_results_field, self.get_view_field_name(relationship.related, related_field_names or []) )] = sort_order else: sorting[sort_by] = sort_order if sorting: pipeline.append({'$sort': sorting}) if offset: pipeline.append({'$skip': int(offset)}) if limit is not None: pipeline.append({'$limit': int(limit)}) if discarded: pipeline.append({'$project': {f: False for f in discarded}}) results = ODMCursor(self.session, entity, entity.query.aggregate(pipeline)) return count, results.all()
def query(self, entity, limit=None, offset=None, limit_fields=None, order_by=None, desc=False, filters={}, substring_filters=[], search_related=False, related_field_names=None, **kw): entity = resolve_entity(entity) query = self.session.query(entity) filters = self._modify_params_for_dates(entity, filters) if search_related: # Values for related fields contain the text to search filters = self._modify_params_for_related_searches( entity, filters, view_names=related_field_names, substrings=substring_filters) else: # Values for related fields contain the primary key filters = self._modify_params_for_relationships(entity, filters) for field_name, value in filters.items(): field = getattr(entity, field_name) if self.is_relation(entity, field_name) and isinstance( value, list): related_class = self._get_related_class(entity, field_name) related_pk = self.get_primary_field(related_class) related_pk_col = getattr(related_class, related_pk) related_pk_values = (getattr(v, related_pk) for v in value) if self._relates_many(entity, field_name): field_filter = field.any( related_pk_col.in_(related_pk_values)) else: field_filter = field.has( related_pk_col.in_(related_pk_values)) query = query.filter(field_filter) elif field_name in substring_filters and self.is_string( entity, field_name): escaped_value = self._escape_like(value.lower()) query = query.filter( func.lower(field).contains(escaped_value, escape='*')) else: query = query.filter(field == value) count = query.count() if order_by is not None: if not isinstance(order_by, (tuple, list)): order_by = [order_by] if not isinstance(desc, (tuple, list)): desc = [desc] for sort_by, sort_descending in zip_longest(order_by, desc): if self.is_relation(entity, sort_by): mapper = class_mapper(entity) class_ = self._get_related_class(entity, sort_by) query = query.outerjoin(sort_by) f = self.get_view_field_name(class_, related_field_names) field = self.get_field(class_, f) else: field = self.get_field(entity, sort_by) if sort_descending: field = _desc(field) query = query.order_by(field) if offset is not None: query = query.offset(offset) if limit is not None: query = query.limit(limit) objs = query.all() return count, objs
def query(self, entity, limit=None, offset=None, limit_fields=None, order_by=None, desc=False, filters={}, substring_filters=[], search_related=False, related_field_names=None, **kw): entity = resolve_entity(entity) query = self.session.query(entity) filters = self._modify_params_for_dates(entity, filters) if search_related: # Values for related fields contain the text to search filters = self._modify_params_for_related_searches(entity, filters, view_names=related_field_names, substrings=substring_filters) else: # Values for related fields contain the primary key filters = self._modify_params_for_relationships(entity, filters) for field_name, value in filters.items(): field = getattr(entity, field_name) if self.is_relation(entity, field_name) and isinstance(value, list): related_class = self._get_related_class(entity, field_name) related_pk = self.get_primary_field(related_class) related_pk_col = getattr(related_class, related_pk) related_pk_values = (getattr(v, related_pk) for v in value) if self._relates_many(entity, field_name): field_filter = field.any(related_pk_col.in_(related_pk_values)) else: field_filter = field.has(related_pk_col.in_(related_pk_values)) query = query.filter(field_filter) elif field_name in substring_filters and self.is_string(entity, field_name): escaped_value = self._escape_like(value.lower()) query = query.filter(func.lower(field).contains(escaped_value, escape='*')) else: query = query.filter(field==value) count = query.count() if order_by is not None: if not isinstance(order_by, (tuple, list)): order_by = [order_by] if not isinstance(desc, (tuple, list)): desc = [desc] for sort_by, sort_descending in zip_longest(order_by, desc): if self.is_relation(entity, sort_by): mapper = class_mapper(entity) class_ = self._get_related_class(entity, sort_by) query = query.outerjoin(sort_by) f = self.get_view_field_name(class_, related_field_names) field = self.get_field(class_, f) else: field = self.get_field(entity, sort_by) if sort_descending: field = _desc(field) query = query.order_by(field) if offset is not None: query = query.offset(offset) if limit is not None: query = query.limit(limit) objs = query.all() return count, objs
def query(self, entity, limit=None, offset=0, limit_fields=None, order_by=None, desc=False, filters={}, substring_filters=[], search_related=False, related_field_names=None, **kw): if '_id' in filters: try: filters['_id'] = ObjectId(filters['_id']) except InvalidId: pass if search_related: # Values for related fields contain the text to search filters = self._modify_params_for_related_searches( entity, filters, view_names=related_field_names, substrings=substring_filters) filters = self._modify_params_for_relationships(entity, filters) for field in substring_filters: if self.is_string(entity, field): filters[field] = { '$regex': re.compile(re.escape(filters[field]), re.IGNORECASE) } count = entity.query.find(filters).count() pipeline = [] if filters: pipeline.append({'$match': filters}) discarded = [] if order_by is not None: if not isinstance(order_by, (tuple, list)): order_by = [order_by] if not isinstance(desc, (tuple, list)): desc = [desc] sorting = SON() for sort_by, sort_descending in zip_longest(order_by, desc): sort_order = DESCENDING if sort_descending else ASCENDING if self.is_relation(entity, sort_by): relationship = getattr(entity, sort_by) join = relationship.join my_foreign_key = relationship._detect_foreign_keys( relationship.mapper, join.rel_cls, False) rel_foreign_key = relationship._detect_foreign_keys( mapper(relationship.related), join.own_cls, False) related_col_name = mapper( relationship.related).collection.m.collection_name embedded_results_field = '__%s_%s' % (related_col_name, uuid.uuid4().hex) discarded.append(embedded_results_field) if my_foreign_key: pipeline.append({ '$lookup': { 'from': related_col_name, 'localField': my_foreign_key[0].name, 'foreignField': '_id', 'as': embedded_results_field } }) else: pipeline.append({ '$lookup': { 'from': related_col_name, 'localField': '_id', 'foreignField': rel_foreign_key[0].name, 'as': embedded_results_field } }) sorting['%s.%s' % (embedded_results_field, self.get_view_field_name( relationship.related, related_field_names or []))] = sort_order else: sorting[sort_by] = sort_order if sorting: pipeline.append({'$sort': sorting}) if offset: pipeline.append({'$skip': int(offset)}) if limit is not None: pipeline.append({'$limit': int(limit)}) if discarded: pipeline.append({'$project': {f: False for f in discarded}}) results = ODMCursor(self.session, entity, entity.query.aggregate(pipeline)) return count, results.all()