Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/base.py: 59%

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

338 statements  

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 

7 

8"""Constants and rudimental functions used throughout the ORM.""" 

9 

10from __future__ import annotations 

11 

12from enum import Enum 

13import operator 

14import typing 

15from typing import Any 

16from typing import Callable 

17from typing import cast 

18from typing import Dict 

19from typing import Generic 

20from typing import Literal 

21from typing import no_type_check 

22from typing import Optional 

23from typing import overload 

24from typing import Tuple 

25from typing import Type 

26from typing import TYPE_CHECKING 

27from typing import TypeVar 

28from typing import Union 

29 

30from . import exc 

31from ._typing import _HasPathString 

32from ._typing import _O 

33from ._typing import insp_is_mapper 

34from .. import exc as sa_exc 

35from .. import inspection 

36from .. import util 

37from ..sql import roles 

38from ..sql._typing import _T 

39from ..sql._typing import _T_co 

40from ..sql.elements import SQLColumnExpression 

41from ..sql.elements import SQLCoreOperations 

42from ..util import FastIntFlag 

43from ..util.langhelpers import TypingOnly 

44 

45if typing.TYPE_CHECKING: 

46 from ._typing import _EntityType 

47 from ._typing import _ExternalEntityType 

48 from ._typing import _InternalEntityType 

49 from .attributes import InstrumentedAttribute 

50 from .dynamic import AppenderQuery 

51 from .instrumentation import ClassManager 

52 from .interfaces import PropComparator 

53 from .mapper import Mapper 

54 from .properties import MappedColumn 

55 from .state import InstanceState 

56 from .util import AliasedClass 

57 from .writeonly import WriteOnlyCollection 

58 from ..sql._annotated_cols import TypedColumns 

59 from ..sql._typing import _ColumnExpressionArgument 

60 from ..sql._typing import _InfoType 

61 from ..sql.elements import ColumnElement 

62 from ..sql.operators import OperatorType 

63 from ..sql.schema import Column 

64 

65 

66class LoaderCallableStatus(Enum): 

67 PASSIVE_NO_RESULT = 0 

68 """Symbol returned by a loader callable or other attribute/history 

69 retrieval operation when a value could not be determined, based 

70 on loader callable flags. 

71 """ 

72 

73 PASSIVE_CLASS_MISMATCH = 1 

74 """Symbol indicating that an object is locally present for a given 

75 primary key identity but it is not of the requested class. The 

76 return value is therefore None and no SQL should be emitted.""" 

77 

78 ATTR_WAS_SET = 2 

79 """Symbol returned by a loader callable to indicate the 

80 retrieved value, or values, were assigned to their attributes 

81 on the target object. 

82 """ 

83 

84 ATTR_EMPTY = 3 

85 """Symbol used internally to indicate an attribute had no callable.""" 

86 

87 NO_VALUE = 4 

88 """Symbol which may be placed as the 'previous' value of an attribute, 

89 indicating no value was loaded for an attribute when it was modified, 

90 and flags indicated we were not to load it. 

91 """ 

92 

93 NEVER_SET = NO_VALUE 

94 """ 

95 Synonymous with NO_VALUE 

96 

97 .. versionchanged:: 1.4 NEVER_SET was merged with NO_VALUE 

98 

99 """ 

100 

101 DONT_SET = 5 

102 

103 

104( 

105 PASSIVE_NO_RESULT, 

106 PASSIVE_CLASS_MISMATCH, 

107 ATTR_WAS_SET, 

108 ATTR_EMPTY, 

109 NO_VALUE, 

110 DONT_SET, 

111) = tuple(LoaderCallableStatus) 

112 

113NEVER_SET = NO_VALUE 

114 

115 

116class PassiveFlag(FastIntFlag): 

117 """Bitflag interface that passes options onto loader callables""" 

118 

119 NO_CHANGE = 0 

120 """No callables or SQL should be emitted on attribute access 

121 and no state should change 

122 """ 

123 

124 CALLABLES_OK = 1 

125 """Loader callables can be fired off if a value 

126 is not present. 

127 """ 

128 

129 SQL_OK = 2 

130 """Loader callables can emit SQL at least on scalar value attributes.""" 

131 

132 RELATED_OBJECT_OK = 4 

133 """Callables can use SQL to load related objects as well 

134 as scalar value attributes. 

135 """ 

136 

137 INIT_OK = 8 

138 """Attributes should be initialized with a blank 

139 value (None or an empty collection) upon get, if no other 

140 value can be obtained. 

141 """ 

142 

143 NON_PERSISTENT_OK = 16 

144 """Callables can be emitted if the parent is not persistent.""" 

145 

146 LOAD_AGAINST_COMMITTED = 32 

147 """Callables should use committed values as primary/foreign keys during a 

148 load. 

149 """ 

150 

151 NO_AUTOFLUSH = 64 

152 """Loader callables should disable autoflush.""" 

153 

154 NO_RAISE = 128 

155 """Loader callables should not raise any assertions""" 

156 

157 DEFERRED_HISTORY_LOAD = 256 

158 """indicates special load of the previous value of an attribute""" 

159 

160 INCLUDE_PENDING_MUTATIONS = 512 

161 

162 # pre-packaged sets of flags used as inputs 

163 PASSIVE_OFF = ( 

164 RELATED_OBJECT_OK | NON_PERSISTENT_OK | INIT_OK | CALLABLES_OK | SQL_OK 

165 ) 

166 "Callables can be emitted in all cases." 

167 

168 PASSIVE_RETURN_NO_VALUE = PASSIVE_OFF ^ INIT_OK 

169 """PASSIVE_OFF ^ INIT_OK""" 

170 

171 PASSIVE_NO_INITIALIZE = PASSIVE_RETURN_NO_VALUE ^ CALLABLES_OK 

172 "PASSIVE_RETURN_NO_VALUE ^ CALLABLES_OK" 

173 

174 PASSIVE_NO_FETCH = PASSIVE_OFF ^ SQL_OK 

175 "PASSIVE_OFF ^ SQL_OK" 

176 

177 PASSIVE_NO_FETCH_RELATED = PASSIVE_OFF ^ RELATED_OBJECT_OK 

178 "PASSIVE_OFF ^ RELATED_OBJECT_OK" 

179 

180 PASSIVE_ONLY_PERSISTENT = PASSIVE_OFF ^ NON_PERSISTENT_OK 

181 "PASSIVE_OFF ^ NON_PERSISTENT_OK" 

182 

183 PASSIVE_MERGE = PASSIVE_OFF | NO_RAISE 

184 """PASSIVE_OFF | NO_RAISE 

185 

186 Symbol used specifically for session.merge() and similar cases 

187 

188 """ 

189 

190 

191( 

192 NO_CHANGE, 

193 CALLABLES_OK, 

194 SQL_OK, 

195 RELATED_OBJECT_OK, 

196 INIT_OK, 

197 NON_PERSISTENT_OK, 

198 LOAD_AGAINST_COMMITTED, 

199 NO_AUTOFLUSH, 

200 NO_RAISE, 

201 DEFERRED_HISTORY_LOAD, 

202 INCLUDE_PENDING_MUTATIONS, 

203 PASSIVE_OFF, 

204 PASSIVE_RETURN_NO_VALUE, 

205 PASSIVE_NO_INITIALIZE, 

206 PASSIVE_NO_FETCH, 

207 PASSIVE_NO_FETCH_RELATED, 

208 PASSIVE_ONLY_PERSISTENT, 

209 PASSIVE_MERGE, 

210) = PassiveFlag.__members__.values() 

211 

212DEFAULT_MANAGER_ATTR = "_sa_class_manager" 

213DEFAULT_STATE_ATTR = "_sa_instance_state" 

214 

215 

216class EventConstants(Enum): 

217 EXT_CONTINUE = 1 

218 EXT_STOP = 2 

219 EXT_SKIP = 3 

220 NO_KEY = 4 

221 """indicates an :class:`.AttributeEvent` event that did not have any 

222 key argument. 

223 

224 .. versionadded:: 2.0 

225 

226 """ 

227 

228 

229EXT_CONTINUE, EXT_STOP, EXT_SKIP, NO_KEY = tuple(EventConstants) 

230 

231 

232class RelationshipDirection(Enum): 

233 """enumeration which indicates the 'direction' of a 

234 :class:`_orm.RelationshipProperty`. 

235 

236 :class:`.RelationshipDirection` is accessible from the 

237 :attr:`_orm.Relationship.direction` attribute of 

238 :class:`_orm.RelationshipProperty`. 

239 

240 """ 

241 

242 ONETOMANY = 1 

