summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/context.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2022-04-15 11:05:36 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2022-04-20 15:14:09 -0400
commitaeeff72e806420bf85e2e6723b1f941df38a3e1a (patch)
tree0bed521b4d7c4860f998e51ba5e318d18b2f5900 /lib/sqlalchemy/orm/context.py
parent13a8552053c21a9fa7ff6f992ed49ee92cca73e4 (diff)
downloadsqlalchemy-aeeff72e806420bf85e2e6723b1f941df38a3e1a.tar.gz
pep-484: ORM public API, constructors
for the moment, abandoning using @overload with relationship() and mapped_column(). The overloads are very difficult to get working at all, and the overloads that were there all wouldn't pass on mypy. various techniques of getting them to "work", meaning having right hand side dictate what's legal on the left, have mixed success and wont give consistent results; additionally, it's legal to have Optional / non-optional independent of nullable in any case for columns. relationship cases are less ambiguous but mypy was not going along with things. we have a comprehensive system of allowing left side annotations to drive the right side, in the absense of explicit settings on the right. so type-centric SQLAlchemy will be left-side driven just like dataclasses, and the various flags and switches on the right side will just not be needed very much. in other matters, one surprise, forgot to remove string support from orm.join(A, B, "somename") or do deprecations for it in 1.4. This is a really not-directly-used structure barely mentioned in the docs for many years, the example shows a relationship being used, not a string, so we will just change it to raise the usual error here. Change-Id: Iefbbb8d34548b538023890ab8b7c9a5d9496ec6e
Diffstat (limited to 'lib/sqlalchemy/orm/context.py')
-rw-r--r--lib/sqlalchemy/orm/context.py44
1 files changed, 32 insertions, 12 deletions
diff --git a/lib/sqlalchemy/orm/context.py b/lib/sqlalchemy/orm/context.py
index 419da65f7..4fee2d383 100644
--- a/lib/sqlalchemy/orm/context.py
+++ b/lib/sqlalchemy/orm/context.py
@@ -63,11 +63,14 @@ from ..sql.visitors import InternalTraversal
if TYPE_CHECKING:
from ._typing import _InternalEntityType
+ from .mapper import Mapper
+ from .query import Query
from ..sql.compiler import _CompilerStackEntry
from ..sql.dml import _DMLTableElement
from ..sql.elements import ColumnElement
from ..sql.selectable import _LabelConventionCallable
from ..sql.selectable import SelectBase
+ from ..sql.type_api import TypeEngine
_path_registry = PathRegistry.root
@@ -211,6 +214,9 @@ class ORMCompileState(CompileState):
_for_refresh_state = False
_render_for_subquery = False
+ attributes: Dict[Any, Any]
+ global_attributes: Dict[Any, Any]
+
statement: Union[Select, FromStatement]
select_statement: Union[Select, FromStatement]
_entities: List[_QueryEntity]
@@ -1930,7 +1936,7 @@ class ORMSelectCompileState(ORMCompileState, SelectState):
assert right_mapper
adapter = ORMAdapter(
- right, equivalents=right_mapper._equivalent_columns
+ inspect(right), equivalents=right_mapper._equivalent_columns
)
# if an alias() on the right side was generated,
@@ -2075,14 +2081,16 @@ class ORMSelectCompileState(ORMCompileState, SelectState):
def _column_descriptions(
- query_or_select_stmt, compile_state=None, legacy=False
+ query_or_select_stmt: Union[Query, Select, FromStatement],
+ compile_state: Optional[ORMSelectCompileState] = None,
+ legacy: bool = False,
) -> List[ORMColumnDescription]:
if compile_state is None:
compile_state = ORMSelectCompileState._create_entities_collection(
query_or_select_stmt, legacy=legacy
)
ctx = compile_state
- return [
+ d = [
{
"name": ent._label_name,
"type": ent.type,
@@ -2093,17 +2101,10 @@ def _column_descriptions(
else None,
}
for ent, insp_ent in [
- (
- _ent,
- (
- inspect(_ent.entity_zero)
- if _ent.entity_zero is not None
- else None
- ),
- )
- for _ent in ctx._entities
+ (_ent, _ent.entity_zero) for _ent in ctx._entities
]
]
+ return d
def _legacy_filter_by_entity_zero(query_or_augmented_select):
@@ -2157,6 +2158,11 @@ class _QueryEntity:
_null_column_type = False
use_id_for_hash = False
+ _label_name: Optional[str]
+ type: Union[Type[Any], TypeEngine[Any]]
+ expr: Union[_InternalEntityType, ColumnElement[Any]]
+ entity_zero: Optional[_InternalEntityType]
+
def setup_compile_state(self, compile_state: ORMCompileState) -> None:
raise NotImplementedError()
@@ -2234,6 +2240,13 @@ class _MapperEntity(_QueryEntity):
"_polymorphic_discriminator",
)
+ expr: _InternalEntityType
+ mapper: Mapper[Any]
+ entity_zero: _InternalEntityType
+ is_aliased_class: bool
+ path: PathRegistry
+ _label_name: str
+
def __init__(
self, compile_state, entity, entities_collection, is_current_entities
):
@@ -2389,6 +2402,13 @@ class _BundleEntity(_QueryEntity):
"supports_single_entity",
)
+ _entities: List[_QueryEntity]
+ bundle: Bundle
+ type: Type[Any]
+ _label_name: str
+ supports_single_entity: bool
+ expr: Bundle
+
def __init__(
self,
compile_state,