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