async def first(self, **kwargs: Any) -> "Model": """ Gets the first row from the db ordered by primary key column ascending. :raises NoMatch: if no rows are returned :raises MultipleMatches: if more than 1 row is returned. :param kwargs: fields names and proper value types :type kwargs: Any :return: returned model :rtype: Model """ if kwargs: return await self.filter(**kwargs).first() expr = self.build_select_expression( limit=1, order_bys=[ OrderAction( order_str=f"{self.model.Meta.pkname}", model_cls=self.model_cls, # type: ignore ) ] + self.order_bys, ) rows = await self.database.fetch_all(expr) processed_rows = self._process_query_result_rows(rows) if self._prefetch_related and processed_rows: processed_rows = await self._prefetch_related_models( processed_rows, rows) self.check_single_result_rows_count(processed_rows) return processed_rows[0] # type: ignore
def order_by(self, columns: Union[List, str, OrderAction]) -> "QuerySet[T]": """ With `order_by()` you can order the results from database based on your choice of fields. You can provide a string with field name or list of strings with fields names. Ordering in sql will be applied in order of names you provide in order_by. By default if you do not provide ordering `ormar` explicitly orders by all primary keys If you are sorting by nested models that causes that the result rows are unsorted by the main model `ormar` will combine those children rows into one main model. The main model will never duplicate in the result To order by main model field just provide a field name To sort on nested models separate field names with dunder '__'. You can sort this way across all relation types -> `ForeignKey`, reverse virtual FK and `ManyToMany` fields. To sort in descending order provide a hyphen in front of the field name :param columns: columns by which models should be sorted :type columns: Union[List, str] :return: QuerySet :rtype: QuerySet """ if not isinstance(columns, list): columns = [columns] orders_by = [ OrderAction(order_str=x, model_cls=self.model_cls) # type: ignore if not isinstance(x, OrderAction) else x for x in columns ] order_bys = self.order_bys + [ x for x in orders_by if x not in self.order_bys ] return self.rebuild_self(order_bys=order_bys, )
async def get(self, *args: Any, **kwargs: Any) -> "T": """ Get's the first row from the db meeting the criteria set by kwargs. If no criteria set it will return the last row in db sorted by pk. Passing a criteria is actually calling filter(*args, **kwargs) method described below. :raises NoMatch: if no rows are returned :raises MultipleMatches: if more than 1 row is returned. :param kwargs: fields names and proper value types :type kwargs: Any :return: returned model :rtype: Model """ if kwargs or args: return await self.filter(*args, **kwargs).get() if not self.filter_clauses: expr = self.build_select_expression( limit=1, order_bys=[ OrderAction( order_str=f"-{self.model.Meta.pkname}", model_cls=self.model_cls, # type: ignore ) ] + self.order_bys, ) else: expr = self.build_select_expression() rows = await self.database.fetch_all(expr) processed_rows = self._process_query_result_rows(rows) if self._prefetch_related and processed_rows: processed_rows = await self._prefetch_related_models( processed_rows, rows) self.check_single_result_rows_count(processed_rows) return processed_rows[0] # type: ignore