243 """Indicates the one-to-many direction for a :func:`_orm.relationship`. 

244 

245 This symbol is typically used by the internals but may be exposed within 

246 certain API features. 

247 

248 """ 

249 

250 MANYTOONE = 2 

251 """Indicates the many-to-one direction for a :func:`_orm.relationship`. 

252 

253 This symbol is typically used by the internals but may be exposed within 

254 certain API features. 

255 

256 """ 

257 

258 MANYTOMANY = 3 

259 """Indicates the many-to-many direction for a :func:`_orm.relationship`. 

260 

261 This symbol is typically used by the internals but may be exposed within 

262 certain API features. 

263 

264 """ 

265 

266 

267ONETOMANY, MANYTOONE, MANYTOMANY = tuple(RelationshipDirection) 

268 

269 

270class InspectionAttrExtensionType(Enum): 

271 """Symbols indicating the type of extension that a 

272 :class:`.InspectionAttr` is part of.""" 

273 

274 

275class NotExtension(InspectionAttrExtensionType): 

276 NOT_EXTENSION = "not_extension" 

277 """Symbol indicating an :class:`InspectionAttr` that's 

278 not part of sqlalchemy.ext. 

279 

280 Is assigned to the :attr:`.InspectionAttr.extension_type` 

281 attribute. 

282 

283 """ 

284 

285 

286_never_set = frozenset([NEVER_SET]) 

287 

288_none_set = frozenset([None, NEVER_SET, PASSIVE_NO_RESULT]) 

289 

290_none_only_set = frozenset([None]) 

291 

292_SET_DEFERRED_EXPIRED = util.symbol("SET_DEFERRED_EXPIRED") 

293 

294_DEFER_FOR_STATE = util.symbol("DEFER_FOR_STATE") 

295 

296_RAISE_FOR_STATE = util.symbol("RAISE_FOR_STATE") 

297 

298 

299_F = TypeVar("_F", bound=Callable[..., Any]) 

300_Self = TypeVar("_Self") 

301 

302 

303def _assertions( 

304 *assertions: Any, 

305) -> Callable[[_F], _F]: 

306 @util.decorator 

307 def generate(fn: _F, self: _Self, *args: Any, **kw: Any) -> _Self: 

308 for assertion in assertions: 

309 assertion(self, fn.__name__) 

310 fn(self, *args, **kw) 

311 return self 

312 

313 return generate 

314 

315 

316if TYPE_CHECKING: 

317 

318 def manager_of_class(cls: Type[_O]) -> ClassManager[_O]: ... 

319 

320 @overload 

321 def opt_manager_of_class(cls: AliasedClass[Any]) -> None: ... 

322 

323 @overload 

324 def opt_manager_of_class( 

325 cls: _ExternalEntityType[_O], 

326 ) -> Optional[ClassManager[_O]]: ... 

327 

328 def opt_manager_of_class( 

329 cls: _ExternalEntityType[_O], 

330 ) -> Optional[ClassManager[_O]]: ... 

331 

332 def instance_state(instance: _O) -> InstanceState[_O]: ... 

333 

334 def instance_dict(instance: object) -> Dict[str, Any]: ... 

335 

336else: 

337 # these can be replaced by sqlalchemy.ext.instrumentation 

338 # if augmented class instrumentation is enabled. 

339 

340 def manager_of_class(cls): 

341 try: 

342 return cls.__dict__[DEFAULT_MANAGER_ATTR] 

343 except KeyError as ke: 

344 raise exc.UnmappedClassError( 

345 cls, f"Can't locate an instrumentation manager for class {cls}" 

346 ) from ke 

347 

348 def opt_manager_of_class(cls): 

349 return cls.__dict__.get(DEFAULT_MANAGER_ATTR) 

350 

351 instance_state = operator.attrgetter(DEFAULT_STATE_ATTR) 

352 

353 instance_dict = operator.attrgetter("__dict__") 

354 

355 

356def instance_str(instance: object) -> str: 

357 """Return a string describing an instance.""" 

358 

359 return state_str(instance_state(instance)) 

360 

361 

362def state_str(state: InstanceState[Any]) -> str: 

363 """Return a string describing an instance via its InstanceState.""" 

364 

365 if state is None: 

366 return "None" 

367 else: 

368 return "<%s at 0x%x>" % (state.class_.__name__, id(state.obj())) 

369 

370 

371def state_class_str(state: InstanceState[Any]) -> str: 

372 """Return a string describing an instance's class via its 

373 InstanceState. 

374 """ 

375 

376 if state is None: 

377 return "None" 

378 else: 

379 return "<%s>" % (state.class_.__name__,) 

380 

381 

382def attribute_str(instance: object, attribute: str) -> str: 

383 return instance_str(instance) + "." + attribute 

384 

385 

386def state_attribute_str(state: InstanceState[Any], attribute: str) -> str: 

387 return state_str(state) + "." + attribute 

388 

389 

390def entity_str(entity: Any) -> str: 

391 """Return a user-facing string for a mapped entity, such as a mapped 

392 class, :class:`_orm.Mapper`, or :func:`_orm.aliased` construct. 

393 

394 Also accepts a :class:`_orm.PathRegistry` directly, which is itself 

395 ``inspect()``-able and implements ``path_string()``; in that case 

396 this is equivalent to calling 

397 :meth:`_orm.PathRegistry.path_string` directly. 

398 

399 """ 

400 return cast(_HasPathString, inspection.inspect(entity)).path_string() 

401 

402 

403def object_mapper(instance: _T) -> Mapper[_T]: 

404 """Given an object, return the primary Mapper associated with the object 

405 instance. 

406 

407 Raises :class:`sqlalchemy.orm.exc.UnmappedInstanceError` 

408 if no mapping is configured. 

409 

410 This function is available via the inspection system as:: 

411 

412 inspect(instance).mapper 

413 

414 Using the inspection system will raise 

415 :class:`sqlalchemy.exc.NoInspectionAvailable` if the instance is 

416 not part of a mapping. 

417 

418 """ 

419 return object_state(instance).mapper 

420 

421 

422def object_state(instance: _T) -> InstanceState[_T]: 

423 """Given an object, return the :class:`.InstanceState` 

424 associated with the object. 

425 

426 Raises :class:`sqlalchemy.orm.exc.UnmappedInstanceError` 

427 if no mapping is configured. 

428 

429 Equivalent functionality is available via the :func:`_sa.inspect` 

430 function as:: 

431 

432 inspect(instance) 

433 

434 Using the inspection system will raise 

435 :class:`sqlalchemy.exc.NoInspectionAvailable` if the instance is 

436 not part of a mapping. 

437 

438 """ 

439 state = _inspect_mapped_object(instance) 

440 if state is None: 

441 raise exc.UnmappedInstanceError(instance) 

442 else: 

443 return state 

444 

445 

446@inspection._inspects(object) 

447def _inspect_mapped_object(instance: _T) -> Optional[InstanceState[_T]]: 

448 try: 

449 return instance_state(instance) 

450 except (exc.UnmappedClassError,) + exc.NO_STATE: 

451 return None 

452 

453 

454def _class_to_mapper( 

455 class_or_mapper: Union[Mapper[_T], Type[_T]], 

456) -> Mapper[_T]: 

457 # can't get mypy to see an overload for this 

458 insp = inspection.inspect(class_or_mapper, False) 

459 if insp is not None: 

460 return insp.mapper # type: ignore[no-any-return] 

461 else: 

462 assert isinstance(class_or_mapper, type) 

463 raise exc.UnmappedClassError(class_or_mapper) 

464 

465 

466def _mapper_or_none( 

467 entity: Union[Type[_T], _InternalEntityType[_T]], 

468) -> Optional[Mapper[_T]]: 

469 """Return the :class:`_orm.Mapper` for the given class or None if the 

470 class is not mapped. 

471 """ 

472 

473 # can't get mypy to see an overload for this 

474 insp = inspection.inspect(entity, False) 

475 if insp is not None: 

476 return insp.mapper # type: ignore[no-any-return] 

477 else: 

478 return None 

479 

480 

481def _is_mapped_class(entity: Any) -> bool: 

482 """Return True if the given object is a mapped class, 

483 :class:`_orm.Mapper`, or :class:`.AliasedClass`. 

484 """ 

485 

486 insp = inspection.inspect(entity, False) 

487 return ( 

488 insp is not None 

489 and not insp.is_clause_element 

490 and (insp.is_mapper or insp.is_aliased_class) 

491 ) 

492 

493 

494def _is_aliased_class(entity: Any) -> bool: 

495 insp = inspection.inspect(entity, False) 

496 return insp is not None and getattr(insp, "is_aliased_class", False) 

497 

498 

499@no_type_check 

500def _entity_descriptor(entity: _EntityType[Any], key: str) -> Any: 

501 """Return a class attribute given an entity and string name. 

502 

503 May return :class:`.InstrumentedAttribute` or user-defined 

504 attribute. 

505 

506 """ 

507 insp = inspection.inspect(entity) 

508 if insp.is_selectable: 

509 description = entity 

510 entity = insp.c 

511 elif insp.is_aliased_class: 

512 entity = insp.entity 

513 description = entity 

514 elif hasattr(insp, "mapper"): 

515 description = entity = insp.mapper.class_ 

516 else: 

517 description = entity 

518 

519 try: 

520 return getattr(entity, key) 

521 except AttributeError as err: 

522 raise sa_exc.InvalidRequestError( 

523 "Entity '%s' has no property '%s'" % (description, key) 

524 ) from err 

525 

526 

527if TYPE_CHECKING: 

528 

529 def _state_mapper(state: InstanceState[_O]) -> Mapper[_O]: ... 

530 

531else: 

532 _state_mapper = util.dottedgetter("manager.mapper") 

533 

534 

535def _inspect_mapped_class( 

536 class_: Type[_O], configure: bool = False 

537) -> Optional[Mapper[_O]]: 

538 try: 

539 class_manager = opt_manager_of_class(class_) 

540 if class_manager is None or not class_manager.is_mapped: 

541 return None 

542 mapper = class_manager.mapper 

543 except exc.NO_STATE: 

544 return None 

545 else: 

546 if configure: 

547 mapper._check_configure() 

548 return mapper 

549 

550 

551def _parse_mapper_argument(arg: Union[Mapper[_O], Type[_O]]) -> Mapper[_O]: 

552 insp = inspection.inspect(arg, raiseerr=False) 

553 if insp_is_mapper(insp): 

554 return insp 

555 

556 raise sa_exc.ArgumentError(f"Mapper or mapped class expected, got {arg!r}") 

557 

558 

559def class_mapper(class_: Type[_O], configure: bool = True) -> Mapper[_O]: 

560 """Given a class, return the primary :class:`_orm.Mapper` associated 

561 with the key. 

562 

563 Raises :exc:`.UnmappedClassError` if no mapping is configured 

564 on the given class, or :exc:`.ArgumentError` if a non-class 

565 object is passed. 

566 

567 Equivalent functionality is available via the :func:`_sa.inspect` 

568 function as:: 

569 

570 inspect(some_mapped_class) 

571 

572 Using the inspection system will raise 

573 :class:`sqlalchemy.exc.NoInspectionAvailable` if the class is not mapped. 

574 

575 """ 

576 mapper = _inspect_mapped_class(class_, configure=configure) 

577 if mapper is None: 

578 if not isinstance(class_, type): 

579 raise sa_exc.ArgumentError( 

580 "Class object expected, got '%r'." % (class_,) 

581 ) 

582 raise exc.UnmappedClassError(class_) 

583 else: 

584 return mapper 

585 

586 

587class InspectionAttr: 

588 """A base class applied to all ORM objects and attributes that are 

589 related to things that can be returned by the :func:`_sa.inspect` function. 

590 

591 The attributes defined here allow the usage of simple boolean 

592 checks to test basic facts about the object returned. 

593 

594 While the boolean checks here are basically the same as using 

595 the Python isinstance() function, the flags here can be used without 

596 the need to import all of these classes, and also such that 

597 the SQLAlchemy class system can change while leaving the flags 

598 here intact for forwards-compatibility. 

599 

600 """ 

601 

602 __slots__: Tuple[str, ...] = () 

603 

604 is_selectable = False 

605 """Return True if this object is an instance of 

606 :class:`_expression.Selectable`.""" 

607 

608 is_aliased_class = False 

609 """True if this object is an instance of :class:`.AliasedClass`.""" 

610 

611 is_instance = False 

612 """True if this object is an instance of :class:`.InstanceState`.""" 

613 

614 is_mapper = False 

615 """True if this object is an instance of :class:`_orm.Mapper`.""" 

616 

617 is_bundle = False 

618 """True if this object is an instance of :class:`.Bundle`.""" 

619 

620 is_property = False 

621 """True if this object is an instance of :class:`.MapperProperty`.""" 

622 

623 is_attribute = False 

624 """True if this object is a Python :term:`descriptor`. 

625 

626 This can refer to one of many types. Usually a 

627 :class:`.QueryableAttribute` which handles attributes events on behalf 

628 of a :class:`.MapperProperty`. But can also be an extension type 

629 such as :class:`.AssociationProxy` or :class:`.hybrid_property`. 

630 The :attr:`.InspectionAttr.extension_type` will refer to a constant 

631 identifying the specific subtype. 

632 

633 .. seealso:: 

634 

635 :attr:`_orm.Mapper.all_orm_descriptors` 

636 

637 """ 

638 

639 _is_internal_proxy = False 

640 """True if this object is an internal proxy object.""" 

641 

642 is_clause_element = False 

643 """True if this object is an instance of 

644 :class:`_expression.ClauseElement`.""" 

645 

646 extension_type: InspectionAttrExtensionType = NotExtension.NOT_EXTENSION 

647 """The extension type, if any. 

648 Defaults to :attr:`.interfaces.NotExtension.NOT_EXTENSION` 

649 

650 .. seealso:: 

651 

652 :class:`.HybridExtensionType` 

653 

654 :class:`.AssociationProxyExtensionType` 

655 

656 """ 

657 

658 

659class InspectionAttrInfo(InspectionAttr): 

660 """Adds the ``.info`` attribute to :class:`.InspectionAttr`. 

661 

662 The rationale for :class:`.InspectionAttr` vs. :class:`.InspectionAttrInfo` 

663 is that the former is compatible as a mixin for classes that specify 

664 ``__slots__``; this is essentially an implementation artifact. 

665 

666 """ 

667 

668 __slots__ = () 

669 

670 @util.ro_memoized_property 

671 def info(self) -> _InfoType: 

672 """Info dictionary associated with the object, allowing user-defined 

673 data to be associated with this :class:`.InspectionAttr`. 

674 

675 The dictionary is generated when first accessed. Alternatively, 

676 it can be specified as a constructor argument to the 

677 :func:`.column_property`, :func:`_orm.relationship`, or 

678 :func:`.composite` 

679 functions. 

680 

681 .. seealso:: 

682 

683 :attr:`.QueryableAttribute.info` 

684 

685 :attr:`.SchemaItem.info` 

686 

687 """ 

688 return {} 

689 

690 

691class SQLORMOperations(SQLCoreOperations[_T_co], TypingOnly): 

692 __slots__ = () 

693 

694 if typing.TYPE_CHECKING: 

695 

696 def of_type( 

697 self, class_: _EntityType[Any] 

698 ) -> PropComparator[_T_co]: ... 

699 

700 def and_( 

701 self, *criteria: _ColumnExpressionArgument[bool] 

702 ) -> PropComparator[bool]: ... 

703 

704 def any( # noqa: A001 

705 self, 

706 criterion: Optional[_ColumnExpressionArgument[bool]] = None, 

707 **kwargs: Any, 

708 ) -> ColumnElement[bool]: ... 

709 

710 def has( 

711 self, 

712 criterion: Optional[_ColumnExpressionArgument[bool]] = None, 

713 **kwargs: Any, 

714 ) -> ColumnElement[bool]: ... 

715 

716 

717class ORMDescriptor(Generic[_T_co], TypingOnly): 

718 """Represent any Python descriptor that provides a SQL expression 

719 construct at the class level.""" 

720 

721 __slots__ = () 

722 

723 if typing.TYPE_CHECKING: 

724 

725 @overload 

726 def __get__( 

727 self, instance: Any, owner: Literal[None] 

728 ) -> ORMDescriptor[_T_co]: ... 

729 

730 @overload 

731 def __get__( 

732 self, instance: Literal[None], owner: Any 

733 ) -> SQLCoreOperations[_T_co]: ... 

734 

735 @overload 

736 def __get__(self, instance: object, owner: Any) -> _T_co: ... 

737 

738 def __get__( 

739 self, instance: object, owner: Any 

740 ) -> Union[ORMDescriptor[_T_co], SQLCoreOperations[_T_co], _T_co]: ... 

741 

742 

743class _MappedAnnotationBase(Generic[_T_co], TypingOnly): 

744 """common class for Mapped and similar ORM container classes. 

745 

746 these are classes that can appear on the left side of an ORM declarative 

747 mapping, containing a mapped class or in some cases a collection 

748 surrounding a mapped class. 

749 

750 """ 

751 

752 __slots__ = () 

