Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
scoping.py2166 linesDownload Raw Back to orm
1# orm/scoping.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
10from typing import Any
11from typing import Callable
12from typing import Dict
13from typing import Generic
14from typing import Iterable
15from typing import Iterator
16from typing import Optional
17from typing import overload
18from typing import Sequence
19from typing import Tuple
20from typing import Type
21from typing import TYPE_CHECKING
22from typing import TypeVar
23from typing import Union
24
25from .session import _S
26from .session import Session
27from .. import exc as sa_exc
28from .. import util
29from ..util import create_proxy_methods
30from ..util import ScopedRegistry
31from ..util import ThreadLocalRegistry
32from ..util import warn
33from ..util import warn_deprecated
34from ..util.typing import Protocol
35
36if TYPE_CHECKING:
37    from ._typing import _EntityType
38    from ._typing import _IdentityKeyType
39    from ._typing import OrmExecuteOptionsParameter
40    from .identity import IdentityMap
41    from .interfaces import ORMOption
42    from .mapper import Mapper
43    from .query import Query
44    from .query import RowReturningQuery
45    from .session import _BindArguments
46    from .session import _EntityBindKey
47    from .session import _PKIdentityArgument
48    from .session import _SessionBind
49    from .session import sessionmaker
50    from .session import SessionTransaction
51    from ..engine import Connection
52    from ..engine import CursorResult
53    from ..engine import Engine
54    from ..engine import Result
55    from ..engine import Row
56    from ..engine import RowMapping
57    from ..engine.interfaces import _CoreAnyExecuteParams
58    from ..engine.interfaces import _CoreSingleExecuteParams
59    from ..engine.interfaces import CoreExecuteOptionsParameter
60    from ..engine.result import ScalarResult
61    from ..sql._typing import _ColumnsClauseArgument
62    from ..sql._typing import _T0
63    from ..sql._typing import _T1
64    from ..sql._typing import _T2
65    from ..sql._typing import _T3
66    from ..sql._typing import _T4
67    from ..sql._typing import _T5
68    from ..sql._typing import _T6
69    from ..sql._typing import _T7
70    from ..sql._typing import _TypedColumnClauseArgument as _TCCA
71    from ..sql.base import Executable
72    from ..sql.dml import UpdateBase
73    from ..sql.elements import ClauseElement
74    from ..sql.roles import TypedColumnsClauseRole
75    from ..sql.selectable import ForUpdateParameter
76    from ..sql.selectable import TypedReturnsRows
77
78_T = TypeVar("_T", bound=Any)
79
80
81class QueryPropertyDescriptor(Protocol):
82    """Describes the type applied to a class-level
83    :meth:`_orm.scoped_session.query_property` attribute.
84
85    .. versionadded:: 2.0.5
86
87    """
88
89    def __get__(self, instance: Any, owner: Type[_T]) -> Query[_T]: ...
90
91
92_O = TypeVar("_O", bound=object)
93
94__all__ = ["scoped_session"]
95
96
97@create_proxy_methods(
98    Session,
99    ":class:`_orm.Session`",
100    ":class:`_orm.scoping.scoped_session`",
101    classmethods=["close_all", "object_session", "identity_key"],
102    methods=[
103        "__contains__",
104        "__iter__",
105        "add",
106        "add_all",
107        "begin",
108        "begin_nested",
109        "close",
110        "reset",
111        "commit",
112        "connection",
113        "delete",
114        "execute",
115        "expire",
116        "expire_all",
117        "expunge",
118        "expunge_all",
119        "flush",
120        "get",
121        "get_one",
122        "get_bind",
123        "is_modified",
124        "bulk_save_objects",
125        "bulk_insert_mappings",
126        "bulk_update_mappings",
127        "merge",
128        "query",
129        "refresh",
130        "rollback",
131        "scalar",
132        "scalars",
133    ],
134    attributes=[
135        "bind",
136        "dirty",
137        "deleted",
138        "new",
139        "identity_map",
140        "is_active",
141        "autoflush",
142        "no_autoflush",
143        "info",
144    ],
145)
146class scoped_session(Generic[_S]):
147    """Provides scoped management of :class:`.Session` objects.
148
149    See :ref:`unitofwork_contextual` for a tutorial.
150
151    .. note::
152
153       When using :ref:`asyncio_toplevel`, the async-compatible
154       :class:`_asyncio.async_scoped_session` class should be
155       used in place of :class:`.scoped_session`.
156
157    """
158
159    _support_async: bool = False
160
161    session_factory: sessionmaker[_S]
162    """The `session_factory` provided to `__init__` is stored in this
163    attribute and may be accessed at a later time.  This can be useful when
164    a new non-scoped :class:`.Session` is needed."""
165
166    registry: ScopedRegistry[_S]
167
168    def __init__(
169        self,
170        session_factory: sessionmaker[_S],
171        scopefunc: Optional[Callable[[], Any]] = None,
172    ):
173        """Construct a new :class:`.scoped_session`.
174
175        :param session_factory: a factory to create new :class:`.Session`
176         instances. This is usually, but not necessarily, an instance
177         of :class:`.sessionmaker`.
178        :param scopefunc: optional function which defines
179         the current scope.   If not passed, the :class:`.scoped_session`
180         object assumes "thread-local" scope, and will use
181         a Python ``threading.local()`` in order to maintain the current
182         :class:`.Session`.  If passed, the function should return
183         a hashable token; this token will be used as the key in a
184         dictionary in order to store and retrieve the current
185         :class:`.Session`.
186
187        """
188        self.session_factory = session_factory
189
190        if scopefunc:
191            self.registry = ScopedRegistry(session_factory, scopefunc)
192        else:
193            self.registry = ThreadLocalRegistry(session_factory)
194
195    @property
196    def _proxied(self) -> _S:
197        return self.registry()
198
199    def __call__(self, **kw: Any) -> _S:
200        r"""Return the current :class:`.Session`, creating it
201        using the :attr:`.scoped_session.session_factory` if not present.
202
203        :param \**kw: Keyword arguments will be passed to the
204         :attr:`.scoped_session.session_factory` callable, if an existing
205         :class:`.Session` is not present.  If the :class:`.Session` is present
206         and keyword arguments have been passed,
207         :exc:`~sqlalchemy.exc.InvalidRequestError` is raised.
208
209        """
210        if kw:
211            if self.registry.has():
212                raise sa_exc.InvalidRequestError(
213                    "Scoped session is already present; "
214                    "no new arguments may be specified."
215                )
216            else:
217                sess = self.session_factory(**kw)
218                self.registry.set(sess)
219        else:
220            sess = self.registry()
221        if not self._support_async and sess._is_asyncio:
222            warn_deprecated(
223                "Using `scoped_session` with asyncio is deprecated and "
224                "will raise an error in a future version. "
225                "Please use `async_scoped_session` instead.",
226                "1.4.23",
227            )
228        return sess
229
230    def configure(self, **kwargs: Any) -> None:
231        """reconfigure the :class:`.sessionmaker` used by this
232        :class:`.scoped_session`.
233
234        See :meth:`.sessionmaker.configure`.
235
236        """
237
238        if self.registry.has():
239            warn(
240                "At least one scoped session is already present. "
241                " configure() can not affect sessions that have "
242                "already been created."
243            )
244
245        self.session_factory.configure(**kwargs)
246
247    def remove(self) -> None:
248        """Dispose of the current :class:`.Session`, if present.
249
250        This will first call :meth:`.Session.close` method
251        on the current :class:`.Session`, which releases any existing
252        transactional/connection resources still being held; transactions
253        specifically are rolled back.  The :class:`.Session` is then
254        discarded.   Upon next usage within the same scope,
255        the :class:`.scoped_session` will produce a new
256        :class:`.Session` object.
257
258        """
259
260        if self.registry.has():
261            self.registry().close()
262        self.registry.clear()
263
264    def query_property(
265        self, query_cls: Optional[Type[Query[_T]]] = None
266    ) -> QueryPropertyDescriptor:
267        """return a class property which produces a legacy
268        :class:`_query.Query` object against the class and the current
269        :class:`.Session` when called.
270
271        .. legacy:: The :meth:`_orm.scoped_session.query_property` accessor
272           is specific to the legacy :class:`.Query` object and is not
273           considered to be part of :term:`2.0-style` ORM use.
274
275        e.g.::
276
277            from sqlalchemy.orm import QueryPropertyDescriptor
278            from sqlalchemy.orm import scoped_session
279            from sqlalchemy.orm import sessionmaker
280
281            Session = scoped_session(sessionmaker())
282
283            class MyClass:
284                query: QueryPropertyDescriptor = Session.query_property()
285
286            # after mappers are defined
287            result = MyClass.query.filter(MyClass.name=='foo').all()
288
289        Produces instances of the session's configured query class by
290        default.  To override and use a custom implementation, provide
291        a ``query_cls`` callable.  The callable will be invoked with
292        the class's mapper as a positional argument and a session
293        keyword argument.
294
295        There is no limit to the number of query properties placed on
296        a class.
297
298        """
299
300        class query:
301            def __get__(s, instance: Any, owner: Type[_O]) -> Query[_O]:
302                if query_cls:
303                    # custom query class
304                    return query_cls(owner, session=self.registry())  # type: ignore  # noqa: E501
305                else:
306                    # session's configured query class
307                    return self.registry().query(owner)
308
309        return query()
310
311    # START PROXY METHODS scoped_session
312
313    # code within this block is **programmatically,
314    # statically generated** by tools/generate_proxy_methods.py
315
316    def __contains__(self, instance: object) -> bool:
317        r"""Return True if the instance is associated with this session.
318
319        .. container:: class_bases
320
321            Proxied for the :class:`_orm.Session` class on
322            behalf of the :class:`_orm.scoping.scoped_session` class.
323
324        The instance may be pending or persistent within the Session for a
325        result of True.
326
327
328        """  # noqa: E501
329
330        return self._proxied.__contains__(instance)
331
332    def __iter__(self) -> Iterator[object]:
333        r"""Iterate over all pending or persistent instances within this
334        Session.
335
336        .. container:: class_bases
337
338            Proxied for the :class:`_orm.Session` class on
339            behalf of the :class:`_orm.scoping.scoped_session` class.
340
341
342        """  # noqa: E501
343
344        return self._proxied.__iter__()
345
346    def add(self, instance: object, _warn: bool = True) -> None:
347        r"""Place an object into this :class:`_orm.Session`.
348
349        .. container:: class_bases
350
351            Proxied for the :class:`_orm.Session` class on
352            behalf of the :class:`_orm.scoping.scoped_session` class.
353
354        Objects that are in the :term:`transient` state when passed to the
355        :meth:`_orm.Session.add` method will move to the
356        :term:`pending` state, until the next flush, at which point they
357        will move to the :term:`persistent` state.
358
359        Objects that are in the :term:`detached` state when passed to the
360        :meth:`_orm.Session.add` method will move to the :term:`persistent`
361        state directly.
362
363        If the transaction used by the :class:`_orm.Session` is rolled back,
364        objects which were transient when they were passed to
365        :meth:`_orm.Session.add` will be moved back to the
366        :term:`transient` state, and will no longer be present within this
367        :class:`_orm.Session`.
368
369        .. seealso::
370
371            :meth:`_orm.Session.add_all`
372
373            :ref:`session_adding` - at :ref:`session_basics`
374
375
376        """  # noqa: E501
377
378        return self._proxied.add(instance, _warn=_warn)
379
380    def add_all(self, instances: Iterable[object]) -> None:
381        r"""Add the given collection of instances to this :class:`_orm.Session`.
382
383        .. container:: class_bases
384
385            Proxied for the :class:`_orm.Session` class on
386            behalf of the :class:`_orm.scoping.scoped_session` class.
387
388        See the documentation for :meth:`_orm.Session.add` for a general
389        behavioral description.
390
391        .. seealso::
392
393            :meth:`_orm.Session.add`
394
395            :ref:`session_adding` - at :ref:`session_basics`
396
397
398        """  # noqa: E501
399
400        return self._proxied.add_all(instances)
401
402    def begin(self, nested: bool = False) -> SessionTransaction:
403        r"""Begin a transaction, or nested transaction,
404        on this :class:`.Session`, if one is not already begun.
405
406        .. container:: class_bases
407
408            Proxied for the :class:`_orm.Session` class on
409            behalf of the :class:`_orm.scoping.scoped_session` class.
410
411        The :class:`_orm.Session` object features **autobegin** behavior,
412        so that normally it is not necessary to call the
413        :meth:`_orm.Session.begin`
414        method explicitly. However, it may be used in order to control
415        the scope of when the transactional state is begun.
416
417        When used to begin the outermost transaction, an error is raised
418        if this :class:`.Session` is already inside of a transaction.
419
420        :param nested: if True, begins a SAVEPOINT transaction and is
421         equivalent to calling :meth:`~.Session.begin_nested`. For
422         documentation on SAVEPOINT transactions, please see
423         :ref:`session_begin_nested`.
424
425        :return: the :class:`.SessionTransaction` object.  Note that
426         :class:`.SessionTransaction`
427         acts as a Python context manager, allowing :meth:`.Session.begin`
428         to be used in a "with" block.  See :ref:`session_explicit_begin` for
429         an example.
430
431        .. seealso::
432
433            :ref:`session_autobegin`
434
435            :ref:`unitofwork_transaction`
436
437            :meth:`.Session.begin_nested`
438
439
440
441        """  # noqa: E501
442
443        return self._proxied.begin(nested=nested)
444
445    def begin_nested(self) -> SessionTransaction:
446        r"""Begin a "nested" transaction on this Session, e.g. SAVEPOINT.
447
448        .. container:: class_bases
449
450            Proxied for the :class:`_orm.Session` class on
451            behalf of the :class:`_orm.scoping.scoped_session` class.
452
453        The target database(s) and associated drivers must support SQL
454        SAVEPOINT for this method to function correctly.
455
456        For documentation on SAVEPOINT
457        transactions, please see :ref:`session_begin_nested`.
458
459        :return: the :class:`.SessionTransaction` object.  Note that
460         :class:`.SessionTransaction` acts as a context manager, allowing
461         :meth:`.Session.begin_nested` to be used in a "with" block.
462         See :ref:`session_begin_nested` for a usage example.
463
464        .. seealso::
465
466            :ref:`session_begin_nested`
467
468            :ref:`pysqlite_serializable` - special workarounds required
469            with the SQLite driver in order for SAVEPOINT to work
470            correctly. For asyncio use cases, see the section
471            :ref:`aiosqlite_serializable`.
472
473
474        """  # noqa: E501
475
476        return self._proxied.begin_nested()
477
478    def close(self) -> None:
479        r"""Close out the transactional resources and ORM objects used by this
480        :class:`_orm.Session`.
481
482        .. container:: class_bases
483
484            Proxied for the :class:`_orm.Session` class on
485            behalf of the :class:`_orm.scoping.scoped_session` class.
486
487        This expunges all ORM objects associated with this
488        :class:`_orm.Session`, ends any transaction in progress and
489        :term:`releases` any :class:`_engine.Connection` objects which this
490        :class:`_orm.Session` itself has checked out from associated
491        :class:`_engine.Engine` objects. The operation then leaves the
492        :class:`_orm.Session` in a state which it may be used again.
493
494        .. tip::
495
496            In the default running mode the :meth:`_orm.Session.close`
497            method **does not prevent the Session from being used again**.
498            The :class:`_orm.Session` itself does not actually have a
499            distinct "closed" state; it merely means
500            the :class:`_orm.Session` will release all database connections
501            and ORM objects.
502
503            Setting the parameter :paramref:`_orm.Session.close_resets_only`
504            to ``False`` will instead make the ``close`` final, meaning that
505            any further action on the session will be forbidden.
506
507        .. versionchanged:: 1.4  The :meth:`.Session.close` method does not
508           immediately create a new :class:`.SessionTransaction` object;
509           instead, the new :class:`.SessionTransaction` is created only if
510           the :class:`.Session` is used again for a database operation.
511
512        .. seealso::
513
514            :ref:`session_closing` - detail on the semantics of
515            :meth:`_orm.Session.close` and :meth:`_orm.Session.reset`.
516
517            :meth:`_orm.Session.reset` - a similar method that behaves like
518            ``close()`` with  the parameter
519            :paramref:`_orm.Session.close_resets_only` set to ``True``.
520
521
522        """  # noqa: E501
523
524        return self._proxied.close()
525
526    def reset(self) -> None:
527        r"""Close out the transactional resources and ORM objects used by this
528        :class:`_orm.Session`, resetting the session to its initial state.
529
530        .. container:: class_bases
531
532            Proxied for the :class:`_orm.Session` class on
533            behalf of the :class:`_orm.scoping.scoped_session` class.
534
535        This method provides for same "reset-only" behavior that the
536        :meth:`_orm.Session.close` method has provided historically, where the
537        state of the :class:`_orm.Session` is reset as though the object were
538        brand new, and ready to be used again.
539        This method may then be useful for :class:`_orm.Session` objects
540        which set :paramref:`_orm.Session.close_resets_only` to ``False``,
541        so that "reset only" behavior is still available.
542
543        .. versionadded:: 2.0.22
544
545        .. seealso::
546
547            :ref:`session_closing` - detail on the semantics of
548            :meth:`_orm.Session.close` and :meth:`_orm.Session.reset`.
549
550            :meth:`_orm.Session.close` - a similar method will additionally
551            prevent re-use of the Session when the parameter
552            :paramref:`_orm.Session.close_resets_only` is set to ``False``.
553
554        """  # noqa: E501
555
556        return self._proxied.reset()
557
558    def commit(self) -> None:
559        r"""Flush pending changes and commit the current transaction.
560
561        .. container:: class_bases
562
563            Proxied for the :class:`_orm.Session` class on
564            behalf of the :class:`_orm.scoping.scoped_session` class.
565
566        When the COMMIT operation is complete, all objects are fully
567        :term:`expired`, erasing their internal contents, which will be
568        automatically re-loaded when the objects are next accessed. In the
569        interim, these objects are in an expired state and will not function if
570        they are :term:`detached` from the :class:`.Session`. Additionally,
571        this re-load operation is not supported when using asyncio-oriented
572        APIs. The :paramref:`.Session.expire_on_commit` parameter may be used
573        to disable this behavior.
574
575        When there is no transaction in place for the :class:`.Session`,
576        indicating that no operations were invoked on this :class:`.Session`
577        since the previous call to :meth:`.Session.commit`, the method will
578        begin and commit an internal-only "logical" transaction, that does not
579        normally affect the database unless pending flush changes were
580        detected, but will still invoke event handlers and object expiration
581        rules.
582
583        The outermost database transaction is committed unconditionally,
584        automatically releasing any SAVEPOINTs in effect.
585
586        .. seealso::
587
588            :ref:`session_committing`
589
590            :ref:`unitofwork_transaction`
591
592            :ref:`asyncio_orm_avoid_lazyloads`
593
594
595        """  # noqa: E501
596
597        return self._proxied.commit()
598
599    def connection(
600        self,
601        bind_arguments: Optional[_BindArguments] = None,
602        execution_options: Optional[CoreExecuteOptionsParameter] = None,
603    ) -> Connection:
604        r"""Return a :class:`_engine.Connection` object corresponding to this
605        :class:`.Session` object's transactional state.
606
607        .. container:: class_bases
608
609            Proxied for the :class:`_orm.Session` class on
610            behalf of the :class:`_orm.scoping.scoped_session` class.
611
612        Either the :class:`_engine.Connection` corresponding to the current
613        transaction is returned, or if no transaction is in progress, a new
614        one is begun and the :class:`_engine.Connection`
615        returned (note that no
616        transactional state is established with the DBAPI until the first
617        SQL statement is emitted).
618
619        Ambiguity in multi-bind or unbound :class:`.Session` objects can be
620        resolved through any of the optional keyword arguments.   This
621        ultimately makes usage of the :meth:`.get_bind` method for resolution.
622
623        :param bind_arguments: dictionary of bind arguments.  May include
624         "mapper", "bind", "clause", other custom arguments that are passed
625         to :meth:`.Session.get_bind`.
626
627        :param execution_options: a dictionary of execution options that will
628         be passed to :meth:`_engine.Connection.execution_options`, **when the
629         connection is first procured only**.   If the connection is already
630         present within the :class:`.Session`, a warning is emitted and
631         the arguments are ignored.
632
633         .. seealso::
634
635            :ref:`session_transaction_isolation`
636
637
638        """  # noqa: E501
639
640        return self._proxied.connection(
641            bind_arguments=bind_arguments, execution_options=execution_options
642        )
643
644    def delete(self, instance: object) -> None:
645        r"""Mark an instance as deleted.
646
647        .. container:: class_bases
648
649            Proxied for the :class:`_orm.Session` class on
650            behalf of the :class:`_orm.scoping.scoped_session` class.
651
652        The object is assumed to be either :term:`persistent` or
653        :term:`detached` when passed; after the method is called, the
654        object will remain in the :term:`persistent` state until the next
655        flush proceeds.  During this time, the object will also be a member
656        of the :attr:`_orm.Session.deleted` collection.
657
658        When the next flush proceeds, the object will move to the
659        :term:`deleted` state, indicating a ``DELETE`` statement was emitted
660        for its row within the current transaction.   When the transaction
661        is successfully committed,
662        the deleted object is moved to the :term:`detached` state and is
663        no longer present within this :class:`_orm.Session`.
664
665        .. seealso::
666
667            :ref:`session_deleting` - at :ref:`session_basics`
668
669
670        """  # noqa: E501
671
672        return self._proxied.delete(instance)
673
674    @overload
675    def execute(
676        self,
677        statement: TypedReturnsRows[_T],
678        params: Optional[_CoreAnyExecuteParams] = None,
679        *,
680        execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
681        bind_arguments: Optional[_BindArguments] = None,
682        _parent_execute_state: Optional[Any] = None,
683        _add_event: Optional[Any] = None,
684    ) -> Result[_T]: ...
685
686    @overload
687    def execute(
688        self,
689        statement: UpdateBase,
690        params: Optional[_CoreAnyExecuteParams] = None,
691        *,
692        execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
693        bind_arguments: Optional[_BindArguments] = None,
694        _parent_execute_state: Optional[Any] = None,
695        _add_event: Optional[Any] = None,
696    ) -> CursorResult[Any]: ...
697
698    @overload
699    def execute(
700        self,
701        statement: Executable,
702        params: Optional[_CoreAnyExecuteParams] = None,
703        *,
704        execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
705        bind_arguments: Optional[_BindArguments] = None,
706        _parent_execute_state: Optional[Any] = None,
707        _add_event: Optional[Any] = None,
708    ) -> Result[Any]: ...
709
710    def execute(
711        self,
712        statement: Executable,
713        params: Optional[_CoreAnyExecuteParams] = None,
714        *,
715        execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
716        bind_arguments: Optional[_BindArguments] = None,
717        _parent_execute_state: Optional[Any] = None,
718        _add_event: Optional[Any] = None,
719    ) -> Result[Any]:
720        r"""Execute a SQL expression construct.
721
722        .. container:: class_bases
723
724            Proxied for the :class:`_orm.Session` class on
725            behalf of the :class:`_orm.scoping.scoped_session` class.
726
727        Returns a :class:`_engine.Result` object representing
728        results of the statement execution.
729
730        E.g.::
731
732            from sqlalchemy import select
733            result = session.execute(
734                select(User).where(User.id == 5)
735            )
736
737        The API contract of :meth:`_orm.Session.execute` is similar to that
738        of :meth:`_engine.Connection.execute`, the :term:`2.0 style` version
739        of :class:`_engine.Connection`.
740
741        .. versionchanged:: 1.4 the :meth:`_orm.Session.execute` method is
742           now the primary point of ORM statement execution when using
743           :term:`2.0 style` ORM usage.
744
745        :param statement:
746            An executable statement (i.e. an :class:`.Executable` expression
747            such as :func:`_expression.select`).
748
749        :param params:
750            Optional dictionary, or list of dictionaries, containing
751            bound parameter values.   If a single dictionary, single-row
752            execution occurs; if a list of dictionaries, an
753            "executemany" will be invoked.  The keys in each dictionary
754            must correspond to parameter names present in the statement.
755
756        :param execution_options: optional dictionary of execution options,
757         which will be associated with the statement execution.  This
758         dictionary can provide a subset of the options that are accepted
759         by :meth:`_engine.Connection.execution_options`, and may also
760         provide additional options understood only in an ORM context.
761
762         .. seealso::
763
764            :ref:`orm_queryguide_execution_options` - ORM-specific execution
765            options
766
767        :param bind_arguments: dictionary of additional arguments to determine
768         the bind.  May include "mapper", "bind", or other custom arguments.
769         Contents of this dictionary are passed to the
770         :meth:`.Session.get_bind` method.
771
772        :return: a :class:`_engine.Result` object.
773
774
775
776        """  # noqa: E501
777
778        return self._proxied.execute(
779            statement,
780            params=params,
781            execution_options=execution_options,
782            bind_arguments=bind_arguments,
783            _parent_execute_state=_parent_execute_state,
784            _add_event=_add_event,
785        )
786
787    def expire(
788        self, instance: object, attribute_names: Optional[Iterable[str]] = None
789    ) -> None:
790        r"""Expire the attributes on an instance.
791
792        .. container:: class_bases
793
794            Proxied for the :class:`_orm.Session` class on
795            behalf of the :class:`_orm.scoping.scoped_session` class.
796
797        Marks the attributes of an instance as out of date. When an expired
798        attribute is next accessed, a query will be issued to the
799        :class:`.Session` object's current transactional context in order to
800        load all expired attributes for the given instance.   Note that
801        a highly isolated transaction will return the same values as were
802        previously read in that same transaction, regardless of changes
803        in database state outside of that transaction.
804
805        To expire all objects in the :class:`.Session` simultaneously,
806        use :meth:`Session.expire_all`.
807
808        The :class:`.Session` object's default behavior is to
809        expire all state whenever the :meth:`Session.rollback`
810        or :meth:`Session.commit` methods are called, so that new
811        state can be loaded for the new transaction.   For this reason,
812        calling :meth:`Session.expire` only makes sense for the specific
813        case that a non-ORM SQL statement was emitted in the current
814        transaction.
815
816        :param instance: The instance to be refreshed.
817        :param attribute_names: optional list of string attribute names
818          indicating a subset of attributes to be expired.
819
820        .. seealso::
821
822            :ref:`session_expire` - introductory material
823
824            :meth:`.Session.expire`
825
826            :meth:`.Session.refresh`
827
828            :meth:`_orm.Query.populate_existing`
829
830
831        """  # noqa: E501
832
833        return self._proxied.expire(instance, attribute_names=attribute_names)
834
835    def expire_all(self) -> None:
836        r"""Expires all persistent instances within this Session.
837
838        .. container:: class_bases
839
840            Proxied for the :class:`_orm.Session` class on
841            behalf of the :class:`_orm.scoping.scoped_session` class.
842
843        When any attributes on a persistent instance is next accessed,
844        a query will be issued using the
845        :class:`.Session` object's current transactional context in order to
846        load all expired attributes for the given instance.   Note that
847        a highly isolated transaction will return the same values as were
848        previously read in that same transaction, regardless of changes
849        in database state outside of that transaction.
850
851        To expire individual objects and individual attributes
852        on those objects, use :meth:`Session.expire`.
853
854        The :class:`.Session` object's default behavior is to
855        expire all state whenever the :meth:`Session.rollback`
856        or :meth:`Session.commit` methods are called, so that new
857        state can be loaded for the new transaction.   For this reason,
858        calling :meth:`Session.expire_all` is not usually needed,
859        assuming the transaction is isolated.
860
861        .. seealso::
862
863            :ref:`session_expire` - introductory material
864
865            :meth:`.Session.expire`
866
867            :meth:`.Session.refresh`
868
869            :meth:`_orm.Query.populate_existing`
870
871
872        """  # noqa: E501
873
874        return self._proxied.expire_all()
875
876    def expunge(self, instance: object) -> None:
877        r"""Remove the `instance` from this ``Session``.
878
879        .. container:: class_bases
880
881            Proxied for the :class:`_orm.Session` class on
882            behalf of the :class:`_orm.scoping.scoped_session` class.
883
884        This will free all internal references to the instance.  Cascading
885        will be applied according to the *expunge* cascade rule.
886
887
888        """  # noqa: E501
889
890        return self._proxied.expunge(instance)
891
892    def expunge_all(self) -> None:
893        r"""Remove all object instances from this ``Session``.
894
895        .. container:: class_bases
896
897            Proxied for the :class:`_orm.Session` class on
898            behalf of the :class:`_orm.scoping.scoped_session` class.
899
900        This is equivalent to calling ``expunge(obj)`` on all objects in this
901        ``Session``.
902
903
904        """  # noqa: E501
905
906        return self._proxied.expunge_all()
907
908    def flush(self, objects: Optional[Sequence[Any]] = None) -> None:
909        r"""Flush all the object changes to the database.
910
911        .. container:: class_bases
912
913            Proxied for the :class:`_orm.Session` class on
914            behalf of the :class:`_orm.scoping.scoped_session` class.
915
916        Writes out all pending object creations, deletions and modifications
917        to the database as INSERTs, DELETEs, UPDATEs, etc.  Operations are
918        automatically ordered by the Session's unit of work dependency
919        solver.
920
921        Database operations will be issued in the current transactional
922        context and do not affect the state of the transaction, unless an
923        error occurs, in which case the entire transaction is rolled back.
924        You may flush() as often as you like within a transaction to move
925        changes from Python to the database's transaction buffer.
926
927        :param objects: Optional; restricts the flush operation to operate
928          only on elements that are in the given collection.
929
930          This feature is for an extremely narrow set of use cases where
931          particular objects may need to be operated upon before the
932          full flush() occurs.  It is not intended for general use.
933
934
935        """  # noqa: E501
936
937        return self._proxied.flush(objects=objects)
938
939    def get(
940        self,
941        entity: _EntityBindKey[_O],
942        ident: _PKIdentityArgument,
943        *,
944        options: Optional[Sequence[ORMOption]] = None,
945        populate_existing: bool = False,
946        with_for_update: ForUpdateParameter = None,
947        identity_token: Optional[Any] = None,
948        execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
949        bind_arguments: Optional[_BindArguments] = None,
950    ) -> Optional[_O]:
951        r"""Return an instance based on the given primary key identifier,
952        or ``None`` if not found.
953
954        .. container:: class_bases
955
956            Proxied for the :class:`_orm.Session` class on
957            behalf of the :class:`_orm.scoping.scoped_session` class.
958
959        E.g.::
960
961            my_user = session.get(User, 5)
962
963            some_object = session.get(VersionedFoo, (5, 10))
964
965            some_object = session.get(
966                VersionedFoo,
967                {"id": 5, "version_id": 10}
968            )
969
970        .. versionadded:: 1.4 Added :meth:`_orm.Session.get`, which is moved
971           from the now legacy :meth:`_orm.Query.get` method.
972
973        :meth:`_orm.Session.get` is special in that it provides direct
974        access to the identity map of the :class:`.Session`.
975        If the given primary key identifier is present
976        in the local identity map, the object is returned
977        directly from this collection and no SQL is emitted,
978        unless the object has been marked fully expired.
979        If not present,
980        a SELECT is performed in order to locate the object.
981
982        :meth:`_orm.Session.get` also will perform a check if
983        the object is present in the identity map and
984        marked as expired - a SELECT
985        is emitted to refresh the object as well as to
986        ensure that the row is still present.
987        If not, :class:`~sqlalchemy.orm.exc.ObjectDeletedError` is raised.
988
989        :param entity: a mapped class or :class:`.Mapper` indicating the
990         type of entity to be loaded.
991
992        :param ident: A scalar, tuple, or dictionary representing the
993         primary key.  For a composite (e.g. multiple column) primary key,
994         a tuple or dictionary should be passed.
995
996         For a single-column primary key, the scalar calling form is typically
997         the most expedient.  If the primary key of a row is the value "5",
998         the call looks like::
999
1000            my_object = session.get(SomeClass, 5)
1001
1002         The tuple form contains primary key values typically in
1003         the order in which they correspond to the mapped
1004         :class:`_schema.Table`
1005         object's primary key columns, or if the
1006         :paramref:`_orm.Mapper.primary_key` configuration parameter were
1007         used, in
1008         the order used for that parameter. For example, if the primary key
1009         of a row is represented by the integer
1010         digits "5, 10" the call would look like::
1011
1012             my_object = session.get(SomeClass, (5, 10))
1013
1014         The dictionary form should include as keys the mapped attribute names
1015         corresponding to each element of the primary key.  If the mapped class
1016         has the attributes ``id``, ``version_id`` as the attributes which
1017         store the object's primary key value, the call would look like::
1018
1019            my_object = session.get(SomeClass, {"id": 5, "version_id": 10})
1020
1021        :param options: optional sequence of loader options which will be
1022         applied to the query, if one is emitted.
1023
1024        :param populate_existing: causes the method to unconditionally emit
1025         a SQL query and refresh the object with the newly loaded data,
1026         regardless of whether or not the object is already present.
1027
1028        :param with_for_update: optional boolean ``True`` indicating FOR UPDATE
1029          should be used, or may be a dictionary containing flags to
1030          indicate a more specific set of FOR UPDATE flags for the SELECT;
1031          flags should match the parameters of
1032          :meth:`_query.Query.with_for_update`.
1033          Supersedes the :paramref:`.Session.refresh.lockmode` parameter.
1034
1035        :param execution_options: optional dictionary of execution options,
1036         which will be associated with the query execution if one is emitted.
1037         This dictionary can provide a subset of the options that are
1038         accepted by :meth:`_engine.Connection.execution_options`, and may
1039         also provide additional options understood only in an ORM context.
1040
1041         .. versionadded:: 1.4.29
1042
1043         .. seealso::
1044
1045            :ref:`orm_queryguide_execution_options` - ORM-specific execution
1046            options
1047
1048        :param bind_arguments: dictionary of additional arguments to determine
1049         the bind.  May include "mapper", "bind", or other custom arguments.
1050         Contents of this dictionary are passed to the
1051         :meth:`.Session.get_bind` method.
1052
1053         .. versionadded: 2.0.0rc1
1054
1055        :return: The object instance, or ``None``.
1056
1057
1058        """  # noqa: E501
1059
1060        return self._proxied.get(
1061            entity,
1062            ident,
1063            options=options,
1064            populate_existing=populate_existing,
1065            with_for_update=with_for_update,
1066            identity_token=identity_token,
1067            execution_options=execution_options,
1068            bind_arguments=bind_arguments,
1069        )
1070
1071    def get_one(
1072        self,
1073        entity: _EntityBindKey[_O],
1074        ident: _PKIdentityArgument,
1075        *,
1076        options: Optional[Sequence[ORMOption]] = None,
1077        populate_existing: bool = False,
1078        with_for_update: ForUpdateParameter = None,
1079        identity_token: Optional[Any] = None,
1080        execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
1081        bind_arguments: Optional[_BindArguments] = None,
1082    ) -> _O:
1083        r"""Return exactly one instance based on the given primary key
1084        identifier, or raise an exception if not found.
1085
1086        .. container:: class_bases
1087
1088            Proxied for the :class:`_orm.Session` class on
1089            behalf of the :class:`_orm.scoping.scoped_session` class.
1090
1091        Raises ``sqlalchemy.orm.exc.NoResultFound`` if the query
1092        selects no rows.
1093
1094        For a detailed documentation of the arguments see the
1095        method :meth:`.Session.get`.
1096
1097        .. versionadded:: 2.0.22
1098
1099        :return: The object instance.
1100
1101        .. seealso::
1102
1103            :meth:`.Session.get` - equivalent method that instead
1104              returns ``None`` if no row was found with the provided primary
1105              key
1106
1107
1108        """  # noqa: E501
1109
1110        return self._proxied.get_one(
1111            entity,
1112            ident,
1113            options=options,
1114            populate_existing=populate_existing,
1115            with_for_update=with_for_update,
1116            identity_token=identity_token,
1117            execution_options=execution_options,
1118            bind_arguments=bind_arguments,
1119        )
1120
1121    def get_bind(
1122        self,
1123        mapper: Optional[_EntityBindKey[_O]] = None,
1124        *,
1125        clause: Optional[ClauseElement] = None,
1126        bind: Optional[_SessionBind] = None,
1127        _sa_skip_events: Optional[bool] = None,
1128        _sa_skip_for_implicit_returning: bool = False,
1129        **kw: Any,
1130    ) -> Union[Engine, Connection]:
1131        r"""Return a "bind" to which this :class:`.Session` is bound.
1132
1133        .. container:: class_bases
1134
1135            Proxied for the :class:`_orm.Session` class on
1136            behalf of the :class:`_orm.scoping.scoped_session` class.
1137
1138        The "bind" is usually an instance of :class:`_engine.Engine`,
1139        except in the case where the :class:`.Session` has been
1140        explicitly bound directly to a :class:`_engine.Connection`.
1141
1142        For a multiply-bound or unbound :class:`.Session`, the
1143        ``mapper`` or ``clause`` arguments are used to determine the
1144        appropriate bind to return.
1145
1146        Note that the "mapper" argument is usually present
1147        when :meth:`.Session.get_bind` is called via an ORM
1148        operation such as a :meth:`.Session.query`, each
1149        individual INSERT/UPDATE/DELETE operation within a
1150        :meth:`.Session.flush`, call, etc.
1151
1152        The order of resolution is:
1153
1154        1. if mapper given and :paramref:`.Session.binds` is present,
1155           locate a bind based first on the mapper in use, then
1156           on the mapped class in use, then on any base classes that are
1157           present in the ``__mro__`` of the mapped class, from more specific
1158           superclasses to more general.
1159        2. if clause given and ``Session.binds`` is present,
1160           locate a bind based on :class:`_schema.Table` objects
1161           found in the given clause present in ``Session.binds``.
1162        3. if ``Session.binds`` is present, return that.
1163        4. if clause given, attempt to return a bind
1164           linked to the :class:`_schema.MetaData` ultimately
1165           associated with the clause.
1166        5. if mapper given, attempt to return a bind
1167           linked to the :class:`_schema.MetaData` ultimately
1168           associated with the :class:`_schema.Table` or other
1169           selectable to which the mapper is mapped.
1170        6. No bind can be found, :exc:`~sqlalchemy.exc.UnboundExecutionError`
1171           is raised.
1172
1173        Note that the :meth:`.Session.get_bind` method can be overridden on
1174        a user-defined subclass of :class:`.Session` to provide any kind
1175        of bind resolution scheme.  See the example at
1176        :ref:`session_custom_partitioning`.
1177
1178        :param mapper:
1179          Optional mapped class or corresponding :class:`_orm.Mapper` instance.
1180          The bind can be derived from a :class:`_orm.Mapper` first by
1181          consulting the "binds" map associated with this :class:`.Session`,
1182          and secondly by consulting the :class:`_schema.MetaData` associated
1183          with the :class:`_schema.Table` to which the :class:`_orm.Mapper` is
1184          mapped for a bind.
1185
1186        :param clause:
1187            A :class:`_expression.ClauseElement` (i.e.
1188            :func:`_expression.select`,
1189            :func:`_expression.text`,
1190            etc.).  If the ``mapper`` argument is not present or could not
1191            produce a bind, the given expression construct will be searched
1192            for a bound element, typically a :class:`_schema.Table`
1193            associated with
1194            bound :class:`_schema.MetaData`.
1195
1196        .. seealso::
1197
1198             :ref:`session_partitioning`
1199
1200             :paramref:`.Session.binds`

Showing the first 1,200 of 2166 lines. Download the file for the rest.

codekingpro/portable-devtools · Team Ai