codekingpro/portable-devtools
115k
1# orm/_orm_constructors.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
8from __future__ import annotations
9
10import typing
11from typing import Any
12from typing import Callable
13from typing import Collection
14from typing import Iterable
15from typing import Mapping
16from typing import NoReturn
17from typing import Optional
18from typing import overload
19from typing import Type
20from typing import TYPE_CHECKING
21from typing import Union
22
23from . import mapperlib as mapperlib
24from ._typing import _O
25from .descriptor_props import Composite
26from .descriptor_props import Synonym
27from .interfaces import _AttributeOptions
28from .properties import MappedColumn
29from .properties import MappedSQLExpression
30from .query import AliasOption
31from .relationships import _RelationshipArgumentType
32from .relationships import _RelationshipDeclared
33from .relationships import _RelationshipSecondaryArgument
34from .relationships import RelationshipProperty
35from .session import Session
36from .util import _ORMJoin
37from .util import AliasedClass
38from .util import AliasedInsp
39from .util import LoaderCriteriaOption
40from .. import sql
41from .. import util
42from ..exc import InvalidRequestError
43from ..sql._typing import _no_kw
44from ..sql.base import _NoArg
45from ..sql.base import SchemaEventTarget
46from ..sql.schema import _InsertSentinelColumnDefault
47from ..sql.schema import SchemaConst
48from ..sql.selectable import FromClause
49from ..util.typing import Annotated
50from ..util.typing import Literal
51
52if TYPE_CHECKING:
53 from ._typing import _EntityType
54 from ._typing import _ORMColumnExprArgument
55 from .descriptor_props import _CC
56 from .descriptor_props import _CompositeAttrType
57 from .interfaces import PropComparator
58 from .mapper import Mapper
59 from .query import Query
60 from .relationships import _LazyLoadArgumentType
61 from .relationships import _ORMColCollectionArgument
62 from .relationships import _ORMOrderByArgument
63 from .relationships import _RelationshipJoinConditionArgument
64 from .relationships import ORMBackrefArgument
65 from .session import _SessionBind
66 from ..sql._typing import _AutoIncrementType
67 from ..sql._typing import _ColumnExpressionArgument
68 from ..sql._typing import _FromClauseArgument
69 from ..sql._typing import _InfoType
70 from ..sql._typing import _OnClauseArgument
71 from ..sql._typing import _TypeEngineArgument
72 from ..sql.elements import ColumnElement
73 from ..sql.schema import _ServerDefaultArgument
74 from ..sql.schema import _ServerOnUpdateArgument
75 from ..sql.selectable import Alias
76 from ..sql.selectable import Subquery
77
78
79_T = typing.TypeVar("_T")
80
81
82@util.deprecated(
83 "1.4",
84 "The :class:`.AliasOption` object is not necessary "
85 "for entities to be matched up to a query that is established "
86 "via :meth:`.Query.from_statement` and now does nothing.",
87 enable_warnings=False, # AliasOption itself warns
88)
89def contains_alias(alias: Union[Alias, Subquery]) -> AliasOption:
90 r"""Return a :class:`.MapperOption` that will indicate to the
91 :class:`_query.Query`
92 that the main table has been aliased.
93
94 """
95 return AliasOption(alias)
96
97
98def mapped_column(
99 __name_pos: Optional[
100 Union[str, _TypeEngineArgument[Any], SchemaEventTarget]
101 ] = None,
102 __type_pos: Optional[
103 Union[_TypeEngineArgument[Any], SchemaEventTarget]
104 ] = None,
105 *args: SchemaEventTarget,
106 init: Union[_NoArg, bool] = _NoArg.NO_ARG,
107 repr: Union[_NoArg, bool] = _NoArg.NO_ARG, # noqa: A002
108 default: Optional[Any] = _NoArg.NO_ARG,
109 default_factory: Union[_NoArg, Callable[[], _T]] = _NoArg.NO_ARG,
110 compare: Union[_NoArg, bool] = _NoArg.NO_ARG,
111 kw_only: Union[_NoArg, bool] = _NoArg.NO_ARG,
112 hash: Union[_NoArg, bool, None] = _NoArg.NO_ARG, # noqa: A002
113 nullable: Optional[
114 Union[bool, Literal[SchemaConst.NULL_UNSPECIFIED]]
115 ] = SchemaConst.NULL_UNSPECIFIED,
116 primary_key: Optional[bool] = False,
117 deferred: Union[_NoArg, bool] = _NoArg.NO_ARG,
118 deferred_group: Optional[str] = None,
119 deferred_raiseload: Optional[bool] = None,
120 use_existing_column: bool = False,
121 name: Optional[str] = None,
122 type_: Optional[_TypeEngineArgument[Any]] = None,
123 autoincrement: _AutoIncrementType = "auto",
124 doc: Optional[str] = None,
125 key: Optional[str] = None,
126 index: Optional[bool] = None,
127 unique: Optional[bool] = None,
128 info: Optional[_InfoType] = None,
129 onupdate: Optional[Any] = None,
130 insert_default: Optional[Any] = _NoArg.NO_ARG,
131 server_default: Optional[_ServerDefaultArgument] = None,
132 server_onupdate: Optional[_ServerOnUpdateArgument] = None,
133 active_history: bool = False,
134 quote: Optional[bool] = None,
135 system: bool = False,
136 comment: Optional[str] = None,
137 sort_order: Union[_NoArg, int] = _NoArg.NO_ARG,
138 dataclass_metadata: Union[_NoArg, Mapping[Any, Any], None] = _NoArg.NO_ARG,
139 **kw: Any,
140) -> MappedColumn[Any]:
141 r"""declare a new ORM-mapped :class:`_schema.Column` construct
142 for use within :ref:`Declarative Table <orm_declarative_table>`
143 configuration.
144
145 The :func:`_orm.mapped_column` function provides an ORM-aware and
146 Python-typing-compatible construct which is used with
147 :ref:`declarative <orm_declarative_mapping>` mappings to indicate an
148 attribute that's mapped to a Core :class:`_schema.Column` object. It
149 provides the equivalent feature as mapping an attribute to a
150 :class:`_schema.Column` object directly when using Declarative,
151 specifically when using :ref:`Declarative Table <orm_declarative_table>`
152 configuration.
153
154 .. versionadded:: 2.0
155
156 :func:`_orm.mapped_column` is normally used with explicit typing along with
157 the :class:`_orm.Mapped` annotation type, where it can derive the SQL
158 type and nullability for the column based on what's present within the
159 :class:`_orm.Mapped` annotation. It also may be used without annotations
160 as a drop-in replacement for how :class:`_schema.Column` is used in
161 Declarative mappings in SQLAlchemy 1.x style.
162
163 For usage examples of :func:`_orm.mapped_column`, see the documentation
164 at :ref:`orm_declarative_table`.
165
166 .. seealso::
167
168 :ref:`orm_declarative_table` - complete documentation
169
170 :ref:`whatsnew_20_orm_declarative_typing` - migration notes for
171 Declarative mappings using 1.x style mappings
172
173 :param __name: String name to give to the :class:`_schema.Column`. This
174 is an optional, positional only argument that if present must be the
175 first positional argument passed. If omitted, the attribute name to
176 which the :func:`_orm.mapped_column` is mapped will be used as the SQL
177 column name.
178 :param __type: :class:`_types.TypeEngine` type or instance which will
179 indicate the datatype to be associated with the :class:`_schema.Column`.
180 This is an optional, positional-only argument that if present must
181 immediately follow the ``__name`` parameter if present also, or otherwise
182 be the first positional parameter. If omitted, the ultimate type for
183 the column may be derived either from the annotated type, or if a
184 :class:`_schema.ForeignKey` is present, from the datatype of the
185 referenced column.
186 :param \*args: Additional positional arguments include constructs such
187 as :class:`_schema.ForeignKey`, :class:`_schema.CheckConstraint`,
188 and :class:`_schema.Identity`, which are passed through to the constructed
189 :class:`_schema.Column`.
190 :param nullable: Optional bool, whether the column should be "NULL" or
191 "NOT NULL". If omitted, the nullability is derived from the type
192 annotation based on whether or not ``typing.Optional`` (or its equivalent)
193 is present. ``nullable`` defaults to ``True`` otherwise for non-primary
194 key columns, and ``False`` for primary key columns.
195 :param primary_key: optional bool, indicates the :class:`_schema.Column`
196 would be part of the table's primary key or not.
197 :param deferred: Optional bool - this keyword argument is consumed by the
198 ORM declarative process, and is not part of the :class:`_schema.Column`
199 itself; instead, it indicates that this column should be "deferred" for
200 loading as though mapped by :func:`_orm.deferred`.
201
202 .. seealso::
203
204 :ref:`orm_queryguide_deferred_declarative`
205
206 :param deferred_group: Implies :paramref:`_orm.mapped_column.deferred`
207 to ``True``, and set the :paramref:`_orm.deferred.group` parameter.
208
209 .. seealso::
210
211 :ref:`orm_queryguide_deferred_group`
212
213 :param deferred_raiseload: Implies :paramref:`_orm.mapped_column.deferred`
214 to ``True``, and set the :paramref:`_orm.deferred.raiseload` parameter.
215
216 .. seealso::
217
218 :ref:`orm_queryguide_deferred_raiseload`
219
220 :param use_existing_column: if True, will attempt to locate the given
221 column name on an inherited superclass (typically single inheriting
222 superclass), and if present, will not produce a new column, mapping
223 to the superclass column as though it were omitted from this class.
224 This is used for mixins that add new columns to an inherited superclass.
225
226 .. seealso::
227
228 :ref:`orm_inheritance_column_conflicts`
229
230 .. versionadded:: 2.0.0b4
231
232 :param default: Passed directly to the
233 :paramref:`_schema.Column.default` parameter if the
234 :paramref:`_orm.mapped_column.insert_default` parameter is not present.
235 Additionally, when used with :ref:`orm_declarative_native_dataclasses`,
236 indicates a default Python value that should be applied to the keyword
237 constructor within the generated ``__init__()`` method.
238
239 Note that in the case of dataclass generation when
240 :paramref:`_orm.mapped_column.insert_default` is not present, this means
241 the :paramref:`_orm.mapped_column.default` value is used in **two**
242 places, both the ``__init__()`` method as well as the
243 :paramref:`_schema.Column.default` parameter. While this behavior may
244 change in a future release, for the moment this tends to "work out"; a
245 default of ``None`` will mean that the :class:`_schema.Column` gets no
246 default generator, whereas a default that refers to a non-``None`` Python
247 or SQL expression value will be assigned up front on the object when
248 ``__init__()`` is called, which is the same value that the Core
249 :class:`_sql.Insert` construct would use in any case, leading to the same
250 end result.
251
252 .. note:: When using Core level column defaults that are callables to
253 be interpreted by the underlying :class:`_schema.Column` in conjunction
254 with :ref:`ORM-mapped dataclasses
255 <orm_declarative_native_dataclasses>`, especially those that are
256 :ref:`context-aware default functions <context_default_functions>`,
257 **the** :paramref:`_orm.mapped_column.insert_default` **parameter must
258 be used instead**. This is necessary to disambiguate the callable from
259 being interpreted as a dataclass level default.
260
261 .. seealso::
262
263 :ref:`defaults_default_factory_insert_default`
264
265 :paramref:`_orm.mapped_column.insert_default`
266
267 :paramref:`_orm.mapped_column.default_factory`
268
269 :param insert_default: Passed directly to the
270 :paramref:`_schema.Column.default` parameter; will supersede the value
271 of :paramref:`_orm.mapped_column.default` when present, however
272 :paramref:`_orm.mapped_column.default` will always apply to the
273 constructor default for a dataclasses mapping.
274
275 .. seealso::
276
277 :ref:`defaults_default_factory_insert_default`
278
279 :paramref:`_orm.mapped_column.default`
280
281 :paramref:`_orm.mapped_column.default_factory`
282
283 :param sort_order: An integer that indicates how this mapped column
284 should be sorted compared to the others when the ORM is creating a
285 :class:`_schema.Table`. Among mapped columns that have the same
286 value the default ordering is used, placing first the mapped columns
287 defined in the main class, then the ones in the super classes.
288 Defaults to 0. The sort is ascending.
289
290 .. versionadded:: 2.0.4
291
292 :param active_history=False:
293
294 When ``True``, indicates that the "previous" value for a
295 scalar attribute should be loaded when replaced, if not
296 already loaded. Normally, history tracking logic for
297 simple non-primary-key scalar values only needs to be
298 aware of the "new" value in order to perform a flush. This
299 flag is available for applications that make use of
300 :func:`.attributes.get_history` or :meth:`.Session.is_modified`
301 which also need to know the "previous" value of the attribute.
302
303 .. versionadded:: 2.0.10
304
305
306 :param init: Specific to :ref:`orm_declarative_native_dataclasses`,
307 specifies if the mapped attribute should be part of the ``__init__()``
308 method as generated by the dataclass process.
309 :param repr: Specific to :ref:`orm_declarative_native_dataclasses`,
310 specifies if the mapped attribute should be part of the ``__repr__()``
311 method as generated by the dataclass process.
312 :param default_factory: Specific to
313 :ref:`orm_declarative_native_dataclasses`,
314 specifies a default-value generation function that will take place
315 as part of the ``__init__()``
316 method as generated by the dataclass process.
317
318 .. seealso::
319
320 :ref:`defaults_default_factory_insert_default`
321
322 :paramref:`_orm.mapped_column.default`
323
324 :paramref:`_orm.mapped_column.insert_default`
325
326 :param compare: Specific to
327 :ref:`orm_declarative_native_dataclasses`, indicates if this field
328 should be included in comparison operations when generating the
329 ``__eq__()`` and ``__ne__()`` methods for the mapped class.
330
331 .. versionadded:: 2.0.0b4
332
333 :param kw_only: Specific to
334 :ref:`orm_declarative_native_dataclasses`, indicates if this field
335 should be marked as keyword-only when generating the ``__init__()``.
336
337 :param hash: Specific to
338 :ref:`orm_declarative_native_dataclasses`, controls if this field
339 is included when generating the ``__hash__()`` method for the mapped
340 class.
341
342 .. versionadded:: 2.0.36
343
344 :param dataclass_metadata: Specific to
345 :ref:`orm_declarative_native_dataclasses`, supplies metadata
346 to be attached to the generated dataclass field.
347
348 .. versionadded:: 2.0.42
349
350 :param \**kw: All remaining keyword arguments are passed through to the
351 constructor for the :class:`_schema.Column`.
352
353 """
354
355 return MappedColumn(
356 __name_pos,
357 __type_pos,
358 *args,
359 name=name,
360 type_=type_,
361 autoincrement=autoincrement,
362 insert_default=insert_default,
363 attribute_options=_AttributeOptions(
364 init,
365 repr,
366 default,
367 default_factory,
368 compare,
369 kw_only,
370 hash,
371 dataclass_metadata,
372 ),
373 doc=doc,
374 key=key,
375 index=index,
376 unique=unique,
377 info=info,
378 active_history=active_history,
379 nullable=nullable,
380 onupdate=onupdate,
381 primary_key=primary_key,
382 server_default=server_default,
383 server_onupdate=server_onupdate,
384 use_existing_column=use_existing_column,
385 quote=quote,
386 comment=comment,
387 system=system,
388 deferred=deferred,
389 deferred_group=deferred_group,
390 deferred_raiseload=deferred_raiseload,
391 sort_order=sort_order,
392 **kw,
393 )
394
395
396def orm_insert_sentinel(
397 name: Optional[str] = None,
398 type_: Optional[_TypeEngineArgument[Any]] = None,
399 *,
400 default: Optional[Any] = None,
401 omit_from_statements: bool = True,
402) -> MappedColumn[Any]:
403 """Provides a surrogate :func:`_orm.mapped_column` that generates
404 a so-called :term:`sentinel` column, allowing efficient bulk
405 inserts with deterministic RETURNING sorting for tables that don't
406 otherwise have qualifying primary key configurations.
407
408 Use of :func:`_orm.orm_insert_sentinel` is analogous to the use of the
409 :func:`_schema.insert_sentinel` construct within a Core
410 :class:`_schema.Table` construct.
411
412 Guidelines for adding this construct to a Declarative mapped class
413 are the same as that of the :func:`_schema.insert_sentinel` construct;
414 the database table itself also needs to have a column with this name
415 present.
416
417 For background on how this object is used, see the section
418 :ref:`engine_insertmanyvalues_sentinel_columns` as part of the
419 section :ref:`engine_insertmanyvalues`.
420
421 .. seealso::
422
423 :func:`_schema.insert_sentinel`
424
425 :ref:`engine_insertmanyvalues`
426
427 :ref:`engine_insertmanyvalues_sentinel_columns`
428
429
430 .. versionadded:: 2.0.10
431
432 """
433
434 return mapped_column(
435 name=name,
436 default=(
437 default if default is not None else _InsertSentinelColumnDefault()
438 ),
439 _omit_from_statements=omit_from_statements,
440 insert_sentinel=True,
441 use_existing_column=True,
442 nullable=True,
443 )
444
445
446@util.deprecated_params(
447 **{
448 arg: (
449 "2.0",
450 f"The :paramref:`_orm.column_property.{arg}` parameter is "
451 "deprecated for :func:`_orm.column_property`. This parameter "
452 "applies to a writeable-attribute in a Declarative Dataclasses "
453 "configuration only, and :func:`_orm.column_property` is treated "
454 "as a read-only attribute in this context.",
455 )
456 for arg in ("init", "kw_only", "default", "default_factory")
457 }
458)
459def column_property(
460 column: _ORMColumnExprArgument[_T],
461 *additional_columns: _ORMColumnExprArgument[Any],
462 group: Optional[str] = None,
463 deferred: bool = False,
464 raiseload: bool = False,
465 comparator_factory: Optional[Type[PropComparator[_T]]] = None,
466 init: Union[_NoArg, bool] = _NoArg.NO_ARG,
467 repr: Union[_NoArg, bool] = _NoArg.NO_ARG, # noqa: A002
468 default: Optional[Any] = _NoArg.NO_ARG,
469 default_factory: Union[_NoArg, Callable[[], _T]] = _NoArg.NO_ARG,
470 compare: Union[_NoArg, bool] = _NoArg.NO_ARG,
471 kw_only: Union[_NoArg, bool] = _NoArg.NO_ARG,
472 hash: Union[_NoArg, bool, None] = _NoArg.NO_ARG, # noqa: A002
473 active_history: bool = False,
474 expire_on_flush: bool = True,
475 info: Optional[_InfoType] = None,
476 doc: Optional[str] = None,
477 dataclass_metadata: Union[_NoArg, Mapping[Any, Any], None] = _NoArg.NO_ARG,
478) -> MappedSQLExpression[_T]:
479 r"""Provide a column-level property for use with a mapping.
480
481 With Declarative mappings, :func:`_orm.column_property` is used to
482 map read-only SQL expressions to a mapped class.
483
484 When using Imperative mappings, :func:`_orm.column_property` also
485 takes on the role of mapping table columns with additional features.
486 When using fully Declarative mappings, the :func:`_orm.mapped_column`
487 construct should be used for this purpose.
488
489 With Declarative Dataclass mappings, :func:`_orm.column_property`
490 is considered to be **read only**, and will not be included in the
491 Dataclass ``__init__()`` constructor.
492
493 The :func:`_orm.column_property` function returns an instance of
494 :class:`.ColumnProperty`.
495
496 .. seealso::
497
498 :ref:`mapper_column_property_sql_expressions` - general use of
499 :func:`_orm.column_property` to map SQL expressions
500
501 :ref:`orm_imperative_table_column_options` - usage of
502 :func:`_orm.column_property` with Imperative Table mappings to apply
503 additional options to a plain :class:`_schema.Column` object
504
505 :param \*cols:
506 list of Column objects to be mapped.
507
508 :param active_history=False:
509
510 Used only for Imperative Table mappings, or legacy-style Declarative
511 mappings (i.e. which have not been upgraded to
512 :func:`_orm.mapped_column`), for column-based attributes that are
513 expected to be writeable; use :func:`_orm.mapped_column` with
514 :paramref:`_orm.mapped_column.active_history` for Declarative mappings.
515 See that parameter for functional details.
516
517 :param comparator_factory: a class which extends
518 :class:`.ColumnProperty.Comparator` which provides custom SQL
519 clause generation for comparison operations.
520
521 :param group:
522 a group name for this property when marked as deferred.
523
524 :param deferred:
525 when True, the column property is "deferred", meaning that
526 it does not load immediately, and is instead loaded when the
527 attribute is first accessed on an instance. See also
528 :func:`~sqlalchemy.orm.deferred`.
529
530 :param doc:
531 optional string that will be applied as the doc on the
532 class-bound descriptor.
533
534 :param expire_on_flush=True:
535 Disable expiry on flush. A column_property() which refers
536 to a SQL expression (and not a single table-bound column)
537 is considered to be a "read only" property; populating it
538 has no effect on the state of data, and it can only return
539 database state. For this reason a column_property()'s value
540 is expired whenever the parent object is involved in a
541 flush, that is, has any kind of "dirty" state within a flush.
542 Setting this parameter to ``False`` will have the effect of
543 leaving any existing value present after the flush proceeds.
544 Note that the :class:`.Session` with default expiration
545 settings still expires
546 all attributes after a :meth:`.Session.commit` call, however.
547
548 :param info: Optional data dictionary which will be populated into the
549 :attr:`.MapperProperty.info` attribute of this object.
550
551 :param raiseload: if True, indicates the column should raise an error
552 when undeferred, rather than loading the value. This can be
553 altered at query time by using the :func:`.deferred` option with
554 raiseload=False.
555
556 .. versionadded:: 1.4
557
558 .. seealso::
559
560 :ref:`orm_queryguide_deferred_raiseload`
561
562 :param init: Specific to :ref:`orm_declarative_native_dataclasses`,
563 specifies if the mapped attribute should be part of the ``__init__()``
564 method as generated by the dataclass process.
565 :param repr: Specific to :ref:`orm_declarative_native_dataclasses`,
566 specifies if the mapped attribute should be part of the ``__repr__()``
567 method as generated by the dataclass process.
568 :param default_factory: Specific to
569 :ref:`orm_declarative_native_dataclasses`,
570 specifies a default-value generation function that will take place
571 as part of the ``__init__()``
572 method as generated by the dataclass process.
573
574 .. seealso::
575
576 :ref:`defaults_default_factory_insert_default`
577
578 :paramref:`_orm.mapped_column.default`
579
580 :paramref:`_orm.mapped_column.insert_default`
581
582 :param compare: Specific to
583 :ref:`orm_declarative_native_dataclasses`, indicates if this field
584 should be included in comparison operations when generating the
585 ``__eq__()`` and ``__ne__()`` methods for the mapped class.
586
587 .. versionadded:: 2.0.0b4
588
589 :param kw_only: Specific to
590 :ref:`orm_declarative_native_dataclasses`, indicates if this field
591 should be marked as keyword-only when generating the ``__init__()``.
592
593 :param hash: Specific to
594 :ref:`orm_declarative_native_dataclasses`, controls if this field
595 is included when generating the ``__hash__()`` method for the mapped
596 class.
597
598 .. versionadded:: 2.0.36
599
600 :param dataclass_metadata: Specific to
601 :ref:`orm_declarative_native_dataclasses`, supplies metadata
602 to be attached to the generated dataclass field.
603
604 .. versionadded:: 2.0.42
605
606 """
607 return MappedSQLExpression(
608 column,
609 *additional_columns,
610 attribute_options=_AttributeOptions(
611 False if init is _NoArg.NO_ARG else init,
612 repr,
613 default,
614 default_factory,
615 compare,
616 kw_only,
617 hash,
618 dataclass_metadata,
619 ),
620 group=group,
621 deferred=deferred,
622 raiseload=raiseload,
623 comparator_factory=comparator_factory,
624 active_history=active_history,
625 expire_on_flush=expire_on_flush,
626 info=info,
627 doc=doc,
628 _assume_readonly_dc_attributes=True,
629 )
630
631
632@overload
633def composite(
634 _class_or_attr: _CompositeAttrType[Any],
635 *attrs: _CompositeAttrType[Any],
636 group: Optional[str] = None,
637 deferred: bool = False,
638 raiseload: bool = False,
639 comparator_factory: Optional[Type[Composite.Comparator[_T]]] = None,
640 active_history: bool = False,
641 init: Union[_NoArg, bool] = _NoArg.NO_ARG,
642 repr: Union[_NoArg, bool] = _NoArg.NO_ARG, # noqa: A002
643 default: Optional[Any] = _NoArg.NO_ARG,
644 default_factory: Union[_NoArg, Callable[[], _T]] = _NoArg.NO_ARG,
645 compare: Union[_NoArg, bool] = _NoArg.NO_ARG,
646 kw_only: Union[_NoArg, bool] = _NoArg.NO_ARG,
647 hash: Union[_NoArg, bool, None] = _NoArg.NO_ARG, # noqa: A002
648 info: Optional[_InfoType] = None,
649 doc: Optional[str] = None,
650 dataclass_metadata: Union[_NoArg, Mapping[Any, Any], None] = _NoArg.NO_ARG,
651 **__kw: Any,
652) -> Composite[Any]: ...
653
654
655@overload
656def composite(
657 _class_or_attr: Type[_CC],
658 *attrs: _CompositeAttrType[Any],
659 group: Optional[str] = None,
660 deferred: bool = False,
661 raiseload: bool = False,
662 comparator_factory: Optional[Type[Composite.Comparator[_T]]] = None,
663 active_history: bool = False,
664 init: Union[_NoArg, bool] = _NoArg.NO_ARG,
665 repr: Union[_NoArg, bool] = _NoArg.NO_ARG, # noqa: A002
666 default: Optional[Any] = _NoArg.NO_ARG,
667 default_factory: Union[_NoArg, Callable[[], _T]] = _NoArg.NO_ARG,
668 compare: Union[_NoArg, bool] = _NoArg.NO_ARG,
669 kw_only: Union[_NoArg, bool] = _NoArg.NO_ARG,
670 hash: Union[_NoArg, bool, None] = _NoArg.NO_ARG, # noqa: A002
671 info: Optional[_InfoType] = None,
672 doc: Optional[str] = None,
673 **__kw: Any,
674) -> Composite[_CC]: ...
675
676
677@overload
678def composite(
679 _class_or_attr: Callable[..., _CC],
680 *attrs: _CompositeAttrType[Any],
681 group: Optional[str] = None,
682 deferred: bool = False,
683 raiseload: bool = False,
684 comparator_factory: Optional[Type[Composite.Comparator[_T]]] = None,
685 active_history: bool = False,
686 init: Union[_NoArg, bool] = _NoArg.NO_ARG,
687 repr: Union[_NoArg, bool] = _NoArg.NO_ARG, # noqa: A002
688 default: Optional[Any] = _NoArg.NO_ARG,
689 default_factory: Union[_NoArg, Callable[[], _T]] = _NoArg.NO_ARG,
690 compare: Union[_NoArg, bool] = _NoArg.NO_ARG,
691 kw_only: Union[_NoArg, bool] = _NoArg.NO_ARG,
692 hash: Union[_NoArg, bool, None] = _NoArg.NO_ARG, # noqa: A002
693 info: Optional[_InfoType] = None,
694 doc: Optional[str] = None,
695 **__kw: Any,
696) -> Composite[_CC]: ...
697
698
699def composite(
700 _class_or_attr: Union[
701 None, Type[_CC], Callable[..., _CC], _CompositeAttrType[Any]
702 ] = None,
703 *attrs: _CompositeAttrType[Any],
704 group: Optional[str] = None,
705 deferred: bool = False,
706 raiseload: bool = False,
707 comparator_factory: Optional[Type[Composite.Comparator[_T]]] = None,
708 active_history: bool = False,
709 init: Union[_NoArg, bool] = _NoArg.NO_ARG,
710 repr: Union[_NoArg, bool] = _NoArg.NO_ARG, # noqa: A002
711 default: Optional[Any] = _NoArg.NO_ARG,
712 default_factory: Union[_NoArg, Callable[[], _T]] = _NoArg.NO_ARG,
713 compare: Union[_NoArg, bool] = _NoArg.NO_ARG,
714 kw_only: Union[_NoArg, bool] = _NoArg.NO_ARG,
715 hash: Union[_NoArg, bool, None] = _NoArg.NO_ARG, # noqa: A002
716 info: Optional[_InfoType] = None,
717 doc: Optional[str] = None,
718 dataclass_metadata: Union[_NoArg, Mapping[Any, Any], None] = _NoArg.NO_ARG,
719 **__kw: Any,
720) -> Composite[Any]:
721 r"""Return a composite column-based property for use with a Mapper.
722
723 See the mapping documentation section :ref:`mapper_composite` for a
724 full usage example.
725
726 The :class:`.MapperProperty` returned by :func:`.composite`
727 is the :class:`.Composite`.
728
729 :param class\_:
730 The "composite type" class, or any classmethod or callable which
731 will produce a new instance of the composite object given the
732 column values in order.
733
734 :param \*attrs:
735 List of elements to be mapped, which may include:
736
737 * :class:`_schema.Column` objects
738 * :func:`_orm.mapped_column` constructs
739 * string names of other attributes on the mapped class, which may be
740 any other SQL or object-mapped attribute. This can for
741 example allow a composite that refers to a many-to-one relationship
742
743 :param active_history=False:
744 When ``True``, indicates that the "previous" value for a
745 scalar attribute should be loaded when replaced, if not
746 already loaded. See the same flag on :func:`.column_property`.
747
748 :param group:
749 A group name for this property when marked as deferred.
750
751 :param deferred:
752 When True, the column property is "deferred", meaning that it does
753 not load immediately, and is instead loaded when the attribute is
754 first accessed on an instance. See also
755 :func:`~sqlalchemy.orm.deferred`.
756
757 :param comparator_factory: a class which extends
758 :class:`.Composite.Comparator` which provides custom SQL
759 clause generation for comparison operations.
760
761 :param doc:
762 optional string that will be applied as the doc on the
763 class-bound descriptor.
764
765 :param info: Optional data dictionary which will be populated into the
766 :attr:`.MapperProperty.info` attribute of this object.
767
768 :param init: Specific to :ref:`orm_declarative_native_dataclasses`,
769 specifies if the mapped attribute should be part of the ``__init__()``
770 method as generated by the dataclass process.
771 :param repr: Specific to :ref:`orm_declarative_native_dataclasses`,
772 specifies if the mapped attribute should be part of the ``__repr__()``
773 method as generated by the dataclass process.
774 :param default_factory: Specific to
775 :ref:`orm_declarative_native_dataclasses`,
776 specifies a default-value generation function that will take place
777 as part of the ``__init__()``
778 method as generated by the dataclass process.
779
780 :param compare: Specific to
781 :ref:`orm_declarative_native_dataclasses`, indicates if this field
782 should be included in comparison operations when generating the
783 ``__eq__()`` and ``__ne__()`` methods for the mapped class.
784
785 .. versionadded:: 2.0.0b4
786
787 :param kw_only: Specific to
788 :ref:`orm_declarative_native_dataclasses`, indicates if this field
789 should be marked as keyword-only when generating the ``__init__()``.
790
791 :param hash: Specific to
792 :ref:`orm_declarative_native_dataclasses`, controls if this field
793 is included when generating the ``__hash__()`` method for the mapped
794 class.
795
796 .. versionadded:: 2.0.36
797
798 :param dataclass_metadata: Specific to
799 :ref:`orm_declarative_native_dataclasses`, supplies metadata
800 to be attached to the generated dataclass field.
801
802 .. versionadded:: 2.0.42
803
804 """
805 if __kw:
806 raise _no_kw()
807
808 return Composite(
809 _class_or_attr,
810 *attrs,
811 attribute_options=_AttributeOptions(
812 init,
813 repr,
814 default,
815 default_factory,
816 compare,
817 kw_only,
818 hash,
819 dataclass_metadata,
820 ),
821 group=group,
822 deferred=deferred,
823 raiseload=raiseload,
824 comparator_factory=comparator_factory,
825 active_history=active_history,
826 info=info,
827 doc=doc,
828 )
829
830
831def with_loader_criteria(
832 entity_or_base: _EntityType[Any],
833 where_criteria: Union[
834 _ColumnExpressionArgument[bool],
835 Callable[[Any], _ColumnExpressionArgument[bool]],
836 ],
837 loader_only: bool = False,
838 include_aliases: bool = False,
839 propagate_to_loaders: bool = True,
840 track_closure_variables: bool = True,
841) -> LoaderCriteriaOption:
842 """Add additional WHERE criteria to the load for all occurrences of
843 a particular entity.
844
845 .. versionadded:: 1.4
846
847 The :func:`_orm.with_loader_criteria` option is intended to add
848 limiting criteria to a particular kind of entity in a query,
849 **globally**, meaning it will apply to the entity as it appears
850 in the SELECT query as well as within any subqueries, join
851 conditions, and relationship loads, including both eager and lazy
852 loaders, without the need for it to be specified in any particular
853 part of the query. The rendering logic uses the same system used by
854 single table inheritance to ensure a certain discriminator is applied
855 to a table.
856
857 E.g., using :term:`2.0-style` queries, we can limit the way the
858 ``User.addresses`` collection is loaded, regardless of the kind
859 of loading used::
860
861 from sqlalchemy.orm import with_loader_criteria
862
863 stmt = select(User).options(
864 selectinload(User.addresses),
865 with_loader_criteria(Address, Address.email_address != "foo"),
866 )
867
868 Above, the "selectinload" for ``User.addresses`` will apply the
869 given filtering criteria to the WHERE clause.
870
871 Another example, where the filtering will be applied to the
872 ON clause of the join, in this example using :term:`1.x style`
873 queries::
874
875 q = (
876 session.query(User)
877 .outerjoin(User.addresses)
878 .options(with_loader_criteria(Address, Address.email_address != "foo"))
879 )
880
881 The primary purpose of :func:`_orm.with_loader_criteria` is to use
882 it in the :meth:`_orm.SessionEvents.do_orm_execute` event handler
883 to ensure that all occurrences of a particular entity are filtered
884 in a certain way, such as filtering for access control roles. It
885 also can be used to apply criteria to relationship loads. In the
886 example below, we can apply a certain set of rules to all queries
887 emitted by a particular :class:`_orm.Session`::
888
889 session = Session(bind=engine)
890
891
892 @event.listens_for("do_orm_execute", session)
893 def _add_filtering_criteria(execute_state):
894
895 if (
896 execute_state.is_select
897 and not execute_state.is_column_load
898 and not execute_state.is_relationship_load
899 ):
900 execute_state.statement = execute_state.statement.options(
901 with_loader_criteria(
902 SecurityRole,
903 lambda cls: cls.role.in_(["some_role"]),
904 include_aliases=True,
905 )
906 )
907
908 In the above example, the :meth:`_orm.SessionEvents.do_orm_execute`
909 event will intercept all queries emitted using the
910 :class:`_orm.Session`. For those queries which are SELECT statements
911 and are not attribute or relationship loads a custom
912 :func:`_orm.with_loader_criteria` option is added to the query. The
913 :func:`_orm.with_loader_criteria` option will be used in the given
914 statement and will also be automatically propagated to all relationship
915 loads that descend from this query.
916
917 The criteria argument given is a ``lambda`` that accepts a ``cls``
918 argument. The given class will expand to include all mapped subclass
919 and need not itself be a mapped class.
920
921 .. tip::
922
923 When using :func:`_orm.with_loader_criteria` option in
924 conjunction with the :func:`_orm.contains_eager` loader option,
925 it's important to note that :func:`_orm.with_loader_criteria` only
926 affects the part of the query that determines what SQL is rendered
927 in terms of the WHERE and FROM clauses. The
928 :func:`_orm.contains_eager` option does not affect the rendering of
929 the SELECT statement outside of the columns clause, so does not have
930 any interaction with the :func:`_orm.with_loader_criteria` option.
931 However, the way things "work" is that :func:`_orm.contains_eager`
932 is meant to be used with a query that is already selecting from the
933 additional entities in some way, where
934 :func:`_orm.with_loader_criteria` can apply it's additional
935 criteria.
936
937 In the example below, assuming a mapping relationship as
938 ``A -> A.bs -> B``, the given :func:`_orm.with_loader_criteria`
939 option will affect the way in which the JOIN is rendered::
940
941 stmt = (
942 select(A)
943 .join(A.bs)
944 .options(contains_eager(A.bs), with_loader_criteria(B, B.flag == 1))
945 )
946
947 Above, the given :func:`_orm.with_loader_criteria` option will
948 affect the ON clause of the JOIN that is specified by
949 ``.join(A.bs)``, so is applied as expected. The
950 :func:`_orm.contains_eager` option has the effect that columns from
951 ``B`` are added to the columns clause:
952
953 .. sourcecode:: sql
954
955 SELECT
956 b.id, b.a_id, b.data, b.flag,
957 a.id AS id_1,
958 a.data AS data_1
959 FROM a JOIN b ON a.id = b.a_id AND b.flag = :flag_1
960
961
962 The use of the :func:`_orm.contains_eager` option within the above
963 statement has no effect on the behavior of the
964 :func:`_orm.with_loader_criteria` option. If the
965 :func:`_orm.contains_eager` option were omitted, the SQL would be
966 the same as regards the FROM and WHERE clauses, where
967 :func:`_orm.with_loader_criteria` continues to add its criteria to
968 the ON clause of the JOIN. The addition of
969 :func:`_orm.contains_eager` only affects the columns clause, in that
970 additional columns against ``b`` are added which are then consumed
971 by the ORM to produce ``B`` instances.
972
973 .. warning:: The use of a lambda inside of the call to
974 :func:`_orm.with_loader_criteria` is only invoked **once per unique
975 class**. Custom functions should not be invoked within this lambda.
976 See :ref:`engine_lambda_caching` for an overview of the "lambda SQL"
977 feature, which is for advanced use only.
978
979 :param entity_or_base: a mapped class, or a class that is a super
980 class of a particular set of mapped classes, to which the rule
981 will apply.
982
983 :param where_criteria: a Core SQL expression that applies limiting
984 criteria. This may also be a "lambda:" or Python function that
985 accepts a target class as an argument, when the given class is
986 a base with many different mapped subclasses.
987
988 .. note:: To support pickling, use a module-level Python function to
989 produce the SQL expression instead of a lambda or a fixed SQL
990 expression, which tend to not be picklable.
991
992 :param include_aliases: if True, apply the rule to :func:`_orm.aliased`
993 constructs as well.
994
995 :param propagate_to_loaders: defaults to True, apply to relationship
996 loaders such as lazy loaders. This indicates that the
997 option object itself including SQL expression is carried along with
998 each loaded instance. Set to ``False`` to prevent the object from
999 being assigned to individual instances.
1000
1001
1002 .. seealso::
1003
1004 :ref:`examples_session_orm_events` - includes examples of using
1005 :func:`_orm.with_loader_criteria`.
1006
1007 :ref:`do_orm_execute_global_criteria` - basic example on how to
1008 combine :func:`_orm.with_loader_criteria` with the
1009 :meth:`_orm.SessionEvents.do_orm_execute` event.
1010
1011 :param track_closure_variables: when False, closure variables inside
1012 of a lambda expression will not be used as part of
1013 any cache key. This allows more complex expressions to be used
1014 inside of a lambda expression but requires that the lambda ensures
1015 it returns the identical SQL every time given a particular class.
1016
1017 .. versionadded:: 1.4.0b2
1018
1019 """ # noqa: E501
1020 return LoaderCriteriaOption(
1021 entity_or_base,
1022 where_criteria,
1023 loader_only,
1024 include_aliases,
1025 propagate_to_loaders,
1026 track_closure_variables,
1027 )
1028
1029
1030def relationship(
1031 argument: Optional[_RelationshipArgumentType[Any]] = None,
1032 secondary: Optional[_RelationshipSecondaryArgument] = None,
1033 *,
1034 uselist: Optional[bool] = None,
1035 collection_class: Optional[
1036 Union[Type[Collection[Any]], Callable[[], Collection[Any]]]
1037 ] = None,
1038 primaryjoin: Optional[_RelationshipJoinConditionArgument] = None,
1039 secondaryjoin: Optional[_RelationshipJoinConditionArgument] = None,
1040 back_populates: Optional[str] = None,
1041 order_by: _ORMOrderByArgument = False,
1042 backref: Optional[ORMBackrefArgument] = None,
1043 overlaps: Optional[str] = None,
1044 post_update: bool = False,
1045 cascade: str = "save-update, merge",
1046 viewonly: bool = False,
1047 init: Union[_NoArg, bool] = _NoArg.NO_ARG,
1048 repr: Union[_NoArg, bool] = _NoArg.NO_ARG, # noqa: A002
1049 default: Union[_NoArg, _T] = _NoArg.NO_ARG,
1050 default_factory: Union[_NoArg, Callable[[], _T]] = _NoArg.NO_ARG,
1051 compare: Union[_NoArg, bool] = _NoArg.NO_ARG,
1052 kw_only: Union[_NoArg, bool] = _NoArg.NO_ARG,
1053 hash: Union[_NoArg, bool, None] = _NoArg.NO_ARG, # noqa: A002
1054 lazy: _LazyLoadArgumentType = "select",
1055 passive_deletes: Union[Literal["all"], bool] = False,
1056 passive_updates: bool = True,
1057 active_history: bool = False,
1058 enable_typechecks: bool = True,
1059 foreign_keys: Optional[_ORMColCollectionArgument] = None,
1060 remote_side: Optional[_ORMColCollectionArgument] = None,
1061 join_depth: Optional[int] = None,
1062 comparator_factory: Optional[
1063 Type[RelationshipProperty.Comparator[Any]]
1064 ] = None,
1065 single_parent: bool = False,
1066 innerjoin: bool = False,
1067 distinct_target_key: Optional[bool] = None,
1068 load_on_pending: bool = False,
1069 query_class: Optional[Type[Query[Any]]] = None,
1070 info: Optional[_InfoType] = None,
1071 omit_join: Literal[None, False] = None,
1072 sync_backref: Optional[bool] = None,
1073 dataclass_metadata: Union[_NoArg, Mapping[Any, Any], None] = _NoArg.NO_ARG,
1074 **kw: Any,
1075) -> _RelationshipDeclared[Any]:
1076 """Provide a relationship between two mapped classes.
1077
1078 This corresponds to a parent-child or associative table relationship.
1079 The constructed class is an instance of :class:`.Relationship`.
1080
1081 .. seealso::
1082
1083 :ref:`tutorial_orm_related_objects` - tutorial introduction
1084 to :func:`_orm.relationship` in the :ref:`unified_tutorial`
1085
1086 :ref:`relationship_config_toplevel` - narrative documentation
1087
1088 :param argument:
1089 This parameter refers to the class that is to be related. It
1090 accepts several forms, including a direct reference to the target
1091 class itself, the :class:`_orm.Mapper` instance for the target class,
1092 a Python callable / lambda that will return a reference to the
1093 class or :class:`_orm.Mapper` when called, and finally a string
1094 name for the class, which will be resolved from the
1095 :class:`_orm.registry` in use in order to locate the class, e.g.::
1096
1097 class SomeClass(Base):
1098 # ...
1099
1100 related = relationship("RelatedClass")
1101
1102 The :paramref:`_orm.relationship.argument` may also be omitted from the
1103 :func:`_orm.relationship` construct entirely, and instead placed inside
1104 a :class:`_orm.Mapped` annotation on the left side, which should
1105 include a Python collection type if the relationship is expected
1106 to be a collection, such as::
1107
1108 class SomeClass(Base):
1109 # ...
1110
1111 related_items: Mapped[List["RelatedItem"]] = relationship()
1112
1113 Or for a many-to-one or one-to-one relationship::
1114
1115 class SomeClass(Base):
1116 # ...
1117
1118 related_item: Mapped["RelatedItem"] = relationship()
1119
1120 .. seealso::
1121
1122 :ref:`orm_declarative_properties` - further detail
1123 on relationship configuration when using Declarative.
1124
1125 :param secondary:
1126 For a many-to-many relationship, specifies the intermediary
1127 table, and is typically an instance of :class:`_schema.Table`.
1128 In less common circumstances, the argument may also be specified
1129 as an :class:`_expression.Alias` construct, or even a
1130 :class:`_expression.Join` construct.
1131
1132 :paramref:`_orm.relationship.secondary` may
1133 also be passed as a callable function which is evaluated at
1134 mapper initialization time. When using Declarative, it may also
1135 be a string argument noting the name of a :class:`_schema.Table`
1136 that is
1137 present in the :class:`_schema.MetaData`
1138 collection associated with the
1139 parent-mapped :class:`_schema.Table`.
1140
1141 .. warning:: When passed as a Python-evaluable string, the
1142 argument is interpreted using Python's ``eval()`` function.
1143 **DO NOT PASS UNTRUSTED INPUT TO THIS STRING**.
1144 See :ref:`declarative_relationship_eval` for details on
1145 declarative evaluation of :func:`_orm.relationship` arguments.
1146
1147 The :paramref:`_orm.relationship.secondary` keyword argument is
1148 typically applied in the case where the intermediary
1149 :class:`_schema.Table`
1150 is not otherwise expressed in any direct class mapping. If the
1151 "secondary" table is also explicitly mapped elsewhere (e.g. as in
1152 :ref:`association_pattern`), one should consider applying the
1153 :paramref:`_orm.relationship.viewonly` flag so that this
1154 :func:`_orm.relationship`
1155 is not used for persistence operations which
1156 may conflict with those of the association object pattern.
1157
1158 .. seealso::
1159
1160 :ref:`relationships_many_to_many` - Reference example of "many
1161 to many".
1162
1163 :ref:`self_referential_many_to_many` - Specifics on using
1164 many-to-many in a self-referential case.
1165
1166 :ref:`declarative_many_to_many` - Additional options when using
1167 Declarative.
1168
1169 :ref:`association_pattern` - an alternative to
1170 :paramref:`_orm.relationship.secondary`
1171 when composing association
1172 table relationships, allowing additional attributes to be
1173 specified on the association table.
1174
1175 :ref:`composite_secondary_join` - a lesser-used pattern which
1176 in some cases can enable complex :func:`_orm.relationship` SQL
1177 conditions to be used.
1178
1179 :param active_history=False:
1180 When ``True``, indicates that the "previous" value for a
1181 many-to-one reference should be loaded when replaced, if
1182 not already loaded. Normally, history tracking logic for
1183 simple many-to-ones only needs to be aware of the "new"
1184 value in order to perform a flush. This flag is available
1185 for applications that make use of
1186 :func:`.attributes.get_history` which also need to know
1187 the "previous" value of the attribute.
1188
1189 :param backref:
1190 A reference to a string relationship name, or a :func:`_orm.backref`
1191 construct, which will be used to automatically generate a new
1192 :func:`_orm.relationship` on the related class, which then refers to this
1193 one using a bi-directional :paramref:`_orm.relationship.back_populates`
1194 configuration.
1195
1196 In modern Python, explicit use of :func:`_orm.relationship`
1197 with :paramref:`_orm.relationship.back_populates` should be preferred,
1198 as it is more robust in terms of mapper configuration as well as
1199 more conceptually straightforward. It also integrates with
1200 new :pep:`484` typing features introduced in SQLAlchemy 2.0 which
