fix for issue 73

This commit is contained in:
collerek
2020-12-14 15:36:04 +01:00
parent ef4b687957
commit 6e67b69385
15 changed files with 306 additions and 80 deletions

View File

@ -1,11 +1,14 @@
import string
import uuid
from random import choices
from typing import Dict, List
from typing import Dict, List, TYPE_CHECKING, Type
import sqlalchemy
from sqlalchemy import text
if TYPE_CHECKING: # pragma: no cover
from ormar import Model
def get_table_alias() -> str:
alias = "".join(choices(string.ascii_uppercase, k=2)) + uuid.uuid4().hex[:4]
@ -15,6 +18,7 @@ def get_table_alias() -> str:
class AliasManager:
def __init__(self) -> None:
self._aliases: Dict[str, str] = dict()
self._aliases_new: Dict[str, str] = dict()
@staticmethod
def prefixed_columns(
@ -35,11 +39,25 @@ class AliasManager:
def prefixed_table_name(alias: str, name: str) -> text:
return text(f"{name} {alias}_{name}")
def add_relation_type(self, to_table_name: str, table_name: str,) -> None:
if f"{table_name}_{to_table_name}" not in self._aliases:
self._aliases[f"{table_name}_{to_table_name}"] = get_table_alias()
if f"{to_table_name}_{table_name}" not in self._aliases:
self._aliases[f"{to_table_name}_{table_name}"] = get_table_alias()
def add_relation_type_new(
self, source_model: Type["Model"], relation_name: str, is_multi: bool = False
) -> None:
parent_key = f"{source_model.get_name()}_{relation_name}"
if parent_key not in self._aliases_new:
self._aliases_new[parent_key] = get_table_alias()
to_field = source_model.Meta.model_fields[relation_name]
child_model = to_field.to
related_name = to_field.related_name
if not related_name:
related_name = child_model.resolve_relation_name(
child_model, source_model, explicit_multi=is_multi
)
child_key = f"{child_model.get_name()}_{related_name}"
if child_key not in self._aliases_new:
self._aliases_new[child_key] = get_table_alias()
def resolve_relation_join(self, from_table: str, to_table: str) -> str:
return self._aliases.get(f"{from_table}_{to_table}", "")
def resolve_relation_join_new(
self, from_model: Type["Model"], relation_name: str
) -> str:
alias = self._aliases_new.get(f"{from_model.get_name()}_{relation_name}", "")
return alias

View File

@ -56,8 +56,14 @@ class RelationsManager:
return None
@staticmethod
def add(parent: "Model", child: "Model", child_name: str, virtual: bool) -> None:
to_field: Type[BaseField] = child.resolve_relation_field(child, parent)
def add(
parent: "Model",
child: "Model",
child_name: str,
virtual: bool,
relation_name: str,
) -> None:
to_field: Type[BaseField] = child.Meta.model_fields[relation_name]
(parent, child, child_name, to_name,) = get_relations_sides_and_names(
to_field, parent, child, child_name, virtual

View File

@ -18,8 +18,11 @@ def get_relations_sides_and_names(
to_name = to_field.name
if issubclass(to_field, ManyToManyField):
child_name, to_name = (
child.resolve_relation_name(parent, child),
child.resolve_relation_name(child, parent),
to_field.related_name
or child.resolve_relation_name(
parent, to_field.through, explicit_multi=True
),
to_name,
)
child = proxy(child)
elif virtual: