Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/base.py: 58%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# orm/base.py
2# Copyright (C) 2005-2026 the SQLAlchemy authors and contributors
3# <see AUTHORS file>
4#
5# This module is part of SQLAlchemy and is released under
6# the MIT License: https://www.opensource.org/licenses/mit-license.php
8"""Constants and rudimental functions used throughout the ORM."""
10from __future__ import annotations
12from enum import Enum
13import operator
14import typing
15from typing import Any
16from typing import Callable
17from typing import Dict
18from typing import Generic
19from typing import Literal
20from typing import no_type_check
21from typing import Optional
22from typing import overload
23from typing import Tuple
24from typing import Type
25from typing import TYPE_CHECKING
26from typing import TypeVar
27from typing import Union
29from . import exc
30from ._typing import _O
31from ._typing import insp_is_mapper
32from .. import exc as sa_exc
33from .. import inspection
34from .. import util
35from ..sql import roles
36from ..sql._typing import _T
37from ..sql._typing import _T_co
38from ..sql.elements import SQLColumnExpression
39from ..sql.elements import SQLCoreOperations
40from ..util import FastIntFlag
41from ..util.langhelpers import TypingOnly
43if typing.TYPE_CHECKING:
44 from ._typing import _EntityType
45 from ._typing import _ExternalEntityType
46 from ._typing import _InternalEntityType
47 from .attributes import InstrumentedAttribute
48 from .dynamic import AppenderQuery
49 from .instrumentation import ClassManager
50 from .interfaces import PropComparator
51 from .mapper import Mapper
52 from .properties import MappedColumn
53 from .state import InstanceState
54 from .util import AliasedClass
55 from .writeonly import WriteOnlyCollection
56 from ..sql._annotated_cols import TypedColumns
57 from ..sql._typing import _ColumnExpressionArgument
58 from ..sql._typing import _InfoType
59 from ..sql.elements import ColumnElement
60 from ..sql.operators import OperatorType
61 from ..sql.schema import Column
64class LoaderCallableStatus(Enum):
65 PASSIVE_NO_RESULT = 0
66 """Symbol returned by a loader callable or other attribute/history
67 retrieval operation when a value could not be determined, based
68 on loader callable flags.
69 """
71 PASSIVE_CLASS_MISMATCH = 1
72 """Symbol indicating that an object is locally present for a given
73 primary key identity but it is not of the requested class. The
74 return value is therefore None and no SQL should be emitted."""
76 ATTR_WAS_SET = 2
77 """Symbol returned by a loader callable to indicate the
78 retrieved value, or values, were assigned to their attributes
79 on the target object.
80 """
82 ATTR_EMPTY = 3
83 """Symbol used internally to indicate an attribute had no callable."""
85 NO_VALUE = 4
86 """Symbol which may be placed as the 'previous' value of an attribute,
87 indicating no value was loaded for an attribute when it was modified,
88 and flags indicated we were not to load it.
89 """
91 NEVER_SET = NO_VALUE
92 """
93 Synonymous with NO_VALUE
95 .. versionchanged:: 1.4 NEVER_SET was merged with NO_VALUE
97 """
99 DONT_SET = 5
102(
103 PASSIVE_NO_RESULT,
104 PASSIVE_CLASS_MISMATCH,
105 ATTR_WAS_SET,
106 ATTR_EMPTY,
107 NO_VALUE,
108 DONT_SET,
109) = tuple(LoaderCallableStatus)
111NEVER_SET = NO_VALUE
114class PassiveFlag(FastIntFlag):
115 """Bitflag interface that passes options onto loader callables"""
117 NO_CHANGE = 0
118 """No callables or SQL should be emitted on attribute access
119 and no state should change
120 """
122 CALLABLES_OK = 1
123 """Loader callables can be fired off if a value
124 is not present.
125 """
127 SQL_OK = 2
128 """Loader callables can emit SQL at least on scalar value attributes."""
130 RELATED_OBJECT_OK = 4
131 """Callables can use SQL to load related objects as well
132 as scalar value attributes.
133 """
135 INIT_OK = 8
136 """Attributes should be initialized with a blank
137 value (None or an empty collection) upon get, if no other
138 value can be obtained.
139 """
141 NON_PERSISTENT_OK = 16
142 """Callables can be emitted if the parent is not persistent."""
144 LOAD_AGAINST_COMMITTED = 32
145 """Callables should use committed values as primary/foreign keys during a
146 load.
147 """
149 NO_AUTOFLUSH = 64
150 """Loader callables should disable autoflush."""
152 NO_RAISE = 128
153 """Loader callables should not raise any assertions"""
155 DEFERRED_HISTORY_LOAD = 256
156 """indicates special load of the previous value of an attribute"""
158 INCLUDE_PENDING_MUTATIONS = 512
160 # pre-packaged sets of flags used as inputs
161 PASSIVE_OFF = (
162 RELATED_OBJECT_OK | NON_PERSISTENT_OK | INIT_OK | CALLABLES_OK | SQL_OK
163 )
164 "Callables can be emitted in all cases."
166 PASSIVE_RETURN_NO_VALUE = PASSIVE_OFF ^ INIT_OK
167 """PASSIVE_OFF ^ INIT_OK"""
169 PASSIVE_NO_INITIALIZE = PASSIVE_RETURN_NO_VALUE ^ CALLABLES_OK
170 "PASSIVE_RETURN_NO_VALUE ^ CALLABLES_OK"
172 PASSIVE_NO_FETCH = PASSIVE_OFF ^ SQL_OK
173 "PASSIVE_OFF ^ SQL_OK"
175 PASSIVE_NO_FETCH_RELATED = PASSIVE_OFF ^ RELATED_OBJECT_OK
176 "PASSIVE_OFF ^ RELATED_OBJECT_OK"
178 PASSIVE_ONLY_PERSISTENT = PASSIVE_OFF ^ NON_PERSISTENT_OK
179 "PASSIVE_OFF ^ NON_PERSISTENT_OK"
181 PASSIVE_MERGE = PASSIVE_OFF | NO_RAISE
182 """PASSIVE_OFF | NO_RAISE
184 Symbol used specifically for session.merge() and similar cases
186 """
189(
190 NO_CHANGE,
191 CALLABLES_OK,
192 SQL_OK,
193 RELATED_OBJECT_OK,
194 INIT_OK,
195 NON_PERSISTENT_OK,
196 LOAD_AGAINST_COMMITTED,
197 NO_AUTOFLUSH,
198 NO_RAISE,
199 DEFERRED_HISTORY_LOAD,
200 INCLUDE_PENDING_MUTATIONS,
201 PASSIVE_OFF,
202 PASSIVE_RETURN_NO_VALUE,
203 PASSIVE_NO_INITIALIZE,
204 PASSIVE_NO_FETCH,
205 PASSIVE_NO_FETCH_RELATED,
206 PASSIVE_ONLY_PERSISTENT,
207 PASSIVE_MERGE,
208) = PassiveFlag.__members__.values()
210DEFAULT_MANAGER_ATTR = "_sa_class_manager"
211DEFAULT_STATE_ATTR = "_sa_instance_state"
214class EventConstants(Enum):
215 EXT_CONTINUE = 1
216 EXT_STOP = 2
217 EXT_SKIP = 3
218 NO_KEY = 4
219 """indicates an :class:`.AttributeEvent` event that did not have any
220 key argument.
222 .. versionadded:: 2.0
224 """
227EXT_CONTINUE, EXT_STOP, EXT_SKIP, NO_KEY = tuple(EventConstants)
230class RelationshipDirection(Enum):
231 """enumeration which indicates the 'direction' of a
232 :class:`_orm.RelationshipProperty`.
234 :class:`.RelationshipDirection` is accessible from the
235 :attr:`_orm.Relationship.direction` attribute of
236 :class:`_orm.RelationshipProperty`.
238 """
240 ONETOMANY = 1
241 """Indicates the one-to-many direction for a :func:`_orm.relationship`.
243 This symbol is typically used by the internals but may be exposed within
244 certain API features.
246 """
248 MANYTOONE = 2
249 """Indicates the many-to-one direction for a :func:`_orm.relationship`.
251 This symbol is typically used by the internals but may be exposed within
252 certain API features.
254 """
256 MANYTOMANY = 3
257 """Indicates the many-to-many direction for a :func:`_orm.relationship`.
259 This symbol is typically used by the internals but may be exposed within
260 certain API features.
262 """
265ONETOMANY, MANYTOONE, MANYTOMANY = tuple(RelationshipDirection)
268class InspectionAttrExtensionType(Enum):
269 """Symbols indicating the type of extension that a
270 :class:`.InspectionAttr` is part of."""
273class NotExtension(InspectionAttrExtensionType):
274 NOT_EXTENSION = "not_extension"
275 """Symbol indicating an :class:`InspectionAttr` that's
276 not part of sqlalchemy.ext.
278 Is assigned to the :attr:`.InspectionAttr.extension_type`
279 attribute.
281 """
284_never_set = frozenset([NEVER_SET])
286_none_set = frozenset([None, NEVER_SET, PASSIVE_NO_RESULT])
288_none_only_set = frozenset([None])
290_SET_DEFERRED_EXPIRED = util.symbol("SET_DEFERRED_EXPIRED")
292_DEFER_FOR_STATE = util.symbol("DEFER_FOR_STATE")
294_RAISE_FOR_STATE = util.symbol("RAISE_FOR_STATE")
297_F = TypeVar("_F", bound=Callable[..., Any])
298_Self = TypeVar("_Self")
301def _assertions(
302 *assertions: Any,
303) -> Callable[[_F], _F]:
304 @util.decorator
305 def generate(fn: _F, self: _Self, *args: Any, **kw: Any) -> _Self:
306 for assertion in assertions:
307 assertion(self, fn.__name__)
308 fn(self, *args, **kw)
309 return self
311 return generate
314if TYPE_CHECKING:
316 def manager_of_class(cls: Type[_O]) -> ClassManager[_O]: ...
318 @overload
319 def opt_manager_of_class(cls: AliasedClass[Any]) -> None: ...
321 @overload
322 def opt_manager_of_class(
323 cls: _ExternalEntityType[_O],
324 ) -> Optional[ClassManager[_O]]: ...
326 def opt_manager_of_class(
327 cls: _ExternalEntityType[_O],
328 ) -> Optional[ClassManager[_O]]: ...
330 def instance_state(instance: _O) -> InstanceState[_O]: ...
332 def instance_dict(instance: object) -> Dict[str, Any]: ...
334else:
335 # these can be replaced by sqlalchemy.ext.instrumentation
336 # if augmented class instrumentation is enabled.
338 def manager_of_class(cls):
339 try:
340 return cls.__dict__[DEFAULT_MANAGER_ATTR]
341 except KeyError as ke:
342 raise exc.UnmappedClassError(
343 cls, f"Can't locate an instrumentation manager for class {cls}"
344 ) from ke
346 def opt_manager_of_class(cls):
347 return cls.__dict__.get(DEFAULT_MANAGER_ATTR)
349 instance_state = operator.attrgetter(DEFAULT_STATE_ATTR)
351 instance_dict = operator.attrgetter("__dict__")
354def instance_str(instance: object) -> str:
355 """Return a string describing an instance."""
357 return state_str(instance_state(instance))
360def state_str(state: InstanceState[Any]) -> str:
361 """Return a string describing an instance via its InstanceState."""
363 if state is None:
364 return "None"
365 else:
366 return "<%s at 0x%x>" % (state.class_.__name__, id(state.obj()))
369def state_class_str(state: InstanceState[Any]) -> str:
370 """Return a string describing an instance's class via its
371 InstanceState.
372 """
374 if state is None:
375 return "None"
376 else:
377 return "<%s>" % (state.class_.__name__,)
380def attribute_str(instance: object, attribute: str) -> str:
381 return instance_str(instance) + "." + attribute
384def state_attribute_str(state: InstanceState[Any], attribute: str) -> str:
385 return state_str(state) + "." + attribute
388def object_mapper(instance: _T) -> Mapper[_T]:
389 """Given an object, return the primary Mapper associated with the object
390 instance.
392 Raises :class:`sqlalchemy.orm.exc.UnmappedInstanceError`
393 if no mapping is configured.
395 This function is available via the inspection system as::
397 inspect(instance).mapper
399 Using the inspection system will raise
400 :class:`sqlalchemy.exc.NoInspectionAvailable` if the instance is
401 not part of a mapping.
403 """
404 return object_state(instance).mapper
407def object_state(instance: _T) -> InstanceState[_T]:
408 """Given an object, return the :class:`.InstanceState`
409 associated with the object.
411 Raises :class:`sqlalchemy.orm.exc.UnmappedInstanceError`
412 if no mapping is configured.
414 Equivalent functionality is available via the :func:`_sa.inspect`
415 function as::
417 inspect(instance)
419 Using the inspection system will raise
420 :class:`sqlalchemy.exc.NoInspectionAvailable` if the instance is
421 not part of a mapping.
423 """
424 state = _inspect_mapped_object(instance)
425 if state is None:
426 raise exc.UnmappedInstanceError(instance)
427 else:
428 return state
431@inspection._inspects(object)
432def _inspect_mapped_object(instance: _T) -> Optional[InstanceState[_T]]:
433 try:
434 return instance_state(instance)
435 except (exc.UnmappedClassError,) + exc.NO_STATE:
436 return None
439def _class_to_mapper(
440 class_or_mapper: Union[Mapper[_T], Type[_T]],
441) -> Mapper[_T]:
442 # can't get mypy to see an overload for this
443 insp = inspection.inspect(class_or_mapper, False)
444 if insp is not None:
445 return insp.mapper # type: ignore
446 else:
447 assert isinstance(class_or_mapper, type)
448 raise exc.UnmappedClassError(class_or_mapper)
451def _mapper_or_none(
452 entity: Union[Type[_T], _InternalEntityType[_T]],
453) -> Optional[Mapper[_T]]:
454 """Return the :class:`_orm.Mapper` for the given class or None if the
455 class is not mapped.
456 """
458 # can't get mypy to see an overload for this
459 insp = inspection.inspect(entity, False)
460 if insp is not None:
461 return insp.mapper # type: ignore
462 else:
463 return None
466def _is_mapped_class(entity: Any) -> bool:
467 """Return True if the given object is a mapped class,
468 :class:`_orm.Mapper`, or :class:`.AliasedClass`.
469 """
471 insp = inspection.inspect(entity, False)
472 return (
473 insp is not None
474 and not insp.is_clause_element
475 and (insp.is_mapper or insp.is_aliased_class)
476 )
479def _is_aliased_class(entity: Any) -> bool:
480 insp = inspection.inspect(entity, False)
481 return insp is not None and getattr(insp, "is_aliased_class", False)
484@no_type_check
485def _entity_descriptor(entity: _EntityType[Any], key: str) -> Any:
486 """Return a class attribute given an entity and string name.
488 May return :class:`.InstrumentedAttribute` or user-defined
489 attribute.
491 """
492 insp = inspection.inspect(entity)
493 if insp.is_selectable:
494 description = entity
495 entity = insp.c
496 elif insp.is_aliased_class:
497 entity = insp.entity
498 description = entity
499 elif hasattr(insp, "mapper"):
500 description = entity = insp.mapper.class_
501 else:
502 description = entity
504 try:
505 return getattr(entity, key)
506 except AttributeError as err:
507 raise sa_exc.InvalidRequestError(
508 "Entity '%s' has no property '%s'" % (description, key)
509 ) from err
512if TYPE_CHECKING:
514 def _state_mapper(state: InstanceState[_O]) -> Mapper[_O]: ...
516else:
517 _state_mapper = util.dottedgetter("manager.mapper")
520def _inspect_mapped_class(
521 class_: Type[_O], configure: bool = False
522) -> Optional[Mapper[_O]]:
523 try:
524 class_manager = opt_manager_of_class(class_)
525 if class_manager is None or not class_manager.is_mapped:
526 return None
527 mapper = class_manager.mapper
528 except exc.NO_STATE:
529 return None
530 else:
531 if configure:
532 mapper._check_configure()
533 return mapper
536def _parse_mapper_argument(arg: Union[Mapper[_O], Type[_O]]) -> Mapper[_O]:
537 insp = inspection.inspect(arg, raiseerr=False)
538 if insp_is_mapper(insp):
539 return insp
541 raise sa_exc.ArgumentError(f"Mapper or mapped class expected, got {arg!r}")
544def class_mapper(class_: Type[_O], configure: bool = True) -> Mapper[_O]:
545 """Given a class, return the primary :class:`_orm.Mapper` associated
546 with the key.
548 Raises :exc:`.UnmappedClassError` if no mapping is configured
549 on the given class, or :exc:`.ArgumentError` if a non-class
550 object is passed.
552 Equivalent functionality is available via the :func:`_sa.inspect`
553 function as::
555 inspect(some_mapped_class)
557 Using the inspection system will raise
558 :class:`sqlalchemy.exc.NoInspectionAvailable` if the class is not mapped.
560 """
561 mapper = _inspect_mapped_class(class_, configure=configure)
562 if mapper is None:
563 if not isinstance(class_, type):
564 raise sa_exc.ArgumentError(
565 "Class object expected, got '%r'." % (class_,)
566 )
567 raise exc.UnmappedClassError(class_)
568 else:
569 return mapper
572class InspectionAttr:
573 """A base class applied to all ORM objects and attributes that are
574 related to things that can be returned by the :func:`_sa.inspect` function.
576 The attributes defined here allow the usage of simple boolean
577 checks to test basic facts about the object returned.
579 While the boolean checks here are basically the same as using
580 the Python isinstance() function, the flags here can be used without
581 the need to import all of these classes, and also such that
582 the SQLAlchemy class system can change while leaving the flags
583 here intact for forwards-compatibility.
585 """
587 __slots__: Tuple[str, ...] = ()
589 is_selectable = False
590 """Return True if this object is an instance of
591 :class:`_expression.Selectable`."""
593 is_aliased_class = False
594 """True if this object is an instance of :class:`.AliasedClass`."""
596 is_instance = False
597 """True if this object is an instance of :class:`.InstanceState`."""
599 is_mapper = False
600 """True if this object is an instance of :class:`_orm.Mapper`."""
602 is_bundle = False
603 """True if this object is an instance of :class:`.Bundle`."""
605 is_property = False
606 """True if this object is an instance of :class:`.MapperProperty`."""
608 is_attribute = False
609 """True if this object is a Python :term:`descriptor`.
611 This can refer to one of many types. Usually a
612 :class:`.QueryableAttribute` which handles attributes events on behalf
613 of a :class:`.MapperProperty`. But can also be an extension type
614 such as :class:`.AssociationProxy` or :class:`.hybrid_property`.
615 The :attr:`.InspectionAttr.extension_type` will refer to a constant
616 identifying the specific subtype.
618 .. seealso::
620 :attr:`_orm.Mapper.all_orm_descriptors`
622 """
624 _is_internal_proxy = False
625 """True if this object is an internal proxy object."""
627 is_clause_element = False
628 """True if this object is an instance of
629 :class:`_expression.ClauseElement`."""
631 extension_type: InspectionAttrExtensionType = NotExtension.NOT_EXTENSION
632 """The extension type, if any.
633 Defaults to :attr:`.interfaces.NotExtension.NOT_EXTENSION`
635 .. seealso::
637 :class:`.HybridExtensionType`
639 :class:`.AssociationProxyExtensionType`
641 """
644class InspectionAttrInfo(InspectionAttr):
645 """Adds the ``.info`` attribute to :class:`.InspectionAttr`.
647 The rationale for :class:`.InspectionAttr` vs. :class:`.InspectionAttrInfo`
648 is that the former is compatible as a mixin for classes that specify
649 ``__slots__``; this is essentially an implementation artifact.
651 """
653 __slots__ = ()
655 @util.ro_memoized_property
656 def info(self) -> _InfoType:
657 """Info dictionary associated with the object, allowing user-defined
658 data to be associated with this :class:`.InspectionAttr`.
660 The dictionary is generated when first accessed. Alternatively,
661 it can be specified as a constructor argument to the
662 :func:`.column_property`, :func:`_orm.relationship`, or
663 :func:`.composite`
664 functions.
666 .. seealso::
668 :attr:`.QueryableAttribute.info`
670 :attr:`.SchemaItem.info`
672 """
673 return {}
676class SQLORMOperations(SQLCoreOperations[_T_co], TypingOnly):
677 __slots__ = ()
679 if typing.TYPE_CHECKING:
681 def of_type(
682 self, class_: _EntityType[Any]
683 ) -> PropComparator[_T_co]: ...
685 def and_(
686 self, *criteria: _ColumnExpressionArgument[bool]
687 ) -> PropComparator[bool]: ...
689 def any( # noqa: A001
690 self,
691 criterion: Optional[_ColumnExpressionArgument[bool]] = None,
692 **kwargs: Any,
693 ) -> ColumnElement[bool]: ...
695 def has(
696 self,
697 criterion: Optional[_ColumnExpressionArgument[bool]] = None,
698 **kwargs: Any,
699 ) -> ColumnElement[bool]: ...
702class ORMDescriptor(Generic[_T_co], TypingOnly):
703 """Represent any Python descriptor that provides a SQL expression
704 construct at the class level."""
706 __slots__ = ()
708 if typing.TYPE_CHECKING:
710 @overload
711 def __get__(
712 self, instance: Any, owner: Literal[None]
713 ) -> ORMDescriptor[_T_co]: ...
715 @overload
716 def __get__(
717 self, instance: Literal[None], owner: Any
718 ) -> SQLCoreOperations[_T_co]: ...
720 @overload
721 def __get__(self, instance: object, owner: Any) -> _T_co: ...
723 def __get__(
724 self, instance: object, owner: Any
725 ) -> Union[ORMDescriptor[_T_co], SQLCoreOperations[_T_co], _T_co]: ...
728class _MappedAnnotationBase(Generic[_T_co], TypingOnly):
729 """common class for Mapped and similar ORM container classes.
731 these are classes that can appear on the left side of an ORM declarative
732 mapping, containing a mapped class or in some cases a collection
733 surrounding a mapped class.
735 """
737 __slots__ = ()
740class SQLORMExpression(
741 SQLORMOperations[_T_co], SQLColumnExpression[_T_co], TypingOnly
742):
743 """A type that may be used to indicate any ORM-level attribute or
744 object that acts in place of one, in the context of SQL expression
745 construction.
747 :class:`.SQLORMExpression` extends from the Core
748 :class:`.SQLColumnExpression` to add additional SQL methods that are ORM
749 specific, such as :meth:`.PropComparator.of_type`, and is part of the bases
750 for :class:`.InstrumentedAttribute`. It may be used in :pep:`484` typing to
751 indicate arguments or return values that should behave as ORM-level
752 attribute expressions.
754 .. versionadded:: 2.0.0b4
757 """
759 __slots__ = ()
762class Mapped(
763 SQLORMExpression[_T_co],
764 ORMDescriptor[_T_co],
765 _MappedAnnotationBase[_T_co],
766 roles.DDLConstraintColumnRole,
767):
768 """Represent an ORM mapped attribute on a mapped class.
770 This class represents the complete descriptor interface for any class
771 attribute that will have been :term:`instrumented` by the ORM
772 :class:`_orm.Mapper` class. Provides appropriate information to type
773 checkers such as pylance and mypy so that ORM-mapped attributes
774 are correctly typed.
776 The most prominent use of :class:`_orm.Mapped` is in
777 the :ref:`Declarative Mapping <orm_explicit_declarative_base>` form
778 of :class:`_orm.Mapper` configuration, where used explicitly it drives
779 the configuration of ORM attributes such as :func:`_orm.mapped_class`
780 and :func:`_orm.relationship`.
782 .. seealso::
784 :ref:`orm_explicit_declarative_base`
786 :ref:`orm_declarative_table`
788 .. tip::
790 The :class:`_orm.Mapped` class represents attributes that are handled
791 directly by the :class:`_orm.Mapper` class. It does not include other
792 Python descriptor classes that are provided as extensions, including
793 :ref:`hybrids_toplevel` and the :ref:`associationproxy_toplevel`.
794 While these systems still make use of ORM-specific superclasses
795 and structures, they are not :term:`instrumented` by the
796 :class:`_orm.Mapper` and instead provide their own functionality
797 when they are accessed on a class.
799 .. versionadded:: 1.4
802 """
804 __slots__ = ()
806 if typing.TYPE_CHECKING:
808 @overload
809 def __get__( # type: ignore[misc]
810 self: MappedColumn[_T_co], instance: TypedColumns, owner: Any
811 ) -> Column[_T_co]: ...
813 @overload
814 def __get__(
815 self, instance: None, owner: Any
816 ) -> InstrumentedAttribute[_T_co]: ...
818 @overload
819 def __get__(self, instance: object, owner: Any) -> _T_co: ...
821 def __get__(
822 self, instance: Optional[object], owner: Any
823 ) -> Union[InstrumentedAttribute[_T_co], Column[_T_co], _T_co]: ...
825 @classmethod
826 def _empty_constructor(cls, arg1: Any) -> Mapped[_T_co]: ...
828 def __set__(
829 self, instance: Any, value: Union[SQLCoreOperations[_T_co], _T_co]
830 ) -> None: ...
832 def __delete__(self, instance: Any) -> None: ...
835class _MappedAttribute(Generic[_T_co], TypingOnly):
836 """Mixin for attributes which should be replaced by mapper-assigned
837 attributes.
839 """
841 __slots__ = ()
844class _DeclarativeMapped(Mapped[_T_co], _MappedAttribute[_T_co]):
845 """Mixin for :class:`.MapperProperty` subclasses that allows them to
846 be compatible with ORM-annotated declarative mappings.
848 """
850 __slots__ = ()
852 # MappedSQLExpression, Relationship, Composite etc. dont actually do
853 # SQL expression behavior. yet there is code that compares them with
854 # __eq__(), __ne__(), etc. Since #8847 made Mapped even more full
855 # featured including ColumnOperators, we need to have those methods
856 # be no-ops for these objects, so return NotImplemented to fall back
857 # to normal comparison behavior.
858 def operate(self, op: OperatorType, *other: Any, **kwargs: Any) -> Any:
859 return NotImplemented
861 __sa_operate__ = operate
863 def reverse_operate(
864 self, op: OperatorType, other: Any, **kwargs: Any
865 ) -> Any:
866 return NotImplemented
869class DynamicMapped(_MappedAnnotationBase[_T_co]):
870 """Represent the ORM mapped attribute type for a "dynamic" relationship.
872 The :class:`_orm.DynamicMapped` type annotation may be used in an
873 :ref:`Annotated Declarative Table <orm_declarative_mapped_column>` mapping
874 to indicate that the ``lazy="dynamic"`` loader strategy should be used
875 for a particular :func:`_orm.relationship`.
877 .. legacy:: The "dynamic" lazy loader strategy is the legacy form of what
878 is now the "write_only" strategy described in the section
879 :ref:`write_only_relationship`.
881 E.g.::
883 class User(Base):
884 __tablename__ = "user"
885 id: Mapped[int] = mapped_column(primary_key=True)
886 addresses: DynamicMapped[Address] = relationship(
887 cascade="all,delete-orphan"
888 )
890 See the section :ref:`dynamic_relationship` for background.
892 .. versionadded:: 2.0
894 .. seealso::
896 :ref:`dynamic_relationship` - complete background
898 :class:`.WriteOnlyMapped` - fully 2.0 style version
900 """
902 __slots__ = ()
904 if TYPE_CHECKING:
906 @overload
907 def __get__(
908 self, instance: None, owner: Any
909 ) -> InstrumentedAttribute[_T_co]: ...
911 @overload
912 def __get__(
913 self, instance: object, owner: Any
914 ) -> AppenderQuery[_T_co]: ...
916 def __get__(
917 self, instance: Optional[object], owner: Any
918 ) -> Union[InstrumentedAttribute[_T_co], AppenderQuery[_T_co]]: ...
920 def __set__(
921 self, instance: Any, value: typing.Collection[_T_co]
922 ) -> None: ...
925class WriteOnlyMapped(_MappedAnnotationBase[_T_co]):
926 """Represent the ORM mapped attribute type for a "write only" relationship.
928 The :class:`_orm.WriteOnlyMapped` type annotation may be used in an
929 :ref:`Annotated Declarative Table <orm_declarative_mapped_column>` mapping
930 to indicate that the ``lazy="write_only"`` loader strategy should be used
931 for a particular :func:`_orm.relationship`.
933 E.g.::
935 class User(Base):
936 __tablename__ = "user"
937 id: Mapped[int] = mapped_column(primary_key=True)
938 addresses: WriteOnlyMapped[Address] = relationship(
939 cascade="all,delete-orphan"
940 )
942 See the section :ref:`write_only_relationship` for background.
944 .. versionadded:: 2.0
946 .. seealso::
948 :ref:`write_only_relationship` - complete background
950 :class:`.DynamicMapped` - includes legacy :class:`_orm.Query` support
952 """
954 __slots__ = ()
956 if TYPE_CHECKING:
958 @overload
959 def __get__(
960 self, instance: None, owner: Any
961 ) -> InstrumentedAttribute[_T_co]: ...
963 @overload
964 def __get__(
965 self, instance: object, owner: Any
966 ) -> WriteOnlyCollection[_T_co]: ...
968 def __get__(
969 self, instance: Optional[object], owner: Any
970 ) -> Union[
971 InstrumentedAttribute[_T_co], WriteOnlyCollection[_T_co]
972 ]: ...
974 def __set__(
975 self, instance: Any, value: typing.Collection[_T_co]
976 ) -> None: ...