From 279d3966b1e7bc60b23c38f165bcab8f2c1c5526 Mon Sep 17 00:00:00 2001 From: collerek Date: Thu, 27 Aug 2020 11:04:49 +0200 Subject: [PATCH] liniting and missin type annots --- .coverage | Bin 53248 -> 53248 bytes ormar/models/__init__.py | 6 +++--- ormar/models/model.py | 37 +++++++++++++++++++++++++-------- ormar/models/modelproxy.py | 10 ++++----- ormar/models/newbasemodel.py | 2 +- ormar/queryset/query.py | 6 +++++- ormar/relations.py | 39 +++++++++++++++++++---------------- 7 files changed, 63 insertions(+), 37 deletions(-) diff --git a/.coverage b/.coverage index 6c4c46660b6bd8578aefb2379417f44b551754f5..350ca4de7553b2794dec37b4a604f3e941d04af5 100644 GIT binary patch delta 343 zcmV-d0jU0fpaX!Q1F$783O67zF*-0bIx#e}FE7_nHn#u|`48$3-Vf6c$Pc&=pbvKs zZx2ilF%KyZ3l8lL(hjl?oDPK!eGYF9Jq{oZ`wis{&<(e<5fFO~le&#}56Ag$bI#3k z_Ods7*~?!3lR%Cbf8+oDZT|1w-R}JBojdpTp8wrB|DF8ZdHZ|}6a)bY8Wi4|Z@zPK z!v+%s0SOKh3KbFr0SPP;*8FX@@0-^4e_j9D-+TK$6cGdg2`UkGF?s*?_iz8(`yTu4 z_g)?l1OW*?5Pmx`=RWt%_jdk#`o7;={O{R&e+l0HyMGxE83X|dG!NRvXTP`Z?sc}* z-?x9Y@2>aTb{~`Pj#(+4@!Xtkvmpuu0SQD34gl{LU;#k?i~GvW`Pce?-{*I?{QtK< pw|DC|lW>nQ7#0Tv0SPV#>f%lI|NoQk?)&@SAMg1+53{(BNI)*mqpAP^ delta 322 zcmV-I0lof!paX!Q1F$783N|1zGCDFcIx#b|FE7_nHo5>0`48$3-Vf6c$Pc&=p$~Wu za1TxoGY=~d4G!-P)DE)_oeqc&fDUpFKn^1f{tf62(+#?_5fFY2ledj`4|D$8oOAP> zUw-q;FTeZ&lRb_Y8u`C}oBw-v@6Ny8xpQyt`QM%M-^t&dx6cQYZ;lpc6A}ag2`CcQ z{B5@Ho4@Ya{@!oj2NV$m0SPJ*?qc%(?eE|IxA#5!?e|_E5Cj1UKoEYrm~)@&Z+dU% z_v!n7Z*jk$z4uFa`|th%84m;j2{aGd#b>{_?p|k0{eAma`|f(bZTA6_?T%R}Z9F$; z+gKn91OW*`3Jw787hnNE|BJia>|g8ueV^am^8erd+}^Ff%lI U|NoQk?)(0Iyyy2kv$&5)KpqL4H~;_u diff --git a/ormar/models/__init__.py b/ormar/models/__init__.py index c0592aa..e6d8bd5 100644 --- a/ormar/models/__init__.py +++ b/ormar/models/__init__.py @@ -1,5 +1,5 @@ -from ormar.models.newbasemodel import NewBaseModel -from ormar.models.model import Model -from ormar.models.metaclass import expand_reverse_relationships +from ormar.models.newbasemodel import NewBaseModel # noqa I100 +from ormar.models.model import Model # noqa I100 +from ormar.models.metaclass import expand_reverse_relationships # noqa I100 __all__ = ["NewBaseModel", "Model", "expand_reverse_relationships"] diff --git a/ormar/models/model.py b/ormar/models/model.py index 5fc6635..1b40edb 100644 --- a/ormar/models/model.py +++ b/ormar/models/model.py @@ -7,7 +7,7 @@ import ormar.queryset # noqa I100 from ormar.models import NewBaseModel # noqa I100 -def group_related_list(list_): +def group_related_list(list_: List) -> dict: test_dict = dict() grouped = itertools.groupby(list_, key=lambda x: x.split("__")[0]) for key, group in grouped: @@ -45,6 +45,23 @@ class Model(NewBaseModel): ) previous_table = cls.Meta.table.name + + item = cls.populate_nested_models_from_row( + item, row, related_models, previous_table + ) + item = cls.extract_prefixed_table_columns(item, row, table_prefix) + + instance = cls(**item) if item.get(cls.Meta.pkname, None) is not None else None + return instance + + @classmethod + def populate_nested_models_from_row( + cls, + item: dict, + row: sqlalchemy.engine.ResultProxy, + related_models: Any, + previous_table: sqlalchemy.Table, + ) -> dict: for related in related_models: if isinstance(related_models, dict) and related_models[related]: first_part, remainder = related, related_models[related] @@ -58,14 +75,18 @@ class Model(NewBaseModel): child = model_cls.from_row(row, previous_table=previous_table) item[related] = child + return item + + @classmethod + def extract_prefixed_table_columns( + cls, item: dict, row: sqlalchemy.engine.result.ResultProxy, table_prefix: str + ) -> dict: for column in cls.Meta.table.columns: if column.name not in item: item[column.name] = row[ f'{table_prefix + "_" if table_prefix else ""}{column.name}' ] - - instance = cls(**item) if item.get(cls.Meta.pkname, None) is not None else None - return instance + return item async def save(self) -> "Model": self_fields = self._extract_model_db_fields() @@ -85,11 +106,9 @@ class Model(NewBaseModel): self_fields = self._extract_model_db_fields() self_fields.pop(self.Meta.pkname) - expr = ( - self.Meta.table.update() - .values(**self_fields) - .where(self.pk_column == getattr(self, self.Meta.pkname)) - ) + expr = self.Meta.table.update().values(**self_fields) + expr = expr.where(self.pk_column == getattr(self, self.Meta.pkname)) + await self.Meta.database.execute(expr) return self diff --git a/ormar/models/modelproxy.py b/ormar/models/modelproxy.py index 83b6d09..8a99de8 100644 --- a/ormar/models/modelproxy.py +++ b/ormar/models/modelproxy.py @@ -1,6 +1,5 @@ -import copy import inspect -from typing import List, Set, TYPE_CHECKING +from typing import List, Optional, Set, TYPE_CHECKING import ormar from ormar.fields.foreign_key import ForeignKeyField @@ -80,11 +79,12 @@ class ModelTableProxy: return self_fields @staticmethod - def resolve_relation_name(item: "Model", related: "Model"): + def resolve_relation_name(item: "Model", related: "Model") -> Optional[str]: for name, field in item.Meta.model_fields.items(): if issubclass(field, ForeignKeyField): - # fastapi is creating clones of response model that's why it can be a subclass - # of the original one so we need to compare Meta too + # fastapi is creating clones of response model + # that's why it can be a subclass of the original model + # so we need to compare Meta too as this one is copied as is if field.to == related.__class__ or field.to.Meta == related.Meta: return name diff --git a/ormar/models/newbasemodel.py b/ormar/models/newbasemodel.py index fca1bbd..af5b295 100644 --- a/ormar/models/newbasemodel.py +++ b/ormar/models/newbasemodel.py @@ -153,7 +153,7 @@ class NewBaseModel(pydantic.BaseModel, ModelTableProxy, metaclass=ModelMetaclass def pk_type(cls) -> Any: return cls.Meta.model_fields[cls.Meta.pkname].__type__ - def remove(self, name: "Model"): + def remove(self, name: "Model") -> None: self._orm.remove_parent(self, name) def dict( # noqa A003 diff --git a/ormar/queryset/query.py b/ormar/queryset/query.py index 8271887..e216f07 100644 --- a/ormar/queryset/query.py +++ b/ormar/queryset/query.py @@ -46,9 +46,13 @@ class Query: def relation_manager(self) -> AliasManager: return self.model_cls.Meta.alias_manager + @property + def prefixed_pk_name(self) -> str: + return f"{self.table.name}.{self.model_cls.Meta.pkname}" + def build_select_expression(self) -> Tuple[sqlalchemy.sql.select, List[str]]: self.columns = list(self.table.columns) - self.order_bys = [text(f"{self.table.name}.{self.model_cls.Meta.pkname}")] + self.order_bys = [text(self.prefixed_pk_name)] self.select_from = self.table self._select_related.sort(key=lambda item: (item, -len(item))) diff --git a/ormar/relations.py b/ormar/relations.py index f9113ad..d8c597e 100644 --- a/ormar/relations.py +++ b/ormar/relations.py @@ -2,16 +2,17 @@ import string import uuid from enum import Enum from random import choices -from typing import List, TYPE_CHECKING, Type, Union, Optional +from typing import List, Optional, TYPE_CHECKING, Type, Union from weakref import proxy import sqlalchemy from sqlalchemy import text -import ormar -from ormar.exceptions import RelationshipInstanceError +import ormar # noqa I100 +from ormar.exceptions import RelationshipInstanceError # noqa I100 from ormar.fields.foreign_key import ForeignKeyField # noqa I100 + if TYPE_CHECKING: # pragma no cover from ormar.models import Model @@ -51,20 +52,20 @@ class AliasManager: class RelationProxy(list): - def __init__(self, relation: "Relation"): + def __init__(self, relation: "Relation") -> None: super(RelationProxy, self).__init__() self.relation = relation self._owner = self.relation.manager.owner - def remove(self, item: "Model"): + def remove(self, item: "Model") -> None: super().remove(item) rel_name = item.resolve_relation_name(item, self._owner) item._orm._get(rel_name).remove(self._owner) - def append(self, item: "Model"): + def append(self, item: "Model") -> None: super().append(item) - def add(self, item): + def add(self, item: "Model") -> None: rel_name = item.resolve_relation_name(item, self._owner) setattr(item, rel_name, self._owner) @@ -78,7 +79,7 @@ class Relation: RelationProxy(relation=self) if type_ == RelationType.REVERSE else None ) - def _find_existing(self, child) -> Optional[int]: + def _find_existing(self, child: "Model") -> Optional[int]: for ind, relation_child in enumerate(self.related_models[:]): try: if relation_child.__same__(child): @@ -114,14 +115,14 @@ class Relation: def get(self) -> Union[List["Model"], "Model"]: return self.related_models - def __repr__(self): # pragma no cover + def __repr__(self) -> str: # pragma no cover return str(self.related_models) class RelationsManager: def __init__( self, related_fields: List[Type[ForeignKeyField]] = None, owner: "Model" = None - ): + ) -> None: self.owner = owner self._related_fields = related_fields or [] self._related_names = [field.name for field in self._related_fields] @@ -129,26 +130,27 @@ class RelationsManager: for field in self._related_fields: self._add_relation(field) - def _add_relation(self, field): + def _add_relation(self, field: Type[ForeignKeyField]) -> None: self._relations[field.name] = Relation( manager=self, type_=RelationType.PRIMARY if not field.virtual else RelationType.REVERSE, ) - def __contains__(self, item): + def __contains__(self, item: str) -> bool: return item in self._related_names - def get(self, name) -> Optional[Union[List["Model"], "Model"]]: + def get(self, name: str) -> Optional[Union[List["Model"], "Model"]]: relation = self._relations.get(name, None) if relation: return relation.get() - def _get(self, name) -> Optional[Relation]: + def _get(self, name: str) -> Optional[Relation]: relation = self._relations.get(name, None) if relation: return relation - def add(self, parent: "Model", child: "Model", child_name: str, virtual: bool): + @staticmethod + def add(parent: "Model", child: "Model", child_name: str, virtual: bool) -> None: to_field = next( ( field @@ -160,7 +162,8 @@ class RelationsManager: if not to_field: # pragma no cover raise RelationshipInstanceError( - f"Model {child.__class__} does not have reference to model {parent.__class__}" + f"Model {child.__class__} does not have " + f"reference to model {parent.__class__}" ) to_name = to_field.name @@ -181,12 +184,12 @@ class RelationsManager: parent_relation.add(child) child._orm._get(to_name).add(parent) - def remove(self, name: str, child: "Model"): + def remove(self, name: str, child: "Model") -> None: relation = self._get(name) relation.remove(child) @staticmethod - def remove_parent(item: "Model", name: Union[str, "Model"]): + def remove_parent(item: "Model", name: Union[str, "Model"]) -> None: related_model = name name = item.resolve_relation_name(item, related_model) if name in item._orm: