decl_api.py 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893
  1. # orm/decl_api.py
  2. # Copyright (C) 2005-2024 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. """Public API functions and helpers for declarative."""
  8. from __future__ import annotations
  9. import itertools
  10. import re
  11. import typing
  12. from typing import Any
  13. from typing import Callable
  14. from typing import cast
  15. from typing import ClassVar
  16. from typing import Dict
  17. from typing import FrozenSet
  18. from typing import Generic
  19. from typing import Iterable
  20. from typing import Iterator
  21. from typing import Mapping
  22. from typing import Optional
  23. from typing import overload
  24. from typing import Set
  25. from typing import Tuple
  26. from typing import Type
  27. from typing import TYPE_CHECKING
  28. from typing import TypeVar
  29. from typing import Union
  30. import weakref
  31. from . import attributes
  32. from . import clsregistry
  33. from . import instrumentation
  34. from . import interfaces
  35. from . import mapperlib
  36. from ._orm_constructors import composite
  37. from ._orm_constructors import deferred
  38. from ._orm_constructors import mapped_column
  39. from ._orm_constructors import relationship
  40. from ._orm_constructors import synonym
  41. from .attributes import InstrumentedAttribute
  42. from .base import _inspect_mapped_class
  43. from .base import _is_mapped_class
  44. from .base import Mapped
  45. from .base import ORMDescriptor
  46. from .decl_base import _add_attribute
  47. from .decl_base import _as_declarative
  48. from .decl_base import _ClassScanMapperConfig
  49. from .decl_base import _declarative_constructor
  50. from .decl_base import _DeferredMapperConfig
  51. from .decl_base import _del_attribute
  52. from .decl_base import _mapper
  53. from .descriptor_props import Composite
  54. from .descriptor_props import Synonym
  55. from .descriptor_props import Synonym as _orm_synonym
  56. from .mapper import Mapper
  57. from .properties import MappedColumn
  58. from .relationships import RelationshipProperty
  59. from .state import InstanceState
  60. from .. import exc
  61. from .. import inspection
  62. from .. import util
  63. from ..sql import sqltypes
  64. from ..sql.base import _NoArg
  65. from ..sql.elements import SQLCoreOperations
  66. from ..sql.schema import MetaData
  67. from ..sql.selectable import FromClause
  68. from ..util import hybridmethod
  69. from ..util import hybridproperty
  70. from ..util import typing as compat_typing
  71. from ..util.typing import CallableReference
  72. from ..util.typing import flatten_newtype
  73. from ..util.typing import is_generic
  74. from ..util.typing import is_literal
  75. from ..util.typing import is_newtype
  76. from ..util.typing import is_pep695
  77. from ..util.typing import Literal
  78. from ..util.typing import Self
  79. if TYPE_CHECKING:
  80. from ._typing import _O
  81. from ._typing import _RegistryType
  82. from .decl_base import _DataclassArguments
  83. from .instrumentation import ClassManager
  84. from .interfaces import MapperProperty
  85. from .state import InstanceState # noqa
  86. from ..sql._typing import _TypeEngineArgument
  87. from ..sql.type_api import _MatchedOnType
  88. _T = TypeVar("_T", bound=Any)
  89. _TT = TypeVar("_TT", bound=Any)
  90. # it's not clear how to have Annotated, Union objects etc. as keys here
  91. # from a typing perspective so just leave it open ended for now
  92. _TypeAnnotationMapType = Mapping[Any, "_TypeEngineArgument[Any]"]
  93. _MutableTypeAnnotationMapType = Dict[Any, "_TypeEngineArgument[Any]"]
  94. _DeclaredAttrDecorated = Callable[
  95. ..., Union[Mapped[_T], ORMDescriptor[_T], SQLCoreOperations[_T]]
  96. ]
  97. def has_inherited_table(cls: Type[_O]) -> bool:
  98. """Given a class, return True if any of the classes it inherits from has a
  99. mapped table, otherwise return False.
  100. This is used in declarative mixins to build attributes that behave
  101. differently for the base class vs. a subclass in an inheritance
  102. hierarchy.
  103. .. seealso::
  104. :ref:`decl_mixin_inheritance`
  105. """
  106. for class_ in cls.__mro__[1:]:
  107. if getattr(class_, "__table__", None) is not None:
  108. return True
  109. return False
  110. class _DynamicAttributesType(type):
  111. def __setattr__(cls, key: str, value: Any) -> None:
  112. if "__mapper__" in cls.__dict__:
  113. _add_attribute(cls, key, value)
  114. else:
  115. type.__setattr__(cls, key, value)
  116. def __delattr__(cls, key: str) -> None:
  117. if "__mapper__" in cls.__dict__:
  118. _del_attribute(cls, key)
  119. else:
  120. type.__delattr__(cls, key)
  121. class DeclarativeAttributeIntercept(
  122. _DynamicAttributesType,
  123. # Inspectable is used only by the mypy plugin
  124. inspection.Inspectable[Mapper[Any]],
  125. ):
  126. """Metaclass that may be used in conjunction with the
  127. :class:`_orm.DeclarativeBase` class to support addition of class
  128. attributes dynamically.
  129. """
  130. @compat_typing.dataclass_transform(
  131. field_specifiers=(
  132. MappedColumn,
  133. RelationshipProperty,
  134. Composite,
  135. Synonym,
  136. mapped_column,
  137. relationship,
  138. composite,
  139. synonym,
  140. deferred,
  141. ),
  142. )
  143. class DCTransformDeclarative(DeclarativeAttributeIntercept):
  144. """metaclass that includes @dataclass_transforms"""
  145. class DeclarativeMeta(DeclarativeAttributeIntercept):
  146. metadata: MetaData
  147. registry: RegistryType
  148. def __init__(
  149. cls, classname: Any, bases: Any, dict_: Any, **kw: Any
  150. ) -> None:
  151. # use cls.__dict__, which can be modified by an
  152. # __init_subclass__() method (#7900)
  153. dict_ = cls.__dict__
  154. # early-consume registry from the initial declarative base,
  155. # assign privately to not conflict with subclass attributes named
  156. # "registry"
  157. reg = getattr(cls, "_sa_registry", None)
  158. if reg is None:
  159. reg = dict_.get("registry", None)
  160. if not isinstance(reg, registry):
  161. raise exc.InvalidRequestError(
  162. "Declarative base class has no 'registry' attribute, "
  163. "or registry is not a sqlalchemy.orm.registry() object"
  164. )
  165. else:
  166. cls._sa_registry = reg
  167. if not cls.__dict__.get("__abstract__", False):
  168. _as_declarative(reg, cls, dict_)
  169. type.__init__(cls, classname, bases, dict_)
  170. def synonym_for(
  171. name: str, map_column: bool = False
  172. ) -> Callable[[Callable[..., Any]], Synonym[Any]]:
  173. """Decorator that produces an :func:`_orm.synonym`
  174. attribute in conjunction with a Python descriptor.
  175. The function being decorated is passed to :func:`_orm.synonym` as the
  176. :paramref:`.orm.synonym.descriptor` parameter::
  177. class MyClass(Base):
  178. __tablename__ = 'my_table'
  179. id = Column(Integer, primary_key=True)
  180. _job_status = Column("job_status", String(50))
  181. @synonym_for("job_status")
  182. @property
  183. def job_status(self):
  184. return "Status: %s" % self._job_status
  185. The :ref:`hybrid properties <mapper_hybrids>` feature of SQLAlchemy
  186. is typically preferred instead of synonyms, which is a more legacy
  187. feature.
  188. .. seealso::
  189. :ref:`synonyms` - Overview of synonyms
  190. :func:`_orm.synonym` - the mapper-level function
  191. :ref:`mapper_hybrids` - The Hybrid Attribute extension provides an
  192. updated approach to augmenting attribute behavior more flexibly than
  193. can be achieved with synonyms.
  194. """
  195. def decorate(fn: Callable[..., Any]) -> Synonym[Any]:
  196. return _orm_synonym(name, map_column=map_column, descriptor=fn)
  197. return decorate
  198. class _declared_attr_common:
  199. def __init__(
  200. self,
  201. fn: Callable[..., Any],
  202. cascading: bool = False,
  203. quiet: bool = False,
  204. ):
  205. # suppport
  206. # @declared_attr
  207. # @classmethod
  208. # def foo(cls) -> Mapped[thing]:
  209. # ...
  210. # which seems to help typing tools interpret the fn as a classmethod
  211. # for situations where needed
  212. if isinstance(fn, classmethod):
  213. fn = fn.__func__
  214. self.fget = fn
  215. self._cascading = cascading
  216. self._quiet = quiet
  217. self.__doc__ = fn.__doc__
  218. def _collect_return_annotation(self) -> Optional[Type[Any]]:
  219. return util.get_annotations(self.fget).get("return")
  220. def __get__(self, instance: Optional[object], owner: Any) -> Any:
  221. # the declared_attr needs to make use of a cache that exists
  222. # for the span of the declarative scan_attributes() phase.
  223. # to achieve this we look at the class manager that's configured.
  224. # note this method should not be called outside of the declarative
  225. # setup phase
  226. cls = owner
  227. manager = attributes.opt_manager_of_class(cls)
  228. if manager is None:
  229. if not re.match(r"^__.+__$", self.fget.__name__):
  230. # if there is no manager at all, then this class hasn't been
  231. # run through declarative or mapper() at all, emit a warning.
  232. util.warn(
  233. "Unmanaged access of declarative attribute %s from "
  234. "non-mapped class %s" % (self.fget.__name__, cls.__name__)
  235. )
  236. return self.fget(cls)
  237. elif manager.is_mapped:
  238. # the class is mapped, which means we're outside of the declarative
  239. # scan setup, just run the function.
  240. return self.fget(cls)
  241. # here, we are inside of the declarative scan. use the registry
  242. # that is tracking the values of these attributes.
  243. declarative_scan = manager.declarative_scan()
  244. # assert that we are in fact in the declarative scan
  245. assert declarative_scan is not None
  246. reg = declarative_scan.declared_attr_reg
  247. if self in reg:
  248. return reg[self]
  249. else:
  250. reg[self] = obj = self.fget(cls)
  251. return obj
  252. class _declared_directive(_declared_attr_common, Generic[_T]):
  253. # see mapping_api.rst for docstring
  254. if typing.TYPE_CHECKING:
  255. def __init__(
  256. self,
  257. fn: Callable[..., _T],
  258. cascading: bool = False,
  259. ):
  260. ...
  261. def __get__(self, instance: Optional[object], owner: Any) -> _T:
  262. ...
  263. def __set__(self, instance: Any, value: Any) -> None:
  264. ...
  265. def __delete__(self, instance: Any) -> None:
  266. ...
  267. def __call__(self, fn: Callable[..., _TT]) -> _declared_directive[_TT]:
  268. # extensive fooling of mypy underway...
  269. ...
  270. class declared_attr(interfaces._MappedAttribute[_T], _declared_attr_common):
  271. """Mark a class-level method as representing the definition of
  272. a mapped property or Declarative directive.
  273. :class:`_orm.declared_attr` is typically applied as a decorator to a class
  274. level method, turning the attribute into a scalar-like property that can be
  275. invoked from the uninstantiated class. The Declarative mapping process
  276. looks for these :class:`_orm.declared_attr` callables as it scans classes,
  277. and assumes any attribute marked with :class:`_orm.declared_attr` will be a
  278. callable that will produce an object specific to the Declarative mapping or
  279. table configuration.
  280. :class:`_orm.declared_attr` is usually applicable to
  281. :ref:`mixins <orm_mixins_toplevel>`, to define relationships that are to be
  282. applied to different implementors of the class. It may also be used to
  283. define dynamically generated column expressions and other Declarative
  284. attributes.
  285. Example::
  286. class ProvidesUserMixin:
  287. "A mixin that adds a 'user' relationship to classes."
  288. user_id: Mapped[int] = mapped_column(ForeignKey("user_table.id"))
  289. @declared_attr
  290. def user(cls) -> Mapped["User"]:
  291. return relationship("User")
  292. When used with Declarative directives such as ``__tablename__``, the
  293. :meth:`_orm.declared_attr.directive` modifier may be used which indicates
  294. to :pep:`484` typing tools that the given method is not dealing with
  295. :class:`_orm.Mapped` attributes::
  296. class CreateTableName:
  297. @declared_attr.directive
  298. def __tablename__(cls) -> str:
  299. return cls.__name__.lower()
  300. :class:`_orm.declared_attr` can also be applied directly to mapped
  301. classes, to allow for attributes that dynamically configure themselves
  302. on subclasses when using mapped inheritance schemes. Below
  303. illustrates :class:`_orm.declared_attr` to create a dynamic scheme
  304. for generating the :paramref:`_orm.Mapper.polymorphic_identity` parameter
  305. for subclasses::
  306. class Employee(Base):
  307. __tablename__ = 'employee'
  308. id: Mapped[int] = mapped_column(primary_key=True)
  309. type: Mapped[str] = mapped_column(String(50))
  310. @declared_attr.directive
  311. def __mapper_args__(cls) -> Dict[str, Any]:
  312. if cls.__name__ == 'Employee':
  313. return {
  314. "polymorphic_on":cls.type,
  315. "polymorphic_identity":"Employee"
  316. }
  317. else:
  318. return {"polymorphic_identity":cls.__name__}
  319. class Engineer(Employee):
  320. pass
  321. :class:`_orm.declared_attr` supports decorating functions that are
  322. explicitly decorated with ``@classmethod``. This is never necessary from a
  323. runtime perspective, however may be needed in order to support :pep:`484`
  324. typing tools that don't otherwise recognize the decorated function as
  325. having class-level behaviors for the ``cls`` parameter::
  326. class SomethingMixin:
  327. x: Mapped[int]
  328. y: Mapped[int]
  329. @declared_attr
  330. @classmethod
  331. def x_plus_y(cls) -> Mapped[int]:
  332. return column_property(cls.x + cls.y)
  333. .. versionadded:: 2.0 - :class:`_orm.declared_attr` can accommodate a
  334. function decorated with ``@classmethod`` to help with :pep:`484`
  335. integration where needed.
  336. .. seealso::
  337. :ref:`orm_mixins_toplevel` - Declarative Mixin documentation with
  338. background on use patterns for :class:`_orm.declared_attr`.
  339. """ # noqa: E501
  340. if typing.TYPE_CHECKING:
  341. def __init__(
  342. self,
  343. fn: _DeclaredAttrDecorated[_T],
  344. cascading: bool = False,
  345. ):
  346. ...
  347. def __set__(self, instance: Any, value: Any) -> None:
  348. ...
  349. def __delete__(self, instance: Any) -> None:
  350. ...
  351. # this is the Mapped[] API where at class descriptor get time we want
  352. # the type checker to see InstrumentedAttribute[_T]. However the
  353. # callable function prior to mapping in fact calls the given
  354. # declarative function that does not return InstrumentedAttribute
  355. @overload
  356. def __get__(
  357. self, instance: None, owner: Any
  358. ) -> InstrumentedAttribute[_T]:
  359. ...
  360. @overload
  361. def __get__(self, instance: object, owner: Any) -> _T:
  362. ...
  363. def __get__(
  364. self, instance: Optional[object], owner: Any
  365. ) -> Union[InstrumentedAttribute[_T], _T]:
  366. ...
  367. @hybridmethod
  368. def _stateful(cls, **kw: Any) -> _stateful_declared_attr[_T]:
  369. return _stateful_declared_attr(**kw)
  370. @hybridproperty
  371. def directive(cls) -> _declared_directive[Any]:
  372. # see mapping_api.rst for docstring
  373. return _declared_directive # type: ignore
  374. @hybridproperty
  375. def cascading(cls) -> _stateful_declared_attr[_T]:
  376. # see mapping_api.rst for docstring
  377. return cls._stateful(cascading=True)
  378. class _stateful_declared_attr(declared_attr[_T]):
  379. kw: Dict[str, Any]
  380. def __init__(self, **kw: Any):
  381. self.kw = kw
  382. @hybridmethod
  383. def _stateful(self, **kw: Any) -> _stateful_declared_attr[_T]:
  384. new_kw = self.kw.copy()
  385. new_kw.update(kw)
  386. return _stateful_declared_attr(**new_kw)
  387. def __call__(self, fn: _DeclaredAttrDecorated[_T]) -> declared_attr[_T]:
  388. return declared_attr(fn, **self.kw)
  389. def declarative_mixin(cls: Type[_T]) -> Type[_T]:
  390. """Mark a class as providing the feature of "declarative mixin".
  391. E.g.::
  392. from sqlalchemy.orm import declared_attr
  393. from sqlalchemy.orm import declarative_mixin
  394. @declarative_mixin
  395. class MyMixin:
  396. @declared_attr
  397. def __tablename__(cls):
  398. return cls.__name__.lower()
  399. __table_args__ = {'mysql_engine': 'InnoDB'}
  400. __mapper_args__= {'always_refresh': True}
  401. id = Column(Integer, primary_key=True)
  402. class MyModel(MyMixin, Base):
  403. name = Column(String(1000))
  404. The :func:`_orm.declarative_mixin` decorator currently does not modify
  405. the given class in any way; it's current purpose is strictly to assist
  406. the :ref:`Mypy plugin <mypy_toplevel>` in being able to identify
  407. SQLAlchemy declarative mixin classes when no other context is present.
  408. .. versionadded:: 1.4.6
  409. .. seealso::
  410. :ref:`orm_mixins_toplevel`
  411. :ref:`mypy_declarative_mixins` - in the
  412. :ref:`Mypy plugin documentation <mypy_toplevel>`
  413. """ # noqa: E501
  414. return cls
  415. def _setup_declarative_base(cls: Type[Any]) -> None:
  416. if "metadata" in cls.__dict__:
  417. metadata = cls.__dict__["metadata"]
  418. else:
  419. metadata = None
  420. if "type_annotation_map" in cls.__dict__:
  421. type_annotation_map = cls.__dict__["type_annotation_map"]
  422. else:
  423. type_annotation_map = None
  424. reg = cls.__dict__.get("registry", None)
  425. if reg is not None:
  426. if not isinstance(reg, registry):
  427. raise exc.InvalidRequestError(
  428. "Declarative base class has a 'registry' attribute that is "
  429. "not an instance of sqlalchemy.orm.registry()"
  430. )
  431. elif type_annotation_map is not None:
  432. raise exc.InvalidRequestError(
  433. "Declarative base class has both a 'registry' attribute and a "
  434. "type_annotation_map entry. Per-base type_annotation_maps "
  435. "are not supported. Please apply the type_annotation_map "
  436. "to this registry directly."
  437. )
  438. else:
  439. reg = registry(
  440. metadata=metadata, type_annotation_map=type_annotation_map
  441. )
  442. cls.registry = reg
  443. cls._sa_registry = reg
  444. if "metadata" not in cls.__dict__:
  445. cls.metadata = cls.registry.metadata
  446. if getattr(cls, "__init__", object.__init__) is object.__init__:
  447. cls.__init__ = cls.registry.constructor
  448. class MappedAsDataclass(metaclass=DCTransformDeclarative):
  449. """Mixin class to indicate when mapping this class, also convert it to be
  450. a dataclass.
  451. .. seealso::
  452. :ref:`orm_declarative_native_dataclasses` - complete background
  453. on SQLAlchemy native dataclass mapping
  454. .. versionadded:: 2.0
  455. """
  456. def __init_subclass__(
  457. cls,
  458. init: Union[_NoArg, bool] = _NoArg.NO_ARG,
  459. repr: Union[_NoArg, bool] = _NoArg.NO_ARG, # noqa: A002
  460. eq: Union[_NoArg, bool] = _NoArg.NO_ARG,
  461. order: Union[_NoArg, bool] = _NoArg.NO_ARG,
  462. unsafe_hash: Union[_NoArg, bool] = _NoArg.NO_ARG,
  463. match_args: Union[_NoArg, bool] = _NoArg.NO_ARG,
  464. kw_only: Union[_NoArg, bool] = _NoArg.NO_ARG,
  465. dataclass_callable: Union[
  466. _NoArg, Callable[..., Type[Any]]
  467. ] = _NoArg.NO_ARG,
  468. **kw: Any,
  469. ) -> None:
  470. apply_dc_transforms: _DataclassArguments = {
  471. "init": init,
  472. "repr": repr,
  473. "eq": eq,
  474. "order": order,
  475. "unsafe_hash": unsafe_hash,
  476. "match_args": match_args,
  477. "kw_only": kw_only,
  478. "dataclass_callable": dataclass_callable,
  479. }
  480. current_transforms: _DataclassArguments
  481. if hasattr(cls, "_sa_apply_dc_transforms"):
  482. current = cls._sa_apply_dc_transforms
  483. _ClassScanMapperConfig._assert_dc_arguments(current)
  484. cls._sa_apply_dc_transforms = current_transforms = { # type: ignore # noqa: E501
  485. k: current.get(k, _NoArg.NO_ARG) if v is _NoArg.NO_ARG else v
  486. for k, v in apply_dc_transforms.items()
  487. }
  488. else:
  489. cls._sa_apply_dc_transforms = (
  490. current_transforms
  491. ) = apply_dc_transforms
  492. super().__init_subclass__(**kw)
  493. if not _is_mapped_class(cls):
  494. new_anno = (
  495. _ClassScanMapperConfig._update_annotations_for_non_mapped_class
  496. )(cls)
  497. _ClassScanMapperConfig._apply_dataclasses_to_any_class(
  498. current_transforms, cls, new_anno
  499. )
  500. class DeclarativeBase(
  501. # Inspectable is used only by the mypy plugin
  502. inspection.Inspectable[InstanceState[Any]],
  503. metaclass=DeclarativeAttributeIntercept,
  504. ):
  505. """Base class used for declarative class definitions.
  506. The :class:`_orm.DeclarativeBase` allows for the creation of new
  507. declarative bases in such a way that is compatible with type checkers::
  508. from sqlalchemy.orm import DeclarativeBase
  509. class Base(DeclarativeBase):
  510. pass
  511. The above ``Base`` class is now usable as the base for new declarative
  512. mappings. The superclass makes use of the ``__init_subclass__()``
  513. method to set up new classes and metaclasses aren't used.
  514. When first used, the :class:`_orm.DeclarativeBase` class instantiates a new
  515. :class:`_orm.registry` to be used with the base, assuming one was not
  516. provided explicitly. The :class:`_orm.DeclarativeBase` class supports
  517. class-level attributes which act as parameters for the construction of this
  518. registry; such as to indicate a specific :class:`_schema.MetaData`
  519. collection as well as a specific value for
  520. :paramref:`_orm.registry.type_annotation_map`::
  521. from typing_extensions import Annotated
  522. from sqlalchemy import BigInteger
  523. from sqlalchemy import MetaData
  524. from sqlalchemy import String
  525. from sqlalchemy.orm import DeclarativeBase
  526. bigint = Annotated[int, "bigint"]
  527. my_metadata = MetaData()
  528. class Base(DeclarativeBase):
  529. metadata = my_metadata
  530. type_annotation_map = {
  531. str: String().with_variant(String(255), "mysql", "mariadb"),
  532. bigint: BigInteger()
  533. }
  534. Class-level attributes which may be specified include:
  535. :param metadata: optional :class:`_schema.MetaData` collection.
  536. If a :class:`_orm.registry` is constructed automatically, this
  537. :class:`_schema.MetaData` collection will be used to construct it.
  538. Otherwise, the local :class:`_schema.MetaData` collection will supercede
  539. that used by an existing :class:`_orm.registry` passed using the
  540. :paramref:`_orm.DeclarativeBase.registry` parameter.
  541. :param type_annotation_map: optional type annotation map that will be
  542. passed to the :class:`_orm.registry` as
  543. :paramref:`_orm.registry.type_annotation_map`.
  544. :param registry: supply a pre-existing :class:`_orm.registry` directly.
  545. .. versionadded:: 2.0 Added :class:`.DeclarativeBase`, so that declarative
  546. base classes may be constructed in such a way that is also recognized
  547. by :pep:`484` type checkers. As a result, :class:`.DeclarativeBase`
  548. and other subclassing-oriented APIs should be seen as
  549. superseding previous "class returned by a function" APIs, namely
  550. :func:`_orm.declarative_base` and :meth:`_orm.registry.generate_base`,
  551. where the base class returned cannot be recognized by type checkers
  552. without using plugins.
  553. **__init__ behavior**
  554. In a plain Python class, the base-most ``__init__()`` method in the class
  555. hierarchy is ``object.__init__()``, which accepts no arguments. However,
  556. when the :class:`_orm.DeclarativeBase` subclass is first declared, the
  557. class is given an ``__init__()`` method that links to the
  558. :paramref:`_orm.registry.constructor` constructor function, if no
  559. ``__init__()`` method is already present; this is the usual declarative
  560. constructor that will assign keyword arguments as attributes on the
  561. instance, assuming those attributes are established at the class level
  562. (i.e. are mapped, or are linked to a descriptor). This constructor is
  563. **never accessed by a mapped class without being called explicitly via
  564. super()**, as mapped classes are themselves given an ``__init__()`` method
  565. directly which calls :paramref:`_orm.registry.constructor`, so in the
  566. default case works independently of what the base-most ``__init__()``
  567. method does.
  568. .. versionchanged:: 2.0.1 :class:`_orm.DeclarativeBase` has a default
  569. constructor that links to :paramref:`_orm.registry.constructor` by
  570. default, so that calls to ``super().__init__()`` can access this
  571. constructor. Previously, due to an implementation mistake, this default
  572. constructor was missing, and calling ``super().__init__()`` would invoke
  573. ``object.__init__()``.
  574. The :class:`_orm.DeclarativeBase` subclass may also declare an explicit
  575. ``__init__()`` method which will replace the use of the
  576. :paramref:`_orm.registry.constructor` function at this level::
  577. class Base(DeclarativeBase):
  578. def __init__(self, id=None):
  579. self.id = id
  580. Mapped classes still will not invoke this constructor implicitly; it
  581. remains only accessible by calling ``super().__init__()``::
  582. class MyClass(Base):
  583. def __init__(self, id=None, name=None):
  584. self.name = name
  585. super().__init__(id=id)
  586. Note that this is a different behavior from what functions like the legacy
  587. :func:`_orm.declarative_base` would do; the base created by those functions
  588. would always install :paramref:`_orm.registry.constructor` for
  589. ``__init__()``.
  590. """
  591. if typing.TYPE_CHECKING:
  592. def _sa_inspect_type(self) -> Mapper[Self]:
  593. ...
  594. def _sa_inspect_instance(self) -> InstanceState[Self]:
  595. ...
  596. _sa_registry: ClassVar[_RegistryType]
  597. registry: ClassVar[_RegistryType]
  598. """Refers to the :class:`_orm.registry` in use where new
  599. :class:`_orm.Mapper` objects will be associated."""
  600. metadata: ClassVar[MetaData]
  601. """Refers to the :class:`_schema.MetaData` collection that will be used
  602. for new :class:`_schema.Table` objects.
  603. .. seealso::
  604. :ref:`orm_declarative_metadata`
  605. """
  606. __name__: ClassVar[str]
  607. # this ideally should be Mapper[Self], but mypy as of 1.4.1 does not
  608. # like it, and breaks the declared_attr_one test. Pyright/pylance is
  609. # ok with it.
  610. __mapper__: ClassVar[Mapper[Any]]
  611. """The :class:`_orm.Mapper` object to which a particular class is
  612. mapped.
  613. May also be acquired using :func:`_sa.inspect`, e.g.
  614. ``inspect(klass)``.
  615. """
  616. __table__: ClassVar[FromClause]
  617. """The :class:`_sql.FromClause` to which a particular subclass is
  618. mapped.
  619. This is usually an instance of :class:`_schema.Table` but may also
  620. refer to other kinds of :class:`_sql.FromClause` such as
  621. :class:`_sql.Subquery`, depending on how the class is mapped.
  622. .. seealso::
  623. :ref:`orm_declarative_metadata`
  624. """
  625. # pyright/pylance do not consider a classmethod a ClassVar so use Any
  626. # https://github.com/microsoft/pylance-release/issues/3484
  627. __tablename__: Any
  628. """String name to assign to the generated
  629. :class:`_schema.Table` object, if not specified directly via
  630. :attr:`_orm.DeclarativeBase.__table__`.
  631. .. seealso::
  632. :ref:`orm_declarative_table`
  633. """
  634. __mapper_args__: Any
  635. """Dictionary of arguments which will be passed to the
  636. :class:`_orm.Mapper` constructor.
  637. .. seealso::
  638. :ref:`orm_declarative_mapper_options`
  639. """
  640. __table_args__: Any
  641. """A dictionary or tuple of arguments that will be passed to the
  642. :class:`_schema.Table` constructor. See
  643. :ref:`orm_declarative_table_configuration`
  644. for background on the specific structure of this collection.
  645. .. seealso::
  646. :ref:`orm_declarative_table_configuration`
  647. """
  648. def __init__(self, **kw: Any):
  649. ...
  650. def __init_subclass__(cls, **kw: Any) -> None:
  651. if DeclarativeBase in cls.__bases__:
  652. _check_not_declarative(cls, DeclarativeBase)
  653. _setup_declarative_base(cls)
  654. else:
  655. _as_declarative(cls._sa_registry, cls, cls.__dict__)
  656. super().__init_subclass__(**kw)
  657. def _check_not_declarative(cls: Type[Any], base: Type[Any]) -> None:
  658. cls_dict = cls.__dict__
  659. if (
  660. "__table__" in cls_dict
  661. and not (
  662. callable(cls_dict["__table__"])
  663. or hasattr(cls_dict["__table__"], "__get__")
  664. )
  665. ) or isinstance(cls_dict.get("__tablename__", None), str):
  666. raise exc.InvalidRequestError(
  667. f"Cannot use {base.__name__!r} directly as a declarative base "
  668. "class. Create a Base by creating a subclass of it."
  669. )
  670. class DeclarativeBaseNoMeta(
  671. # Inspectable is used only by the mypy plugin
  672. inspection.Inspectable[InstanceState[Any]]
  673. ):
  674. """Same as :class:`_orm.DeclarativeBase`, but does not use a metaclass
  675. to intercept new attributes.
  676. The :class:`_orm.DeclarativeBaseNoMeta` base may be used when use of
  677. custom metaclasses is desirable.
  678. .. versionadded:: 2.0
  679. """
  680. _sa_registry: ClassVar[_RegistryType]
  681. registry: ClassVar[_RegistryType]
  682. """Refers to the :class:`_orm.registry` in use where new
  683. :class:`_orm.Mapper` objects will be associated."""
  684. metadata: ClassVar[MetaData]
  685. """Refers to the :class:`_schema.MetaData` collection that will be used
  686. for new :class:`_schema.Table` objects.
  687. .. seealso::
  688. :ref:`orm_declarative_metadata`
  689. """
  690. # this ideally should be Mapper[Self], but mypy as of 1.4.1 does not
  691. # like it, and breaks the declared_attr_one test. Pyright/pylance is
  692. # ok with it.
  693. __mapper__: ClassVar[Mapper[Any]]
  694. """The :class:`_orm.Mapper` object to which a particular class is
  695. mapped.
  696. May also be acquired using :func:`_sa.inspect`, e.g.
  697. ``inspect(klass)``.
  698. """
  699. __table__: Optional[FromClause]
  700. """The :class:`_sql.FromClause` to which a particular subclass is
  701. mapped.
  702. This is usually an instance of :class:`_schema.Table` but may also
  703. refer to other kinds of :class:`_sql.FromClause` such as
  704. :class:`_sql.Subquery`, depending on how the class is mapped.
  705. .. seealso::
  706. :ref:`orm_declarative_metadata`
  707. """
  708. if typing.TYPE_CHECKING:
  709. def _sa_inspect_type(self) -> Mapper[Self]:
  710. ...
  711. def _sa_inspect_instance(self) -> InstanceState[Self]:
  712. ...
  713. __tablename__: Any
  714. """String name to assign to the generated
  715. :class:`_schema.Table` object, if not specified directly via
  716. :attr:`_orm.DeclarativeBase.__table__`.
  717. .. seealso::
  718. :ref:`orm_declarative_table`
  719. """
  720. __mapper_args__: Any
  721. """Dictionary of arguments which will be passed to the
  722. :class:`_orm.Mapper` constructor.
  723. .. seealso::
  724. :ref:`orm_declarative_mapper_options`
  725. """
  726. __table_args__: Any
  727. """A dictionary or tuple of arguments that will be passed to the
  728. :class:`_schema.Table` constructor. See
  729. :ref:`orm_declarative_table_configuration`
  730. for background on the specific structure of this collection.
  731. .. seealso::
  732. :ref:`orm_declarative_table_configuration`
  733. """
  734. def __init__(self, **kw: Any):
  735. ...
  736. def __init_subclass__(cls, **kw: Any) -> None:
  737. if DeclarativeBaseNoMeta in cls.__bases__:
  738. _check_not_declarative(cls, DeclarativeBaseNoMeta)
  739. _setup_declarative_base(cls)
  740. else:
  741. _as_declarative(cls._sa_registry, cls, cls.__dict__)
  742. super().__init_subclass__(**kw)
  743. def add_mapped_attribute(
  744. target: Type[_O], key: str, attr: MapperProperty[Any]
  745. ) -> None:
  746. """Add a new mapped attribute to an ORM mapped class.
  747. E.g.::
  748. add_mapped_attribute(User, "addresses", relationship(Address))
  749. This may be used for ORM mappings that aren't using a declarative
  750. metaclass that intercepts attribute set operations.
  751. .. versionadded:: 2.0
  752. """
  753. _add_attribute(target, key, attr)
  754. def declarative_base(
  755. *,
  756. metadata: Optional[MetaData] = None,
  757. mapper: Optional[Callable[..., Mapper[Any]]] = None,
  758. cls: Type[Any] = object,
  759. name: str = "Base",
  760. class_registry: Optional[clsregistry._ClsRegistryType] = None,
  761. type_annotation_map: Optional[_TypeAnnotationMapType] = None,
  762. constructor: Callable[..., None] = _declarative_constructor,
  763. metaclass: Type[Any] = DeclarativeMeta,
  764. ) -> Any:
  765. r"""Construct a base class for declarative class definitions.
  766. The new base class will be given a metaclass that produces
  767. appropriate :class:`~sqlalchemy.schema.Table` objects and makes
  768. the appropriate :class:`_orm.Mapper` calls based on the
  769. information provided declaratively in the class and any subclasses
  770. of the class.
  771. .. versionchanged:: 2.0 Note that the :func:`_orm.declarative_base`
  772. function is superseded by the new :class:`_orm.DeclarativeBase` class,
  773. which generates a new "base" class using subclassing, rather than
  774. return value of a function. This allows an approach that is compatible
  775. with :pep:`484` typing tools.
  776. The :func:`_orm.declarative_base` function is a shorthand version
  777. of using the :meth:`_orm.registry.generate_base`
  778. method. That is, the following::
  779. from sqlalchemy.orm import declarative_base
  780. Base = declarative_base()
  781. Is equivalent to::
  782. from sqlalchemy.orm import registry
  783. mapper_registry = registry()
  784. Base = mapper_registry.generate_base()
  785. See the docstring for :class:`_orm.registry`
  786. and :meth:`_orm.registry.generate_base`
  787. for more details.
  788. .. versionchanged:: 1.4 The :func:`_orm.declarative_base`
  789. function is now a specialization of the more generic
  790. :class:`_orm.registry` class. The function also moves to the
  791. ``sqlalchemy.orm`` package from the ``declarative.ext`` package.
  792. :param metadata:
  793. An optional :class:`~sqlalchemy.schema.MetaData` instance. All
  794. :class:`~sqlalchemy.schema.Table` objects implicitly declared by
  795. subclasses of the base will share this MetaData. A MetaData instance
  796. will be created if none is provided. The
  797. :class:`~sqlalchemy.schema.MetaData` instance will be available via the
  798. ``metadata`` attribute of the generated declarative base class.
  799. :param mapper:
  800. An optional callable, defaults to :class:`_orm.Mapper`. Will
  801. be used to map subclasses to their Tables.
  802. :param cls:
  803. Defaults to :class:`object`. A type to use as the base for the generated
  804. declarative base class. May be a class or tuple of classes.
  805. :param name:
  806. Defaults to ``Base``. The display name for the generated
  807. class. Customizing this is not required, but can improve clarity in
  808. tracebacks and debugging.
  809. :param constructor:
  810. Specify the implementation for the ``__init__`` function on a mapped
  811. class that has no ``__init__`` of its own. Defaults to an
  812. implementation that assigns \**kwargs for declared
  813. fields and relationships to an instance. If ``None`` is supplied,
  814. no __init__ will be provided and construction will fall back to
  815. cls.__init__ by way of the normal Python semantics.
  816. :param class_registry: optional dictionary that will serve as the
  817. registry of class names-> mapped classes when string names
  818. are used to identify classes inside of :func:`_orm.relationship`
  819. and others. Allows two or more declarative base classes
  820. to share the same registry of class names for simplified
  821. inter-base relationships.
  822. :param type_annotation_map: optional dictionary of Python types to
  823. SQLAlchemy :class:`_types.TypeEngine` classes or instances. This
  824. is used exclusively by the :class:`_orm.MappedColumn` construct
  825. to produce column types based on annotations within the
  826. :class:`_orm.Mapped` type.
  827. .. versionadded:: 2.0
  828. .. seealso::
  829. :ref:`orm_declarative_mapped_column_type_map`
  830. :param metaclass:
  831. Defaults to :class:`.DeclarativeMeta`. A metaclass or __metaclass__
  832. compatible callable to use as the meta type of the generated
  833. declarative base class.
  834. .. seealso::
  835. :class:`_orm.registry`
  836. """
  837. return registry(
  838. metadata=metadata,
  839. class_registry=class_registry,
  840. constructor=constructor,
  841. type_annotation_map=type_annotation_map,
  842. ).generate_base(
  843. mapper=mapper,
  844. cls=cls,
  845. name=name,
  846. metaclass=metaclass,
  847. )
  848. class registry:
  849. """Generalized registry for mapping classes.
  850. The :class:`_orm.registry` serves as the basis for maintaining a collection
  851. of mappings, and provides configurational hooks used to map classes.
  852. The three general kinds of mappings supported are Declarative Base,
  853. Declarative Decorator, and Imperative Mapping. All of these mapping
  854. styles may be used interchangeably:
  855. * :meth:`_orm.registry.generate_base` returns a new declarative base
  856. class, and is the underlying implementation of the
  857. :func:`_orm.declarative_base` function.
  858. * :meth:`_orm.registry.mapped` provides a class decorator that will
  859. apply declarative mapping to a class without the use of a declarative
  860. base class.
  861. * :meth:`_orm.registry.map_imperatively` will produce a
  862. :class:`_orm.Mapper` for a class without scanning the class for
  863. declarative class attributes. This method suits the use case historically
  864. provided by the ``sqlalchemy.orm.mapper()`` classical mapping function,
  865. which is removed as of SQLAlchemy 2.0.
  866. .. versionadded:: 1.4
  867. .. seealso::
  868. :ref:`orm_mapping_classes_toplevel` - overview of class mapping
  869. styles.
  870. """
  871. _class_registry: clsregistry._ClsRegistryType
  872. _managers: weakref.WeakKeyDictionary[ClassManager[Any], Literal[True]]
  873. _non_primary_mappers: weakref.WeakKeyDictionary[Mapper[Any], Literal[True]]
  874. metadata: MetaData
  875. constructor: CallableReference[Callable[..., None]]
  876. type_annotation_map: _MutableTypeAnnotationMapType
  877. _dependents: Set[_RegistryType]
  878. _dependencies: Set[_RegistryType]
  879. _new_mappers: bool
  880. def __init__(
  881. self,
  882. *,
  883. metadata: Optional[MetaData] = None,
  884. class_registry: Optional[clsregistry._ClsRegistryType] = None,
  885. type_annotation_map: Optional[_TypeAnnotationMapType] = None,
  886. constructor: Callable[..., None] = _declarative_constructor,
  887. ):
  888. r"""Construct a new :class:`_orm.registry`
  889. :param metadata:
  890. An optional :class:`_schema.MetaData` instance. All
  891. :class:`_schema.Table` objects generated using declarative
  892. table mapping will make use of this :class:`_schema.MetaData`
  893. collection. If this argument is left at its default of ``None``,
  894. a blank :class:`_schema.MetaData` collection is created.
  895. :param constructor:
  896. Specify the implementation for the ``__init__`` function on a mapped
  897. class that has no ``__init__`` of its own. Defaults to an
  898. implementation that assigns \**kwargs for declared
  899. fields and relationships to an instance. If ``None`` is supplied,
  900. no __init__ will be provided and construction will fall back to
  901. cls.__init__ by way of the normal Python semantics.
  902. :param class_registry: optional dictionary that will serve as the
  903. registry of class names-> mapped classes when string names
  904. are used to identify classes inside of :func:`_orm.relationship`
  905. and others. Allows two or more declarative base classes
  906. to share the same registry of class names for simplified
  907. inter-base relationships.
  908. :param type_annotation_map: optional dictionary of Python types to
  909. SQLAlchemy :class:`_types.TypeEngine` classes or instances.
  910. The provided dict will update the default type mapping. This
  911. is used exclusively by the :class:`_orm.MappedColumn` construct
  912. to produce column types based on annotations within the
  913. :class:`_orm.Mapped` type.
  914. .. versionadded:: 2.0
  915. .. seealso::
  916. :ref:`orm_declarative_mapped_column_type_map`
  917. """
  918. lcl_metadata = metadata or MetaData()
  919. if class_registry is None:
  920. class_registry = weakref.WeakValueDictionary()
  921. self._class_registry = class_registry
  922. self._managers = weakref.WeakKeyDictionary()
  923. self._non_primary_mappers = weakref.WeakKeyDictionary()
  924. self.metadata = lcl_metadata
  925. self.constructor = constructor
  926. self.type_annotation_map = {}
  927. if type_annotation_map is not None:
  928. self.update_type_annotation_map(type_annotation_map)
  929. self._dependents = set()
  930. self._dependencies = set()
  931. self._new_mappers = False
  932. with mapperlib._CONFIGURE_MUTEX:
  933. mapperlib._mapper_registries[self] = True
  934. def update_type_annotation_map(
  935. self,
  936. type_annotation_map: _TypeAnnotationMapType,
  937. ) -> None:
  938. """update the :paramref:`_orm.registry.type_annotation_map` with new
  939. values."""
  940. self.type_annotation_map.update(
  941. {
  942. sub_type: sqltype
  943. for typ, sqltype in type_annotation_map.items()
  944. for sub_type in compat_typing.expand_unions(
  945. typ, include_union=True, discard_none=True
  946. )
  947. }
  948. )
  949. def _resolve_type(
  950. self, python_type: _MatchedOnType
  951. ) -> Optional[sqltypes.TypeEngine[Any]]:
  952. search: Iterable[Tuple[_MatchedOnType, Type[Any]]]
  953. python_type_type: Type[Any]
  954. if is_generic(python_type):
  955. if is_literal(python_type):
  956. python_type_type = cast("Type[Any]", python_type)
  957. search = ( # type: ignore[assignment]
  958. (python_type, python_type_type),
  959. (Literal, python_type_type),
  960. )
  961. else:
  962. python_type_type = python_type.__origin__
  963. search = ((python_type, python_type_type),)
  964. elif is_newtype(python_type):
  965. python_type_type = flatten_newtype(python_type)
  966. search = ((python_type, python_type_type),)
  967. elif is_pep695(python_type):
  968. python_type_type = python_type.__value__
  969. flattened = None
  970. search = ((python_type, python_type_type),)
  971. else:
  972. python_type_type = cast("Type[Any]", python_type)
  973. flattened = None
  974. search = ((pt, pt) for pt in python_type_type.__mro__)
  975. for pt, flattened in search:
  976. # we search through full __mro__ for types. however...
  977. sql_type = self.type_annotation_map.get(pt)
  978. if sql_type is None:
  979. sql_type = sqltypes._type_map_get(pt) # type: ignore # noqa: E501
  980. if sql_type is not None:
  981. sql_type_inst = sqltypes.to_instance(sql_type)
  982. # ... this additional step will reject most
  983. # type -> supertype matches, such as if we had
  984. # a MyInt(int) subclass. note also we pass NewType()
  985. # here directly; these always have to be in the
  986. # type_annotation_map to be useful
  987. resolved_sql_type = sql_type_inst._resolve_for_python_type(
  988. python_type_type,
  989. pt,
  990. flattened,
  991. )
  992. if resolved_sql_type is not None:
  993. return resolved_sql_type
  994. return None
  995. @property
  996. def mappers(self) -> FrozenSet[Mapper[Any]]:
  997. """read only collection of all :class:`_orm.Mapper` objects."""
  998. return frozenset(manager.mapper for manager in self._managers).union(
  999. self._non_primary_mappers
  1000. )
  1001. def _set_depends_on(self, registry: RegistryType) -> None:
  1002. if registry is self:
  1003. return
  1004. registry._dependents.add(self)
  1005. self._dependencies.add(registry)
  1006. def _flag_new_mapper(self, mapper: Mapper[Any]) -> None:
  1007. mapper._ready_for_configure = True
  1008. if self._new_mappers:
  1009. return
  1010. for reg in self._recurse_with_dependents({self}):
  1011. reg._new_mappers = True
  1012. @classmethod
  1013. def _recurse_with_dependents(
  1014. cls, registries: Set[RegistryType]
  1015. ) -> Iterator[RegistryType]:
  1016. todo = registries
  1017. done = set()
  1018. while todo:
  1019. reg = todo.pop()
  1020. done.add(reg)
  1021. # if yielding would remove dependents, make sure we have
  1022. # them before
  1023. todo.update(reg._dependents.difference(done))
  1024. yield reg
  1025. # if yielding would add dependents, make sure we have them
  1026. # after
  1027. todo.update(reg._dependents.difference(done))
  1028. @classmethod
  1029. def _recurse_with_dependencies(
  1030. cls, registries: Set[RegistryType]
  1031. ) -> Iterator[RegistryType]:
  1032. todo = registries
  1033. done = set()
  1034. while todo:
  1035. reg = todo.pop()
  1036. done.add(reg)
  1037. # if yielding would remove dependencies, make sure we have
  1038. # them before
  1039. todo.update(reg._dependencies.difference(done))
  1040. yield reg
  1041. # if yielding would remove dependencies, make sure we have
  1042. # them before
  1043. todo.update(reg._dependencies.difference(done))
  1044. def _mappers_to_configure(self) -> Iterator[Mapper[Any]]:
  1045. return itertools.chain(
  1046. (
  1047. manager.mapper
  1048. for manager in list(self._managers)
  1049. if manager.is_mapped
  1050. and not manager.mapper.configured
  1051. and manager.mapper._ready_for_configure
  1052. ),
  1053. (
  1054. npm
  1055. for npm in list(self._non_primary_mappers)
  1056. if not npm.configured and npm._ready_for_configure
  1057. ),
  1058. )
  1059. def _add_non_primary_mapper(self, np_mapper: Mapper[Any]) -> None:
  1060. self._non_primary_mappers[np_mapper] = True
  1061. def _dispose_cls(self, cls: Type[_O]) -> None:
  1062. clsregistry.remove_class(cls.__name__, cls, self._class_registry)
  1063. def _add_manager(self, manager: ClassManager[Any]) -> None:
  1064. self._managers[manager] = True
  1065. if manager.is_mapped:
  1066. raise exc.ArgumentError(
  1067. "Class '%s' already has a primary mapper defined. "
  1068. % manager.class_
  1069. )
  1070. assert manager.registry is None
  1071. manager.registry = self
  1072. def configure(self, cascade: bool = False) -> None:
  1073. """Configure all as-yet unconfigured mappers in this
  1074. :class:`_orm.registry`.
  1075. The configure step is used to reconcile and initialize the
  1076. :func:`_orm.relationship` linkages between mapped classes, as well as
  1077. to invoke configuration events such as the
  1078. :meth:`_orm.MapperEvents.before_configured` and
  1079. :meth:`_orm.MapperEvents.after_configured`, which may be used by ORM
  1080. extensions or user-defined extension hooks.
  1081. If one or more mappers in this registry contain
  1082. :func:`_orm.relationship` constructs that refer to mapped classes in
  1083. other registries, this registry is said to be *dependent* on those
  1084. registries. In order to configure those dependent registries
  1085. automatically, the :paramref:`_orm.registry.configure.cascade` flag
  1086. should be set to ``True``. Otherwise, if they are not configured, an
  1087. exception will be raised. The rationale behind this behavior is to
  1088. allow an application to programmatically invoke configuration of
  1089. registries while controlling whether or not the process implicitly
  1090. reaches other registries.
  1091. As an alternative to invoking :meth:`_orm.registry.configure`, the ORM
  1092. function :func:`_orm.configure_mappers` function may be used to ensure
  1093. configuration is complete for all :class:`_orm.registry` objects in
  1094. memory. This is generally simpler to use and also predates the usage of
  1095. :class:`_orm.registry` objects overall. However, this function will
  1096. impact all mappings throughout the running Python process and may be
  1097. more memory/time consuming for an application that has many registries
  1098. in use for different purposes that may not be needed immediately.
  1099. .. seealso::
  1100. :func:`_orm.configure_mappers`
  1101. .. versionadded:: 1.4.0b2
  1102. """
  1103. mapperlib._configure_registries({self}, cascade=cascade)
  1104. def dispose(self, cascade: bool = False) -> None:
  1105. """Dispose of all mappers in this :class:`_orm.registry`.
  1106. After invocation, all the classes that were mapped within this registry
  1107. will no longer have class instrumentation associated with them. This
  1108. method is the per-:class:`_orm.registry` analogue to the
  1109. application-wide :func:`_orm.clear_mappers` function.
  1110. If this registry contains mappers that are dependencies of other
  1111. registries, typically via :func:`_orm.relationship` links, then those
  1112. registries must be disposed as well. When such registries exist in
  1113. relation to this one, their :meth:`_orm.registry.dispose` method will
  1114. also be called, if the :paramref:`_orm.registry.dispose.cascade` flag
  1115. is set to ``True``; otherwise, an error is raised if those registries
  1116. were not already disposed.
  1117. .. versionadded:: 1.4.0b2
  1118. .. seealso::
  1119. :func:`_orm.clear_mappers`
  1120. """
  1121. mapperlib._dispose_registries({self}, cascade=cascade)
  1122. def _dispose_manager_and_mapper(self, manager: ClassManager[Any]) -> None:
  1123. if "mapper" in manager.__dict__:
  1124. mapper = manager.mapper
  1125. mapper._set_dispose_flags()
  1126. class_ = manager.class_
  1127. self._dispose_cls(class_)
  1128. instrumentation._instrumentation_factory.unregister(class_)
  1129. def generate_base(
  1130. self,
  1131. mapper: Optional[Callable[..., Mapper[Any]]] = None,
  1132. cls: Type[Any] = object,
  1133. name: str = "Base",
  1134. metaclass: Type[Any] = DeclarativeMeta,
  1135. ) -> Any:
  1136. """Generate a declarative base class.
  1137. Classes that inherit from the returned class object will be
  1138. automatically mapped using declarative mapping.
  1139. E.g.::
  1140. from sqlalchemy.orm import registry
  1141. mapper_registry = registry()
  1142. Base = mapper_registry.generate_base()
  1143. class MyClass(Base):
  1144. __tablename__ = "my_table"
  1145. id = Column(Integer, primary_key=True)
  1146. The above dynamically generated class is equivalent to the
  1147. non-dynamic example below::
  1148. from sqlalchemy.orm import registry
  1149. from sqlalchemy.orm.decl_api import DeclarativeMeta
  1150. mapper_registry = registry()
  1151. class Base(metaclass=DeclarativeMeta):
  1152. __abstract__ = True
  1153. registry = mapper_registry
  1154. metadata = mapper_registry.metadata
  1155. __init__ = mapper_registry.constructor
  1156. .. versionchanged:: 2.0 Note that the
  1157. :meth:`_orm.registry.generate_base` method is superseded by the new
  1158. :class:`_orm.DeclarativeBase` class, which generates a new "base"
  1159. class using subclassing, rather than return value of a function.
  1160. This allows an approach that is compatible with :pep:`484` typing
  1161. tools.
  1162. The :meth:`_orm.registry.generate_base` method provides the
  1163. implementation for the :func:`_orm.declarative_base` function, which
  1164. creates the :class:`_orm.registry` and base class all at once.
  1165. See the section :ref:`orm_declarative_mapping` for background and
  1166. examples.
  1167. :param mapper:
  1168. An optional callable, defaults to :class:`_orm.Mapper`.
  1169. This function is used to generate new :class:`_orm.Mapper` objects.
  1170. :param cls:
  1171. Defaults to :class:`object`. A type to use as the base for the
  1172. generated declarative base class. May be a class or tuple of classes.
  1173. :param name:
  1174. Defaults to ``Base``. The display name for the generated
  1175. class. Customizing this is not required, but can improve clarity in
  1176. tracebacks and debugging.
  1177. :param metaclass:
  1178. Defaults to :class:`.DeclarativeMeta`. A metaclass or __metaclass__
  1179. compatible callable to use as the meta type of the generated
  1180. declarative base class.
  1181. .. seealso::
  1182. :ref:`orm_declarative_mapping`
  1183. :func:`_orm.declarative_base`
  1184. """
  1185. metadata = self.metadata
  1186. bases = not isinstance(cls, tuple) and (cls,) or cls
  1187. class_dict: Dict[str, Any] = dict(registry=self, metadata=metadata)
  1188. if isinstance(cls, type):
  1189. class_dict["__doc__"] = cls.__doc__
  1190. if self.constructor is not None:
  1191. class_dict["__init__"] = self.constructor
  1192. class_dict["__abstract__"] = True
  1193. if mapper:
  1194. class_dict["__mapper_cls__"] = mapper
  1195. if hasattr(cls, "__class_getitem__"):
  1196. def __class_getitem__(cls: Type[_T], key: Any) -> Type[_T]:
  1197. # allow generic classes in py3.9+
  1198. return cls
  1199. class_dict["__class_getitem__"] = __class_getitem__
  1200. return metaclass(name, bases, class_dict)
  1201. @compat_typing.dataclass_transform(
  1202. field_specifiers=(
  1203. MappedColumn,
  1204. RelationshipProperty,
  1205. Composite,
  1206. Synonym,
  1207. mapped_column,
  1208. relationship,
  1209. composite,
  1210. synonym,
  1211. deferred,
  1212. ),
  1213. )
  1214. @overload
  1215. def mapped_as_dataclass(self, __cls: Type[_O]) -> Type[_O]:
  1216. ...
  1217. @overload
  1218. def mapped_as_dataclass(
  1219. self,
  1220. __cls: Literal[None] = ...,
  1221. *,
  1222. init: Union[_NoArg, bool] = ...,
  1223. repr: Union[_NoArg, bool] = ..., # noqa: A002
  1224. eq: Union[_NoArg, bool] = ...,
  1225. order: Union[_NoArg, bool] = ...,
  1226. unsafe_hash: Union[_NoArg, bool] = ...,
  1227. match_args: Union[_NoArg, bool] = ...,
  1228. kw_only: Union[_NoArg, bool] = ...,
  1229. dataclass_callable: Union[_NoArg, Callable[..., Type[Any]]] = ...,
  1230. ) -> Callable[[Type[_O]], Type[_O]]:
  1231. ...
  1232. def mapped_as_dataclass(
  1233. self,
  1234. __cls: Optional[Type[_O]] = None,
  1235. *,
  1236. init: Union[_NoArg, bool] = _NoArg.NO_ARG,
  1237. repr: Union[_NoArg, bool] = _NoArg.NO_ARG, # noqa: A002
  1238. eq: Union[_NoArg, bool] = _NoArg.NO_ARG,
  1239. order: Union[_NoArg, bool] = _NoArg.NO_ARG,
  1240. unsafe_hash: Union[_NoArg, bool] = _NoArg.NO_ARG,
  1241. match_args: Union[_NoArg, bool] = _NoArg.NO_ARG,
  1242. kw_only: Union[_NoArg, bool] = _NoArg.NO_ARG,
  1243. dataclass_callable: Union[
  1244. _NoArg, Callable[..., Type[Any]]
  1245. ] = _NoArg.NO_ARG,
  1246. ) -> Union[Type[_O], Callable[[Type[_O]], Type[_O]]]:
  1247. """Class decorator that will apply the Declarative mapping process
  1248. to a given class, and additionally convert the class to be a
  1249. Python dataclass.
  1250. .. seealso::
  1251. :ref:`orm_declarative_native_dataclasses` - complete background
  1252. on SQLAlchemy native dataclass mapping
  1253. .. versionadded:: 2.0
  1254. """
  1255. def decorate(cls: Type[_O]) -> Type[_O]:
  1256. setattr(
  1257. cls,
  1258. "_sa_apply_dc_transforms",
  1259. {
  1260. "init": init,
  1261. "repr": repr,
  1262. "eq": eq,
  1263. "order": order,
  1264. "unsafe_hash": unsafe_hash,
  1265. "match_args": match_args,
  1266. "kw_only": kw_only,
  1267. "dataclass_callable": dataclass_callable,
  1268. },
  1269. )
  1270. _as_declarative(self, cls, cls.__dict__)
  1271. return cls
  1272. if __cls:
  1273. return decorate(__cls)
  1274. else:
  1275. return decorate
  1276. def mapped(self, cls: Type[_O]) -> Type[_O]:
  1277. """Class decorator that will apply the Declarative mapping process
  1278. to a given class.
  1279. E.g.::
  1280. from sqlalchemy.orm import registry
  1281. mapper_registry = registry()
  1282. @mapper_registry.mapped
  1283. class Foo:
  1284. __tablename__ = 'some_table'
  1285. id = Column(Integer, primary_key=True)
  1286. name = Column(String)
  1287. See the section :ref:`orm_declarative_mapping` for complete
  1288. details and examples.
  1289. :param cls: class to be mapped.
  1290. :return: the class that was passed.
  1291. .. seealso::
  1292. :ref:`orm_declarative_mapping`
  1293. :meth:`_orm.registry.generate_base` - generates a base class
  1294. that will apply Declarative mapping to subclasses automatically
  1295. using a Python metaclass.
  1296. .. seealso::
  1297. :meth:`_orm.registry.mapped_as_dataclass`
  1298. """
  1299. _as_declarative(self, cls, cls.__dict__)
  1300. return cls
  1301. def as_declarative_base(self, **kw: Any) -> Callable[[Type[_T]], Type[_T]]:
  1302. """
  1303. Class decorator which will invoke
  1304. :meth:`_orm.registry.generate_base`
  1305. for a given base class.
  1306. E.g.::
  1307. from sqlalchemy.orm import registry
  1308. mapper_registry = registry()
  1309. @mapper_registry.as_declarative_base()
  1310. class Base:
  1311. @declared_attr
  1312. def __tablename__(cls):
  1313. return cls.__name__.lower()
  1314. id = Column(Integer, primary_key=True)
  1315. class MyMappedClass(Base):
  1316. # ...
  1317. All keyword arguments passed to
  1318. :meth:`_orm.registry.as_declarative_base` are passed
  1319. along to :meth:`_orm.registry.generate_base`.
  1320. """
  1321. def decorate(cls: Type[_T]) -> Type[_T]:
  1322. kw["cls"] = cls
  1323. kw["name"] = cls.__name__
  1324. return self.generate_base(**kw) # type: ignore
  1325. return decorate
  1326. def map_declaratively(self, cls: Type[_O]) -> Mapper[_O]:
  1327. """Map a class declaratively.
  1328. In this form of mapping, the class is scanned for mapping information,
  1329. including for columns to be associated with a table, and/or an
  1330. actual table object.
  1331. Returns the :class:`_orm.Mapper` object.
  1332. E.g.::
  1333. from sqlalchemy.orm import registry
  1334. mapper_registry = registry()
  1335. class Foo:
  1336. __tablename__ = 'some_table'
  1337. id = Column(Integer, primary_key=True)
  1338. name = Column(String)
  1339. mapper = mapper_registry.map_declaratively(Foo)
  1340. This function is more conveniently invoked indirectly via either the
  1341. :meth:`_orm.registry.mapped` class decorator or by subclassing a
  1342. declarative metaclass generated from
  1343. :meth:`_orm.registry.generate_base`.
  1344. See the section :ref:`orm_declarative_mapping` for complete
  1345. details and examples.
  1346. :param cls: class to be mapped.
  1347. :return: a :class:`_orm.Mapper` object.
  1348. .. seealso::
  1349. :ref:`orm_declarative_mapping`
  1350. :meth:`_orm.registry.mapped` - more common decorator interface
  1351. to this function.
  1352. :meth:`_orm.registry.map_imperatively`
  1353. """
  1354. _as_declarative(self, cls, cls.__dict__)
  1355. return cls.__mapper__ # type: ignore
  1356. def map_imperatively(
  1357. self,
  1358. class_: Type[_O],
  1359. local_table: Optional[FromClause] = None,
  1360. **kw: Any,
  1361. ) -> Mapper[_O]:
  1362. r"""Map a class imperatively.
  1363. In this form of mapping, the class is not scanned for any mapping
  1364. information. Instead, all mapping constructs are passed as
  1365. arguments.
  1366. This method is intended to be fully equivalent to the now-removed
  1367. SQLAlchemy ``mapper()`` function, except that it's in terms of
  1368. a particular registry.
  1369. E.g.::
  1370. from sqlalchemy.orm import registry
  1371. mapper_registry = registry()
  1372. my_table = Table(
  1373. "my_table",
  1374. mapper_registry.metadata,
  1375. Column('id', Integer, primary_key=True)
  1376. )
  1377. class MyClass:
  1378. pass
  1379. mapper_registry.map_imperatively(MyClass, my_table)
  1380. See the section :ref:`orm_imperative_mapping` for complete background
  1381. and usage examples.
  1382. :param class\_: The class to be mapped. Corresponds to the
  1383. :paramref:`_orm.Mapper.class_` parameter.
  1384. :param local_table: the :class:`_schema.Table` or other
  1385. :class:`_sql.FromClause` object that is the subject of the mapping.
  1386. Corresponds to the
  1387. :paramref:`_orm.Mapper.local_table` parameter.
  1388. :param \**kw: all other keyword arguments are passed to the
  1389. :class:`_orm.Mapper` constructor directly.
  1390. .. seealso::
  1391. :ref:`orm_imperative_mapping`
  1392. :ref:`orm_declarative_mapping`
  1393. """
  1394. return _mapper(self, class_, local_table, kw)
  1395. RegistryType = registry
  1396. if not TYPE_CHECKING:
  1397. # allow for runtime type resolution of ``ClassVar[_RegistryType]``
  1398. _RegistryType = registry # noqa
  1399. def as_declarative(**kw: Any) -> Callable[[Type[_T]], Type[_T]]:
  1400. """
  1401. Class decorator which will adapt a given class into a
  1402. :func:`_orm.declarative_base`.
  1403. This function makes use of the :meth:`_orm.registry.as_declarative_base`
  1404. method, by first creating a :class:`_orm.registry` automatically
  1405. and then invoking the decorator.
  1406. E.g.::
  1407. from sqlalchemy.orm import as_declarative
  1408. @as_declarative()
  1409. class Base:
  1410. @declared_attr
  1411. def __tablename__(cls):
  1412. return cls.__name__.lower()
  1413. id = Column(Integer, primary_key=True)
  1414. class MyMappedClass(Base):
  1415. # ...
  1416. .. seealso::
  1417. :meth:`_orm.registry.as_declarative_base`
  1418. """
  1419. metadata, class_registry = (
  1420. kw.pop("metadata", None),
  1421. kw.pop("class_registry", None),
  1422. )
  1423. return registry(
  1424. metadata=metadata, class_registry=class_registry
  1425. ).as_declarative_base(**kw)
  1426. @inspection._inspects(
  1427. DeclarativeMeta, DeclarativeBase, DeclarativeAttributeIntercept
  1428. )
  1429. def _inspect_decl_meta(cls: Type[Any]) -> Optional[Mapper[Any]]:
  1430. mp: Optional[Mapper[Any]] = _inspect_mapped_class(cls)
  1431. if mp is None:
  1432. if _DeferredMapperConfig.has_cls(cls):
  1433. _DeferredMapperConfig.raise_unmapped_for_cls(cls)
  1434. return mp