753 

754 

755class SQLORMExpression( 

756 SQLORMOperations[_T_co], SQLColumnExpression[_T_co], TypingOnly 

757): 

758 """A type that may be used to indicate any ORM-level attribute or 

759 object that acts in place of one, in the context of SQL expression 

760 construction. 

761 

762 :class:`.SQLORMExpression` extends from the Core 

763 :class:`.SQLColumnExpression` to add additional SQL methods that are ORM 

764 specific, such as :meth:`.PropComparator.of_type`, and is part of the bases 

765 for :class:`.InstrumentedAttribute`. It may be used in :pep:`484` typing to 

766 indicate arguments or return values that should behave as ORM-level 

767 attribute expressions. 

768 

769 .. versionadded:: 2.0.0b4 

770 

771 

772 """ 

773 

774 __slots__ = () 

775 

776 

777class Mapped( 

778 SQLORMExpression[_T_co], 

779 ORMDescriptor[_T_co], 

780 _MappedAnnotationBase[_T_co], 

781 roles.DDLConstraintColumnRole, 

782): 

783 """Represent an ORM mapped attribute on a mapped class. 

784 

785 This class represents the complete descriptor interface for any class 

786 attribute that will have been :term:`instrumented` by the ORM 

787 :class:`_orm.Mapper` class. Provides appropriate information to type 

788 checkers such as pylance and mypy so that ORM-mapped attributes 

789 are correctly typed. 

790 

791 The most prominent use of :class:`_orm.Mapped` is in 

792 the :ref:`Declarative Mapping <orm_explicit_declarative_base>` form 

793 of :class:`_orm.Mapper` configuration, where used explicitly it drives 

794 the configuration of ORM attributes such as :func:`_orm.mapped_class` 

795 and :func:`_orm.relationship`. 

796 

797 .. seealso:: 

798 

799 :ref:`orm_explicit_declarative_base` 

800 

801 :ref:`orm_declarative_table` 

802 

803 .. tip:: 

804 

805 The :class:`_orm.Mapped` class represents attributes that are handled 

806 directly by the :class:`_orm.Mapper` class. It does not include other 

807 Python descriptor classes that are provided as extensions, including 

808 :ref:`hybrids_toplevel` and the :ref:`associationproxy_toplevel`. 

809 While these systems still make use of ORM-specific superclasses 

810 and structures, they are not :term:`instrumented` by the 

811 :class:`_orm.Mapper` and instead provide their own functionality 

812 when they are accessed on a class. 

813 

814 .. versionadded:: 1.4 

815 

816 

817 """ 

818 

819 __slots__ = () 

820 

821 if typing.TYPE_CHECKING: 

822 

823 @overload 

824 def __get__( # type: ignore[misc] 

825 self: MappedColumn[_T_co], instance: TypedColumns, owner: Any 

826 ) -> Column[_T_co]: ... 

827 

828 @overload 

829 def __get__( 

830 self, instance: None, owner: Any 

831 ) -> InstrumentedAttribute[_T_co]: ... 

832 

833 @overload 

834 def __get__(self, instance: object, owner: Any) -> _T_co: ... 

835 

836 def __get__( 

837 self, instance: Optional[object], owner: Any 

838 ) -> Union[InstrumentedAttribute[_T_co], Column[_T_co], _T_co]: ... 

839 

840 @classmethod 

841 def _empty_constructor(cls, arg1: Any) -> Mapped[_T_co]: ... 

842 

843 def __set__( 

844 self, instance: Any, value: Union[SQLCoreOperations[_T_co], _T_co] 

845 ) -> None: ... 

846 

847 def __delete__(self, instance: Any) -> None: ... 

848 

849 

850class _MappedAttribute(Generic[_T_co], TypingOnly): 

851 """Mixin for attributes which should be replaced by mapper-assigned 

852 attributes. 

853 

854 """ 

855 

856 __slots__ = () 

857 

858 

859class _DeclarativeMapped(Mapped[_T_co], _MappedAttribute[_T_co]): 

860 """Mixin for :class:`.MapperProperty` subclasses that allows them to 

861 be compatible with ORM-annotated declarative mappings. 

862 

863 """ 

864 

865 __slots__ = () 

866 

867 # MappedSQLExpression, Relationship, Composite etc. dont actually do 

868 # SQL expression behavior. yet there is code that compares them with 

