11 KiB
queryset.prefetch_query
add_relation_field_to_fields
add_relation_field_to_fields(fields: Union[Set[Any], Dict[Any, Any], None], related_field_name: str) -> Union[Set[Any], Dict[Any, Any], None]
Adds related field into fields to include as otherwise it would be skipped. Related field is added only if fields are already populated. Empty fields implies all fields.
Arguments:
fields (Dict): Union[Set[Any], Dict[Any, Any], None]related_field_name (str): name of the field with relation
Returns:
(Union[Set[Any], Dict[Any, Any], None]): updated fields dict
sort_models
sort_models(models: List["Model"], orders_by: Dict) -> List["Model"]
Since prefetch query gets all related models by ids the sorting needs to happen in python. Since by default models are already sorted by id here we resort only if order_by parameters was set.
Arguments:
models (List[tests.test_prefetch_related.Division]): list of models already fetched from dborders_by (Dict[str, str]): order by dictionary
Returns:
(List[tests.test_prefetch_related.Division]): sorted list of models
set_children_on_model
set_children_on_model(model: "Model", related: str, children: Dict, model_id: int, models: Dict, orders_by: Dict) -> None
Extract ids of child models by given relation id key value.
Based on those ids the actual children model instances are fetched from already fetched data.
If needed the child models are resorted according to passed orders_by dict.
Also relation is registered as each child is set as parent related field name value.
Arguments:
model (Model): parent model instancerelated (str): name of the related fieldchildren (Dict[int, set]): dictionary of children ids/ related field valuemodel_id (int): id of the model on which children should be setmodels (Dict): dictionary of child models instancesorders_by (Dict): order_by dictionary
PrefetchQuery Objects
class PrefetchQuery()
Query used to fetch related models in subsequent queries. Each model is fetched only ones by the name of the relation. That means that for each prefetch_related entry next query is issued to database.
prefetch_related
| async prefetch_related(models: Sequence["Model"], rows: List) -> Sequence["Model"]
Main entry point for prefetch_query.
Receives list of already initialized parent models with all children from select_related already populated. Receives also list of row sql result rows as it's quicker to extract ids that way instead of calling each model.
Returns list with related models already prefetched and set.
Arguments:
models (List[Model]): list of already instantiated models from main queryrows (List[sqlalchemy.engine.result.RowProxy]): row sql result of the main query before the prefetch
Returns:
(List[Model]): list of models with children prefetched
_extract_ids_from_raw_data
| _extract_ids_from_raw_data(parent_model: Type["Model"], column_name: str) -> Set
Iterates over raw rows and extract id values of relation columns by using prefixed column name.
Arguments:
parent_model (Type[Model]): ormar model classcolumn_name (str): name of the relation column which is a key column
Returns:
(set): set of ids of related model that should be extracted
_extract_ids_from_preloaded_models
| _extract_ids_from_preloaded_models(parent_model: Type["Model"], column_name: str) -> Set
Extracts relation ids from already populated models if they were included in the original query before.
Arguments:
parent_model (Type["Model"]): model from which related ids should be extractedcolumn_name (str): name of the relation column which is a key column
Returns:
(set): set of ids of related model that should be extracted
_extract_required_ids
| _extract_required_ids(parent_model: Type["Model"], reverse: bool, related: str) -> Set
Delegates extraction of the fields to either get ids from raw sql response or from already populated models.
Arguments:
parent_model (Type["Model"]): model from which related ids should be extractedreverse (bool): flag if the relation is reverserelated (str): name of the field with relation
Returns:
(set): set of ids of related model that should be extracted
_get_filter_for_prefetch
| _get_filter_for_prefetch(parent_model: Type["Model"], target_model: Type["Model"], reverse: bool, related: str) -> List
Populates where clause with condition to return only models within the set of extracted ids.
If there are no ids for relation the empty list is returned.
Arguments:
parent_model (Type["Model"]): model from which related ids should be extractedtarget_model (Type["Model"]): model to which relation leads toreverse (bool): flag if the relation is reverserelated (str): name of the field with relation
Returns:
(List[sqlalchemy.sql.elements.TextClause]):
_populate_nested_related
| _populate_nested_related(model: "Model", prefetch_dict: Dict, orders_by: Dict) -> "Model"
Populates all related models children of parent model that are included in prefetch query.
Arguments:
model (Model): ormar model instanceprefetch_dict (Dict): dictionary of models to prefetchorders_by (Dict): dictionary of order bys
Returns:
(Model): model with children populated
_prefetch_related_models
| async _prefetch_related_models(models: Sequence["Model"], rows: List) -> Sequence["Model"]
Main method of the query.
Translates select nad prefetch list into dictionaries to avoid querying the same related models multiple times.
Keeps the list of already extracted models.
Extracts the related models from the database and later populate all children on each of the parent models from list.
Arguments:
models (List[Model]): list of parent models from main queryrows (List[sqlalchemy.engine.result.RowProxy]): raw response from sql query
Returns:
(List[Model]): list of models with prefetch children populated
_extract_related_models
| async _extract_related_models(related: str, target_model: Type["Model"], prefetch_dict: Dict, select_dict: Dict, fields: Union[Set[Any], Dict[Any, Any], None], exclude_fields: Union[Set[Any], Dict[Any, Any], None], orders_by: Dict) -> None
Constructs queries with required ids and extracts data with fields that should be included/excluded.
Runs the queries against the database and populated dictionaries with ids and with actual extracted children models.
Calls itself recurrently to extract deeper nested relations of related model.
Arguments:
related (str): name of the relationtarget_model (Type[Model]): model to which relation leads toprefetch_dict (Dict): prefetch related list converted into dictionaryselect_dict (Dict): select related list converted into dictionaryfields (Union[Set[Any], Dict[Any, Any], None]): fields to includeexclude_fields (Union[Set[Any], Dict[Any, Any], None]): fields to excludeorders_by (Dict): dictionary of order bys clauses
Returns:
(None): None
_run_prefetch_query
| async _run_prefetch_query(target_field: Type["BaseField"], fields: Union[Set[Any], Dict[Any, Any], None], exclude_fields: Union[Set[Any], Dict[Any, Any], None], filter_clauses: List) -> Tuple[str, List]
Actually runs the queries against the database and populates the raw response for given related model.
Returns table prefix as it's later needed to eventually initialize the children models.
Arguments:
target_field (Type["BaseField"]): ormar field with relation definitionfields (Union[Set[Any], Dict[Any, Any], None]): fields to includeexclude_fields (Union[Set[Any], Dict[Any, Any], None]): fields to excludefilter_clauses (List[sqlalchemy.sql.elements.TextClause]): list of clauses, actually one clause with ids of relation
Returns:
(Tuple[str, List]): table prefix and raw rows from sql response
_get_select_related_if_apply
| @staticmethod
| _get_select_related_if_apply(related: str, select_dict: Dict) -> Dict
Extract nested related of select_related dictionary to extract models nested deeper on related model and already loaded in select related query.
Arguments:
related (str): name of the relationselect_dict (Dict): dictionary of select related models in main query
Returns:
(Dict): dictionary with nested related of select related
_update_already_loaded_rows
| _update_already_loaded_rows(target_field: Type["BaseField"], prefetch_dict: Dict, orders_by: Dict) -> None
Updates models that are already loaded, usually children of children.
Arguments:
target_field (Type["BaseField"]): ormar field with relation definitionprefetch_dict (Dict): dictionaries of related models to prefetchorders_by (Dict): dictionary of order by clauses by model
_populate_rows
| _populate_rows(rows: List, target_field: Type["ForeignKeyField"], parent_model: Type["Model"], table_prefix: str, fields: Union[Set[Any], Dict[Any, Any], None], exclude_fields: Union[Set[Any], Dict[Any, Any], None], prefetch_dict: Dict, orders_by: Dict) -> None
Instantiates children models extracted from given relation.
Populates them with their own nested children if they are included in prefetch query.
Sets the initialized models and ids of them under corresponding keys in already_extracted dictionary. Later those instances will be fetched by ids and set on the parent model after sorting if needed.
Arguments:
rows (List[sqlalchemy.engine.result.RowProxy]): raw sql response from the prefetch querytarget_field (Type["BaseField"]): field with relation definition from parent modelparent_model (Type[Model]): model with relation definitiontable_prefix (str): prefix of the target table from current relationfields (Union[Set[Any], Dict[Any, Any], None]): fields to includeexclude_fields (Union[Set[Any], Dict[Any, Any], None]): fields to excludeprefetch_dict (Dict): dictionaries of related models to prefetchorders_by (Dict): dictionary of order by clauses by model