869 # __eq__(), __ne__(), etc. Since #8847 made Mapped even more full 

870 # featured including ColumnOperators, we need to have those methods 

871 # be no-ops for these objects, so return NotImplemented to fall back 

872 # to normal comparison behavior. 

873 def operate(self, op: OperatorType, *other: Any, **kwargs: Any) -> Any: 

874 return NotImplemented 

875 

876 __sa_operate__ = operate 

877 

878 def reverse_operate( 

879 self, op: OperatorType, other: Any, **kwargs: Any 

880 ) -> Any: 

881 return NotImplemented 

882 

883 

884class DynamicMapped(_MappedAnnotationBase[_T_co]): 

885 """Represent the ORM mapped attribute type for a "dynamic" relationship. 

886 

887 The :class:`_orm.DynamicMapped` type annotation may be used in an 

888 :ref:`Annotated Declarative Table <orm_declarative_mapped_column>` mapping 

889 to indicate that the ``lazy="dynamic"`` loader strategy should be used 

890 for a particular :func:`_orm.relationship`. 

891 

892 .. legacy:: The "dynamic" lazy loader strategy is the legacy form of what 

893 is now the "write_only" strategy described in the section 

894 :ref:`write_only_relationship`. 

895 

896 E.g.:: 

897 

898 class User(Base): 

899 __tablename__ = "user" 

900 id: Mapped[int] = mapped_column(primary_key=True) 

901 addresses: DynamicMapped[Address] = relationship( 

902 cascade="all,delete-orphan" 

903 ) 

904 

905 See the section :ref:`dynamic_relationship` for background. 

906 

907 .. versionadded:: 2.0 

908 

909 .. seealso:: 

910 

911 :ref:`dynamic_relationship` - complete background 

912 

913 :class:`.WriteOnlyMapped` - fully 2.0 style version 

914 

915 """ 

916 

917 __slots__ = () 

918 

919 if TYPE_CHECKING: 

920 

921 @overload 

922 def __get__( 

923 self, instance: None, owner: Any 

924 ) -> InstrumentedAttribute[_T_co]: ... 

925 

926 @overload 

927 def __get__( 

928 self, instance: object, owner: Any 

929 ) -> AppenderQuery[_T_co]: ... 

930 

931 def __get__( 

932 self, instance: Optional[object], owner: Any 

933 ) -> Union[InstrumentedAttribute[_T_co], AppenderQuery[_T_co]]: ... 

934 

935 def __set__( 

936 self, instance: Any, value: typing.Collection[_T_co] 

937 ) -> None: ... 

938 

939 

940class WriteOnlyMapped(_MappedAnnotationBase[_T_co]): 

941 """Represent the ORM mapped attribute type for a "write only" relationship. 

942 

943 The :class:`_orm.WriteOnlyMapped` type annotation may be used in an 

944 :ref:`Annotated Declarative Table <orm_declarative_mapped_column>` mapping 

945 to indicate that the ``lazy="write_only"`` loader strategy should be used 

946 for a particular :func:`_orm.relationship`. 

947 

948 E.g.:: 

949 

950 class User(Base): 

951 __tablename__ = "user" 

952 id: Mapped[int] = mapped_column(primary_key=True) 

953 addresses: WriteOnlyMapped[Address] = relationship( 

954 cascade="all,delete-orphan" 

955 ) 

956 

957 See the section :ref:`write_only_relationship` for background. 

958 

959 .. versionadded:: 2.0 

960 

961 .. seealso:: 

962 

963 :ref:`write_only_relationship` - complete background 

964 

965 :class:`.DynamicMapped` - includes legacy :class:`_orm.Query` support 

966 

967 """ 

968 

969 __slots__ = () 

970 

971 if TYPE_CHECKING: 

972 

973 @overload 

974 def __get__( 

975 self, instance: None, owner: Any 

976 ) -> InstrumentedAttribute[_T_co]: ... 

977 

978 @overload 

979 def __get__( 

980 self, instance: object, owner: Any 

981 ) -> WriteOnlyCollection[_T_co]: ... 

982 

983 def __get__( 

984 self, instance: Optional[object], owner: Any 

985 ) -> Union[ 

986 InstrumentedAttribute[_T_co], WriteOnlyCollection[_T_co] 

987 ]: ... 

988 

989 def __set__( 

990 self, instance: Any, value: typing.Collection[_T_co] 

991 ) -> None: ...