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

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

263 statements  

1# orm/scoping.py 

2# Copyright (C) 2005-2026 the SQLAlchemy authors and contributors 

3# <see AUTHORS file> 

4# 

5# This module is part of SQLAlchemy and is released under 

6# the MIT License: https://www.opensource.org/licenses/mit-license.php 

7 

8from __future__ import annotations 

9 

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 Protocol 

19from typing import Sequence 

20from typing import Tuple 

21from typing import Type 

22from typing import TYPE_CHECKING 

23from typing import TypeVar 

24from typing import Union 

25 

26from .session import _S 

27from .session import Session 

28from .. import exc as sa_exc 

29from .. import util 

30from ..util import create_proxy_methods 

31from ..util import ScopedRegistry 

32from ..util import ThreadLocalRegistry 

33from ..util import warn 

34from ..util import warn_deprecated 

35from ..util.typing import Never 

36from ..util.typing import TupleAny 

37from ..util.typing import TypeVarTuple 

38from ..util.typing import Unpack 

39 

40if TYPE_CHECKING: 

41 from ._typing import _EntityType 

42 from ._typing import _IdentityKeyType 

43 from ._typing import OrmExecuteOptionsParameter 

44 from .identity import IdentityMap 

45 from .interfaces import ORMOption 

46 from .mapper import Mapper 

47 from .query import Query 

48 from .query import RowReturningQuery 

49 from .session import _BindArguments 

50 from .session import _EntityBindKey 

51 from .session import _PKIdentityArgument 

52 from .session import _SessionBind 

53 from .session import sessionmaker 

54 from .session import SessionTransaction 

55 from ..engine import Connection 

56 from ..engine import Engine 

57 from ..engine import Result 

58 from ..engine import Row 

59 from ..engine import RowMapping 

60 from ..engine.interfaces import _CoreAnyExecuteParams 

61 from ..engine.interfaces import _CoreSingleExecuteParams 

62 from ..engine.interfaces import _ExecuteOptions 

63 from ..engine.interfaces import CoreExecuteOptionsParameter 

64 from ..engine.result import ScalarResult 

65 from ..sql._typing import _ColumnsClauseArgument 

66 from ..sql._typing import _T0 

67 from ..sql._typing import _T1 

68 from ..sql._typing import _T2 

69 from ..sql._typing import _T3 

70 from ..sql._typing import _T4 

71 from ..sql._typing import _T5 

72 from ..sql._typing import _T6 

73 from ..sql._typing import _T7 

74 from ..sql._typing import _TypedColumnClauseArgument as _TCCA 

75 from ..sql.base import Executable 

76 from ..sql.elements import ClauseElement 

77 from ..sql.roles import TypedColumnsClauseRole 

78 from ..sql.selectable import ForUpdateParameter 

79 from ..sql.selectable import TypedReturnsRows 

80 

81 

82_T = TypeVar("_T", bound=Any) 

83_Ts = TypeVarTuple("_Ts") 

84 

85 

86class QueryPropertyDescriptor(Protocol): 

87 """Describes the type applied to a class-level 

88 :meth:`_orm.scoped_session.query_property` attribute. 

89 

90 .. versionadded:: 2.0.5 

91 

92 """ 

93 

94 def __get__(self, instance: Any, owner: Type[_T]) -> Query[_T]: ... 

95 

96 

97_O = TypeVar("_O", bound=object) 

98 

99__all__ = ["scoped_session"] 

100 

101 

102@create_proxy_methods( 

103 Session, 

104 ":class:`_orm.Session`", 

105 ":class:`_orm.scoping.scoped_session`", 

106 classmethods=["object_session", "identity_key"], 

107 methods=[ 

108 "__contains__", 

109 "__iter__", 

110 "add", 

111 "add_all", 

112 "begin", 

113 "begin_nested", 

114 "close", 

115 "reset", 

116 "commit", 

117 "connection", 

118 "delete", 

119 "delete_all", 

120 "execute", 

121 "expire", 

122 "expire_all", 

123 "expunge", 

124 "expunge_all", 

125 "flush", 

126 "get", 

127 "get_one", 

128 "get_bind", 

129 "is_modified", 

130 "bulk_save_objects", 

131 "bulk_insert_mappings", 

132 "bulk_update_mappings", 

133 "merge", 

134 "merge_all", 

135 "query", 

136 "refresh", 

137 "rollback", 

138 "scalar", 

139 "scalars", 

140 ], 

141 attributes=[ 

142 "bind", 

143 "dirty", 

144 "deleted", 

145 "new", 

146 "identity_map", 

147 "is_active", 

148 "autoflush", 

149 "no_autoflush", 

150 "info", 

151 "execution_options", 

152 ], 

153) 

154class scoped_session(Generic[_S]): 

155 """Provides scoped management of :class:`.Session` objects. 

156 

157 See :ref:`unitofwork_contextual` for a tutorial. 

158 

159 .. note:: 

160 

161 When using :ref:`asyncio_toplevel`, the async-compatible 

162 :class:`_asyncio.async_scoped_session` class should be 

163 used in place of :class:`.scoped_session`. 

164 

165 """ 

166 

167 _support_async: bool = False 

168 

169 session_factory: sessionmaker[_S] 

170 """The `session_factory` provided to `__init__` is stored in this 

171 attribute and may be accessed at a later time. This can be useful when 

172 a new non-scoped :class:`.Session` is needed.""" 

173 

174 registry: ScopedRegistry[_S] 

175 

176 def __init__( 

177 self, 

178 session_factory: sessionmaker[_S], 

179 scopefunc: Optional[Callable[[], Any]] = None, 

180 ): 

181 """Construct a new :class:`.scoped_session`. 

182 

183 :param session_factory: a factory to create new :class:`.Session` 

184 instances. This is usually, but not necessarily, an instance 

185 of :class:`.sessionmaker`. 

186 :param scopefunc: optional function which defines 

187 the current scope. If not passed, the :class:`.scoped_session` 

188 object assumes "thread-local" scope, and will use 

189 a Python ``threading.local()`` in order to maintain the current 

190 :class:`.Session`. If passed, the function should return 

191 a hashable token; this token will be used as the key in a 

192 dictionary in order to store and retrieve the current 

193 :class:`.Session`. 

194 

195 """ 

196 self.session_factory = session_factory 

197 

198 if scopefunc: 

199 self.registry = ScopedRegistry(session_factory, scopefunc) 

200 else: 

201 self.registry = ThreadLocalRegistry(session_factory) 

202 

203 @property 

204 def _proxied(self) -> _S: 

205 return self.registry() 

206 

207 def __call__(self, **kw: Any) -> _S: 

208 r"""Return the current :class:`.Session`, creating it 

209 using the :attr:`.scoped_session.session_factory` if not present. 

210 

211 :param \**kw: Keyword arguments will be passed to the 

212 :attr:`.scoped_session.session_factory` callable, if an existing 

213 :class:`.Session` is not present. If the :class:`.Session` is present 

214 and keyword arguments have been passed, 

215 :exc:`~sqlalchemy.exc.InvalidRequestError` is raised. 

216 

217 """ 

218 if kw: 

219 if self.registry.has(): 

220 raise sa_exc.InvalidRequestError( 

221 "Scoped session is already present; " 

222 "no new arguments may be specified." 

223 ) 

224 else: 

225 sess = self.session_factory(**kw) 

226 self.registry.set(sess) 

227 else: 

228 sess = self.registry() 

229 if not self._support_async and sess._is_asyncio: 

230 warn_deprecated( 

231 "Using `scoped_session` with asyncio is deprecated and " 

232 "will raise an error in a future version. " 

233 "Please use `async_scoped_session` instead.", 

234 "1.4.23", 

235 ) 

236 return sess 

237 

238 def configure(self, **kwargs: Any) -> None: 

239 """reconfigure the :class:`.sessionmaker` used by this 

240 :class:`.scoped_session`. 

241 

242 See :meth:`.sessionmaker.configure`. 

243 

244 """ 

245 

246 if self.registry.has(): 

247 warn( 

248 "At least one scoped session is already present. " 

249 " configure() can not affect sessions that have " 

250 "already been created." 

251 ) 

252 

253 self.session_factory.configure(**kwargs) 

254 

255 def remove(self) -> None: 

256 """Dispose of the current :class:`.Session`, if present. 

257 

258 This will first call :meth:`.Session.close` method 

259 on the current :class:`.Session`, which releases any existing 

260 transactional/connection resources still being held; transactions 

261 specifically are rolled back. The :class:`.Session` is then 

262 discarded. Upon next usage within the same scope, 

263 the :class:`.scoped_session` will produce a new 

264 :class:`.Session` object. 

265 

266 """ 

267 

268 if self.registry.has(): 

269 self.registry().close() 

270 self.registry.clear() 

271 

272 def query_property( 

273 self, query_cls: Optional[Type[Query[_T]]] = None 

274 ) -> QueryPropertyDescriptor: 

275 """return a class property which produces a legacy 

276 :class:`_query.Query` object against the class and the current 

277 :class:`.Session` when called. 

278 

279 .. legacy:: The :meth:`_orm.scoped_session.query_property` accessor 

280 is specific to the legacy :class:`.Query` object and is not 

281 considered to be part of :term:`2.0-style` ORM use. 

282 

283 e.g.:: 

284 

285 from sqlalchemy.orm import QueryPropertyDescriptor 

286 from sqlalchemy.orm import scoped_session 

287 from sqlalchemy.orm import sessionmaker 

288 

289 Session = scoped_session(sessionmaker()) 

290 

291 

292 class MyClass: 

293 query: QueryPropertyDescriptor = Session.query_property() 

294 

295 

296 # after mappers are defined 

297 result = MyClass.query.filter(MyClass.name == "foo").all() 

298 

299 Produces instances of the session's configured query class by 

300 default. To override and use a custom implementation, provide 

301 a ``query_cls`` callable. The callable will be invoked with 

302 the class's mapper as a positional argument and a session 

303 keyword argument. 

304 

305 There is no limit to the number of query properties placed on 

306 a class. 

307 

308 """ 

309 

310 class query: 

311 def __get__(s, instance: Any, owner: Type[_O]) -> Query[_O]: 

312 if query_cls: 

313 # custom query class 

314 return query_cls(owner, session=self.registry()) # type: ignore # noqa: E501 

315 else: 

316 # session's configured query class 

317 return self.registry().query(owner) 

318 

319 return query() 

320 

321 # START PROXY METHODS scoped_session 

322 

323 # code within this block is **programmatically, 

324 # statically generated** by tools/generate_proxy_methods.py 

325 

326 def __contains__(self, instance: object) -> bool: 

327 r"""Return True if the instance is associated with this session. 

328 

329 .. container:: class_bases 

330 

331 Proxied for the :class:`_orm.Session` class on 

332 behalf of the :class:`_orm.scoping.scoped_session` class. 

333 

334 The instance may be pending or persistent within the Session for a 

335 result of True. 

336 

337 

338 """ # noqa: E501 

339 

340 return self._proxied.__contains__(instance) 

341 

342 def __iter__(self) -> Iterator[object]: 

343 r"""Iterate over all pending or persistent instances within this 

344 Session. 

345 

346 .. container:: class_bases 

347 

348 Proxied for the :class:`_orm.Session` class on 

349 behalf of the :class:`_orm.scoping.scoped_session` class. 

350 

351 

352 """ # noqa: E501 

353 

354 return self._proxied.__iter__() 

355 

356 def add(self, instance: object, *, _warn: bool = True) -> None: 

357 r"""Place an object into this :class:`_orm.Session`. 

358 

359 .. container:: class_bases 

360 

361 Proxied for the :class:`_orm.Session` class on 

362 behalf of the :class:`_orm.scoping.scoped_session` class. 

363 

364 Objects that are in the :term:`transient` state when passed to the 

365 :meth:`_orm.Session.add` method will move to the 

366 :term:`pending` state, until the next flush, at which point they 

367 will move to the :term:`persistent` state. 

368 

369 Objects that are in the :term:`detached` state when passed to the 

370 :meth:`_orm.Session.add` method will move to the :term:`persistent` 

371 state directly. 

372 

373 If the transaction used by the :class:`_orm.Session` is rolled back, 

374 objects which were transient when they were passed to 

375 :meth:`_orm.Session.add` will be moved back to the 

376 :term:`transient` state, and will no longer be present within this 

377 :class:`_orm.Session`. 

378 

379 .. seealso:: 

380 

381 :meth:`_orm.Session.add_all` 

382 

383 :ref:`session_adding` - at :ref:`session_basics` 

384 

385 

386 """ # noqa: E501 

387 

388 return self._proxied.add(instance, _warn=_warn) 

389 

390 def add_all(self, instances: Iterable[object]) -> None: 

391 r"""Add the given collection of instances to this :class:`_orm.Session`. 

392 

393 .. container:: class_bases 

394 

395 Proxied for the :class:`_orm.Session` class on 

396 behalf of the :class:`_orm.scoping.scoped_session` class. 

397 

398 See the documentation for :meth:`_orm.Session.add` for a general 

399 behavioral description. 

400 

401 .. seealso:: 

402 

403 :meth:`_orm.Session.add` 

404 

405 :ref:`session_adding` - at :ref:`session_basics` 

406 

407 

408 """ # noqa: E501 

409 

410 return self._proxied.add_all(instances) 

411 

412 def begin(self, nested: bool = False) -> SessionTransaction: 

413 r"""Begin a transaction, or nested transaction, 

414 on this :class:`.Session`, if one is not already begun. 

415 

416 .. container:: class_bases 

417 

418 Proxied for the :class:`_orm.Session` class on 

419 behalf of the :class:`_orm.scoping.scoped_session` class. 

420 

421 The :class:`_orm.Session` object features **autobegin** behavior, 

422 so that normally it is not necessary to call the 

423 :meth:`_orm.Session.begin` 

424 method explicitly. However, it may be used in order to control 

425 the scope of when the transactional state is begun. 

426 

427 When used to begin the outermost transaction, an error is raised 

428 if this :class:`.Session` is already inside of a transaction. 

429 

430 :param nested: if True, begins a SAVEPOINT transaction and is 

431 equivalent to calling :meth:`~.Session.begin_nested`. For 

432 documentation on SAVEPOINT transactions, please see 

433 :ref:`session_begin_nested`. 

434 

435 :return: the :class:`.SessionTransaction` object. Note that 

436 :class:`.SessionTransaction` 

437 acts as a Python context manager, allowing :meth:`.Session.begin` 

438 to be used in a "with" block. See :ref:`session_explicit_begin` for 

439 an example. 

440 

441 .. seealso:: 

442 

443 :ref:`session_autobegin` 

444 

445 :ref:`unitofwork_transaction` 

446 

447 :meth:`.Session.begin_nested` 

448 

449 

450 

451 """ # noqa: E501 

452 

453 return self._proxied.begin(nested=nested) 

454 

455 def begin_nested(self) -> SessionTransaction: 

456 r"""Begin a "nested" transaction on this Session, e.g. SAVEPOINT. 

457 

458 .. container:: class_bases 

459 

460 Proxied for the :class:`_orm.Session` class on 

461 behalf of the :class:`_orm.scoping.scoped_session` class. 

462 

463 The target database(s) and associated drivers must support SQL 

464 SAVEPOINT for this method to function correctly. 

465 

466 For documentation on SAVEPOINT 

467 transactions, please see :ref:`session_begin_nested`. 

468 

469 :return: the :class:`.SessionTransaction` object. Note that 

470 :class:`.SessionTransaction` acts as a context manager, allowing 

471 :meth:`.Session.begin_nested` to be used in a "with" block. 

472 See :ref:`session_begin_nested` for a usage example. 

473 

474 .. seealso:: 

475 

476 :ref:`session_begin_nested` 

477 

478 :ref:`pysqlite_serializable` - special workarounds required 

479 with the SQLite driver in order for SAVEPOINT to work 

480 correctly. For asyncio use cases, see the section 

481 :ref:`aiosqlite_serializable`. 

482 

483 

484 """ # noqa: E501 

485 

486 return self._proxied.begin_nested() 

487 

488 def close(self) -> None: 

489 r"""Close out the transactional resources and ORM objects used by this 

490 :class:`_orm.Session`. 

491 

492 .. container:: class_bases 

493 

494 Proxied for the :class:`_orm.Session` class on 

495 behalf of the :class:`_orm.scoping.scoped_session` class. 

496 

497 This expunges all ORM objects associated with this 

498 :class:`_orm.Session`, ends any transaction in progress and 

499 :term:`releases` any :class:`_engine.Connection` objects which this 

500 :class:`_orm.Session` itself has checked out from associated 

501 :class:`_engine.Engine` objects. The operation then leaves the 

502 :class:`_orm.Session` in a state which it may be used again. 

503 

504 .. tip:: 

505 

506 In the default running mode the :meth:`_orm.Session.close` 

507 method **does not prevent the Session from being used again**. 

508 The :class:`_orm.Session` itself does not actually have a 

509 distinct "closed" state; it merely means 

510 the :class:`_orm.Session` will release all database connections 

511 and ORM objects. 

512 

513 Setting the parameter :paramref:`_orm.Session.close_resets_only` 

514 to ``False`` will instead make the ``close`` final, meaning that 

515 any further action on the session will be forbidden. 

516 

517 .. versionchanged:: 1.4 The :meth:`.Session.close` method does not 

518 immediately create a new :class:`.SessionTransaction` object; 

519 instead, the new :class:`.SessionTransaction` is created only if 

520 the :class:`.Session` is used again for a database operation. 

521 

522 .. seealso:: 

523 

524 :ref:`session_closing` - detail on the semantics of 

525 :meth:`_orm.Session.close` and :meth:`_orm.Session.reset`. 

526 

527 :meth:`_orm.Session.reset` - a similar method that behaves like 

528 ``close()`` with the parameter 

529 :paramref:`_orm.Session.close_resets_only` set to ``True``. 

530 

531 

532 """ # noqa: E501 

533 

534 return self._proxied.close() 

535 

536 def reset(self) -> None: 

537 r"""Close out the transactional resources and ORM objects used by this 

538 :class:`_orm.Session`, resetting the session to its initial state. 

539 

540 .. container:: class_bases 

541 

542 Proxied for the :class:`_orm.Session` class on 

543 behalf of the :class:`_orm.scoping.scoped_session` class. 

544 

545 This method provides for same "reset-only" behavior that the 

546 :meth:`_orm.Session.close` method has provided historically, where the 

547 state of the :class:`_orm.Session` is reset as though the object were 

548 brand new, and ready to be used again. 

549 This method may then be useful for :class:`_orm.Session` objects 

550 which set :paramref:`_orm.Session.close_resets_only` to ``False``, 

551 so that "reset only" behavior is still available. 

552 

553 .. versionadded:: 2.0.22 

554 

555 .. seealso:: 

556 

557 :ref:`session_closing` - detail on the semantics of 

558 :meth:`_orm.Session.close` and :meth:`_orm.Session.reset`. 

559 

560 :meth:`_orm.Session.close` - a similar method will additionally 

561 prevent reuse of the Session when the parameter 

562 :paramref:`_orm.Session.close_resets_only` is set to ``False``. 

563 

564 """ # noqa: E501 

565 

566 return self._proxied.reset() 

567 

568 def commit(self) -> None: 

569 r"""Flush pending changes and commit the current transaction. 

570 

571 .. container:: class_bases 

572 

573 Proxied for the :class:`_orm.Session` class on 

574 behalf of the :class:`_orm.scoping.scoped_session` class. 

575 

576 When the COMMIT operation is complete, all objects are fully 

577 :term:`expired`, erasing their internal contents, which will be 

578 automatically re-loaded when the objects are next accessed. In the 

579 interim, these objects are in an expired state and will not function if 

580 they are :term:`detached` from the :class:`.Session`. Additionally, 

581 this re-load operation is not supported when using asyncio-oriented 

582 APIs. The :paramref:`.Session.expire_on_commit` parameter may be used 

583 to disable this behavior. 

584 

585 When there is no transaction in place for the :class:`.Session`, 

586 indicating that no operations were invoked on this :class:`.Session` 

587 since the previous call to :meth:`.Session.commit`, the method will 

588 begin and commit an internal-only "logical" transaction, that does not 

589 normally affect the database unless pending flush changes were 

590 detected, but will still invoke event handlers and object expiration 

591 rules. 

592 

593 The outermost database transaction is committed unconditionally, 

594 automatically releasing any SAVEPOINTs in effect. 

595 

596 .. seealso:: 

597 

598 :ref:`session_committing` 

599 

600 :ref:`unitofwork_transaction` 

601 

602 :ref:`asyncio_orm_avoid_lazyloads` 

603 

604 

605 """ # noqa: E501 

606 

607 return self._proxied.commit() 

608 

609 def connection( 

610 self, 

611 bind_arguments: Optional[_BindArguments] = None, 

612 execution_options: Optional[CoreExecuteOptionsParameter] = None, 

613 ) -> Connection: 

614 r"""Return a :class:`_engine.Connection` object corresponding to this 

615 :class:`.Session` object's transactional state. 

616 

617 .. container:: class_bases 

618 

619 Proxied for the :class:`_orm.Session` class on 

620 behalf of the :class:`_orm.scoping.scoped_session` class. 

621 

622 Either the :class:`_engine.Connection` corresponding to the current 

623 transaction is returned, or if no transaction is in progress, a new 

624 one is begun and the :class:`_engine.Connection` 

625 returned (note that no 

626 transactional state is established with the DBAPI until the first 

627 SQL statement is emitted). 

628 

629 Ambiguity in multi-bind or unbound :class:`.Session` objects can be 

630 resolved through any of the optional keyword arguments. This 

631 ultimately makes usage of the :meth:`.get_bind` method for resolution. 

632 

633 :param bind_arguments: dictionary of bind arguments. May include 

634 "mapper", "bind", "clause", other custom arguments that are passed 

635 to :meth:`.Session.get_bind`. 

636 

637 :param execution_options: a dictionary of execution options that will 

638 be passed to :meth:`_engine.Connection.execution_options`, **when the 

639 connection is first procured only**. If the connection is already 

640 present within the :class:`.Session`, a warning is emitted and 

641 the arguments are ignored. 

642 

643 .. seealso:: 

644 

645 :ref:`session_transaction_isolation` 

646 

647 

648 """ # noqa: E501 

649 

650 return self._proxied.connection( 

651 bind_arguments=bind_arguments, execution_options=execution_options 

652 ) 

653 

654 def delete(self, instance: object) -> None: 

655 r"""Mark an instance as deleted. 

656 

657 .. container:: class_bases 

658 

659 Proxied for the :class:`_orm.Session` class on 

660 behalf of the :class:`_orm.scoping.scoped_session` class. 

661 

662 The object is assumed to be either :term:`persistent` or 

663 :term:`detached` when passed; after the method is called, the 

664 object will remain in the :term:`persistent` state until the next 

665 flush proceeds. During this time, the object will also be a member 

666 of the :attr:`_orm.Session.deleted` collection. 

667 

668 When the next flush proceeds, the object will move to the 

669 :term:`deleted` state, indicating a ``DELETE`` statement was emitted 

670 for its row within the current transaction. When the transaction 

671 is successfully committed, 

672 the deleted object is moved to the :term:`detached` state and is 

673 no longer present within this :class:`_orm.Session`. 

674 

675 .. seealso:: 

676 

677 :ref:`session_deleting` - at :ref:`session_basics` 

678 

679 :meth:`.Session.delete_all` - multiple instance version 

680 

681 

682 """ # noqa: E501 

683 

684 return self._proxied.delete(instance) 

685 

686 def delete_all(self, instances: Iterable[object]) -> None: 

687 r"""Calls :meth:`.Session.delete` on multiple instances. 

688 

689 .. container:: class_bases 

690 

691 Proxied for the :class:`_orm.Session` class on 

692 behalf of the :class:`_orm.scoping.scoped_session` class. 

693 

694 .. seealso:: 

695 

696 :meth:`.Session.delete` - main documentation on delete 

697 

698 .. versionadded:: 2.1 

699 

700 

701 """ # noqa: E501 

702 

703 return self._proxied.delete_all(instances) 

704 

705 @overload 

706 def execute( 

707 self, 

708 statement: TypedReturnsRows[Unpack[_Ts]], 

709 params: Optional[_CoreAnyExecuteParams] = None, 

710 *, 

711 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

712 bind_arguments: Optional[_BindArguments] = None, 

713 _parent_execute_state: Optional[Any] = None, 

714 _add_event: Optional[Any] = None, 

715 ) -> Result[Unpack[_Ts]]: ... 

716 

717 @overload 

718 def execute( 

719 self, 

720 statement: Executable, 

721 params: Optional[_CoreAnyExecuteParams] = None, 

722 *, 

723 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

724 bind_arguments: Optional[_BindArguments] = None, 

725 _parent_execute_state: Optional[Any] = None, 

726 _add_event: Optional[Any] = None, 

727 ) -> Result[Unpack[TupleAny]]: ... 

728 

729 def execute( 

730 self, 

731 statement: Executable, 

732 params: Optional[_CoreAnyExecuteParams] = None, 

733 *, 

734 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

735 bind_arguments: Optional[_BindArguments] = None, 

736 _parent_execute_state: Optional[Any] = None, 

737 _add_event: Optional[Any] = None, 

738 ) -> Result[Unpack[TupleAny]]: 

739 r"""Execute a SQL expression construct. 

740 

741 .. container:: class_bases 

742 

743 Proxied for the :class:`_orm.Session` class on 

744 behalf of the :class:`_orm.scoping.scoped_session` class. 

745 

746 Returns a :class:`_engine.Result` object representing 

747 results of the statement execution. 

748 

749 E.g.:: 

750 

751 from sqlalchemy import select 

752 

753 result = session.execute(select(User).where(User.id == 5)) 

754 

755 The API contract of :meth:`_orm.Session.execute` is similar to that 

756 of :meth:`_engine.Connection.execute`, the :term:`2.0 style` version 

757 of :class:`_engine.Connection`. 

758 

759 .. versionchanged:: 1.4 the :meth:`_orm.Session.execute` method is 

760 now the primary point of ORM statement execution when using 

761 :term:`2.0 style` ORM usage. 

762 

763 :param statement: 

764 An executable statement (i.e. an :class:`.Executable` expression 

765 such as :func:`_expression.select`). 

766 

767 :param params: 

768 Optional dictionary, or list of dictionaries, containing 

769 bound parameter values. If a single dictionary, single-row 

770 execution occurs; if a list of dictionaries, an 

771 "executemany" will be invoked. The keys in each dictionary 

772 must correspond to parameter names present in the statement. 

773 

774 :param execution_options: optional dictionary of execution options, 

775 which will be associated with the statement execution. This 

776 dictionary can provide a subset of the options that are accepted 

777 by :meth:`_engine.Connection.execution_options`, and may also 

778 provide additional options understood only in an ORM context. 

779 

780 The execution_options are passed along to methods like 

781 :meth:`.Connection.execute` on :class:`.Connection` giving the 

782 highest priority to execution_options that are passed to this 

783 method explicitly, then the options that are present on the 

784 statement object if any, and finally those options present 

785 session-wide. 

786 

787 .. seealso:: 

788 

789 :ref:`orm_queryguide_execution_options` - ORM-specific execution 

790 options 

791 

792 :param bind_arguments: dictionary of additional arguments to determine 

793 the bind. May include "mapper", "bind", or other custom arguments. 

794 Contents of this dictionary are passed to the 

795 :meth:`.Session.get_bind` method. 

796 

797 :return: a :class:`_engine.Result` object. 

798 

799 

800 

801 """ # noqa: E501 

802 

803 return self._proxied.execute( 

804 statement, 

805 params=params, 

806 execution_options=execution_options, 

807 bind_arguments=bind_arguments, 

808 _parent_execute_state=_parent_execute_state, 

809 _add_event=_add_event, 

810 ) 

811 

812 def expire( 

813 self, instance: object, attribute_names: Optional[Iterable[str]] = None 

814 ) -> None: 

815 r"""Expire the attributes on an instance. 

816 

817 .. container:: class_bases 

818 

819 Proxied for the :class:`_orm.Session` class on 

820 behalf of the :class:`_orm.scoping.scoped_session` class. 

821 

822 Marks the attributes of an instance as out of date. When an expired 

823 attribute is next accessed, a query will be issued to the 

824 :class:`.Session` object's current transactional context in order to 

825 load all expired attributes for the given instance. Note that 

826 a highly isolated transaction will return the same values as were 

827 previously read in that same transaction, regardless of changes 

828 in database state outside of that transaction. 

829 

830 To expire all objects in the :class:`.Session` simultaneously, 

831 use :meth:`Session.expire_all`. 

832 

833 The :class:`.Session` object's default behavior is to 

834 expire all state whenever the :meth:`Session.rollback` 

835 or :meth:`Session.commit` methods are called, so that new 

836 state can be loaded for the new transaction. For this reason, 

837 calling :meth:`Session.expire` only makes sense for the specific 

838 case that a non-ORM SQL statement was emitted in the current 

839 transaction. 

840 

841 :param instance: The instance to be refreshed. 

842 :param attribute_names: optional list of string attribute names 

843 indicating a subset of attributes to be expired. 

844 

845 .. seealso:: 

846 

847 :ref:`session_expire` - introductory material 

848 

849 :meth:`.Session.expire` 

850 

851 :meth:`.Session.refresh` 

852 

853 :meth:`_orm.Query.populate_existing` 

854 

855 

856 """ # noqa: E501 

857 

858 return self._proxied.expire(instance, attribute_names=attribute_names) 

859 

860 def expire_all(self) -> None: 

861 r"""Expires all persistent instances within this Session. 

862 

863 .. container:: class_bases 

864 

865 Proxied for the :class:`_orm.Session` class on 

866 behalf of the :class:`_orm.scoping.scoped_session` class. 

867 

868 When any attributes on a persistent instance is next accessed, 

869 a query will be issued using the 

870 :class:`.Session` object's current transactional context in order to 

871 load all expired attributes for the given instance. Note that 

872 a highly isolated transaction will return the same values as were 

873 previously read in that same transaction, regardless of changes 

874 in database state outside of that transaction. 

875 

876 To expire individual objects and individual attributes 

877 on those objects, use :meth:`Session.expire`. 

878 

879 The :class:`.Session` object's default behavior is to 

880 expire all state whenever the :meth:`Session.rollback` 

881 or :meth:`Session.commit` methods are called, so that new 

882 state can be loaded for the new transaction. For this reason, 

883 calling :meth:`Session.expire_all` is not usually needed, 

884 assuming the transaction is isolated. 

885 

886 .. seealso:: 

887 

888 :ref:`session_expire` - introductory material 

889 

890 :meth:`.Session.expire` 

891 

892 :meth:`.Session.refresh` 

893 

894 :meth:`_orm.Query.populate_existing` 

895 

896 

897 """ # noqa: E501 

898 

899 return self._proxied.expire_all() 

900 

901 def expunge(self, instance: object) -> None: 

902 r"""Remove the `instance` from this ``Session``. 

903 

904 .. container:: class_bases 

905 

906 Proxied for the :class:`_orm.Session` class on 

907 behalf of the :class:`_orm.scoping.scoped_session` class. 

908 

909 This will free all internal references to the instance. Cascading 

910 will be applied according to the *expunge* cascade rule. 

911 

912 

913 """ # noqa: E501 

914 

915 return self._proxied.expunge(instance) 

916 

917 def expunge_all(self) -> None: 

918 r"""Remove all object instances from this ``Session``. 

919 

920 .. container:: class_bases 

921 

922 Proxied for the :class:`_orm.Session` class on 

923 behalf of the :class:`_orm.scoping.scoped_session` class. 

924 

925 This is equivalent to calling ``expunge(obj)`` on all objects in this 

926 ``Session``. 

927 

928 

929 """ # noqa: E501 

930 

931 return self._proxied.expunge_all() 

932 

933 def flush(self, objects: Optional[Sequence[Any]] = None) -> None: 

934 r"""Flush all the object changes to the database. 

935 

936 .. container:: class_bases 

937 

938 Proxied for the :class:`_orm.Session` class on 

939 behalf of the :class:`_orm.scoping.scoped_session` class. 

940 

941 Writes out all pending object creations, deletions and modifications 

942 to the database as INSERTs, DELETEs, UPDATEs, etc. Operations are 

943 automatically ordered by the Session's unit of work dependency 

944 solver. 

945 

946 Database operations will be issued in the current transactional 

947 context and do not affect the state of the transaction, unless an 

948 error occurs, in which case the entire transaction is rolled back. 

949 You may flush() as often as you like within a transaction to move 

950 changes from Python to the database's transaction buffer. 

951 

952 :param objects: Optional; restricts the flush operation to operate 

953 only on elements that are in the given collection. 

954 

955 This feature is for an extremely narrow set of use cases where 

956 particular objects may need to be operated upon before the 

957 full flush() occurs. It is not intended for general use. 

958 

959 .. deprecated:: 2.1 

960 

961 

962 """ # noqa: E501 

963 

964 return self._proxied.flush(objects=objects) 

965 

966 def get( 

967 self, 

968 entity: _EntityBindKey[_O], 

969 ident: _PKIdentityArgument, 

970 *, 

971 options: Optional[Sequence[ORMOption]] = None, 

972 populate_existing: bool = False, 

973 with_for_update: ForUpdateParameter = None, 

974 identity_token: Optional[Any] = None, 

975 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

976 bind_arguments: Optional[_BindArguments] = None, 

977 ) -> Optional[_O]: 

978 r"""Return an instance based on the given primary key identifier, 

979 or ``None`` if not found. 

980 

981 .. container:: class_bases 

982 

983 Proxied for the :class:`_orm.Session` class on 

984 behalf of the :class:`_orm.scoping.scoped_session` class. 

985 

986 E.g.:: 

987 

988 my_user = session.get(User, 5) 

989 

990 some_object = session.get(VersionedFoo, (5, 10)) 

991 

992 some_object = session.get(VersionedFoo, {"id": 5, "version_id": 10}) 

993 

994 .. versionadded:: 1.4 Added :meth:`_orm.Session.get`, which is moved 

995 from the now legacy :meth:`_orm.Query.get` method. 

996 

997 :meth:`_orm.Session.get` is special in that it provides direct 

998 access to the identity map of the :class:`.Session`. 

999 If the given primary key identifier is present 

1000 in the local identity map, the object is returned 

1001 directly from this collection and no SQL is emitted, 

1002 unless the object has been marked fully expired. 

1003 If not present, 

1004 a SELECT is performed in order to locate the object. 

1005 

1006 :meth:`_orm.Session.get` also will perform a check if 

1007 the object is present in the identity map and 

1008 marked as expired - a SELECT 

1009 is emitted to refresh the object as well as to 

1010 ensure that the row is still present. 

1011 If not, :class:`~sqlalchemy.orm.exc.ObjectDeletedError` is raised. 

1012 

1013 :param entity: a mapped class or :class:`.Mapper` indicating the 

1014 type of entity to be loaded. 

1015 

1016 :param ident: A scalar, tuple, or dictionary representing the 

1017 primary key. For a composite (e.g. multiple column) primary key, 

1018 a tuple or dictionary should be passed. 

1019 

1020 For a single-column primary key, the scalar calling form is typically 

1021 the most expedient. If the primary key of a row is the value "5", 

1022 the call looks like:: 

1023 

1024 my_object = session.get(SomeClass, 5) 

1025 

1026 The tuple form contains primary key values typically in 

1027 the order in which they correspond to the mapped 

1028 :class:`_schema.Table` 

1029 object's primary key columns, or if the 

1030 :paramref:`_orm.Mapper.primary_key` configuration parameter were 

1031 used, in 

1032 the order used for that parameter. For example, if the primary key 

1033 of a row is represented by the integer 

1034 digits "5, 10" the call would look like:: 

1035 

1036 my_object = session.get(SomeClass, (5, 10)) 

1037 

1038 The dictionary form should include as keys the mapped attribute names 

1039 corresponding to each element of the primary key. If the mapped class 

1040 has the attributes ``id``, ``version_id`` as the attributes which 

1041 store the object's primary key value, the call would look like:: 

1042 

1043 my_object = session.get(SomeClass, {"id": 5, "version_id": 10}) 

1044 

1045 :param options: optional sequence of loader options which will be 

1046 applied to the query, if one is emitted. 

1047 

1048 :param populate_existing: causes the method to unconditionally emit 

1049 a SQL query and refresh the object with the newly loaded data, 

1050 regardless of whether or not the object is already present. 

1051 

1052 :param with_for_update: optional boolean ``True`` indicating FOR UPDATE 

1053 should be used, or may be a dictionary containing flags to 

1054 indicate a more specific set of FOR UPDATE flags for the SELECT; 

1055 flags should match the parameters of 

1056 :meth:`_query.Query.with_for_update`. 

1057 Supersedes the :paramref:`.Session.refresh.lockmode` parameter. 

1058 

1059 :param execution_options: optional dictionary of execution options, 

1060 which will be associated with the query execution if one is emitted. 

1061 This dictionary can provide a subset of the options that are 

1062 accepted by :meth:`_engine.Connection.execution_options`, and may 

1063 also provide additional options understood only in an ORM context. 

1064 

1065 .. versionadded:: 1.4.29 

1066 

1067 .. seealso:: 

1068 

1069 :ref:`orm_queryguide_execution_options` - ORM-specific execution 

1070 options 

1071 

1072 :param bind_arguments: dictionary of additional arguments to determine 

1073 the bind. May include "mapper", "bind", or other custom arguments. 

1074 Contents of this dictionary are passed to the 

1075 :meth:`.Session.get_bind` method. 

1076 

1077 .. versionadded:: 2.0.0rc1 

1078 

1079 :return: The object instance, or ``None``. 

1080 

1081 

1082 """ # noqa: E501 

1083 

1084 return self._proxied.get( 

1085 entity, 

1086 ident, 

1087 options=options, 

1088 populate_existing=populate_existing, 

1089 with_for_update=with_for_update, 

1090 identity_token=identity_token, 

1091 execution_options=execution_options, 

1092 bind_arguments=bind_arguments, 

1093 ) 

1094 

1095 def get_one( 

1096 self, 

1097 entity: _EntityBindKey[_O], 

1098 ident: _PKIdentityArgument, 

1099 *, 

1100 options: Optional[Sequence[ORMOption]] = None, 

1101 populate_existing: bool = False, 

1102 with_for_update: ForUpdateParameter = None, 

1103 identity_token: Optional[Any] = None, 

1104 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1105 bind_arguments: Optional[_BindArguments] = None, 

1106 ) -> _O: 

1107 r"""Return exactly one instance based on the given primary key 

1108 identifier, or raise an exception if not found. 

1109 

1110 .. container:: class_bases 

1111 

1112 Proxied for the :class:`_orm.Session` class on 

1113 behalf of the :class:`_orm.scoping.scoped_session` class. 

1114 

1115 Raises :class:`_exc.NoResultFound` if the query selects no rows. 

1116 

1117 For a detailed documentation of the arguments see the 

1118 method :meth:`.Session.get`. 

1119 

1120 .. versionadded:: 2.0.22 

1121 

1122 :return: The object instance. 

1123 

1124 .. seealso:: 

1125 

1126 :meth:`.Session.get` - equivalent method that instead 

1127 returns ``None`` if no row was found with the provided primary 

1128 key 

1129 

1130 

1131 """ # noqa: E501 

1132 

1133 return self._proxied.get_one( 

1134 entity, 

1135 ident, 

1136 options=options, 

1137 populate_existing=populate_existing, 

1138 with_for_update=with_for_update, 

1139 identity_token=identity_token, 

1140 execution_options=execution_options, 

1141 bind_arguments=bind_arguments, 

1142 ) 

1143 

1144 def get_bind( 

1145 self, 

1146 mapper: Optional[_EntityBindKey[_O]] = None, 

1147 *, 

1148 clause: Optional[ClauseElement] = None, 

1149 bind: Optional[_SessionBind] = None, 

1150 _sa_skip_events: Optional[bool] = None, 

1151 _sa_skip_for_implicit_returning: bool = False, 

1152 **kw: Any, 

1153 ) -> Union[Engine, Connection]: 

1154 r"""Return a "bind" to which this :class:`.Session` is bound. 

1155 

1156 .. container:: class_bases 

1157 

1158 Proxied for the :class:`_orm.Session` class on 

1159 behalf of the :class:`_orm.scoping.scoped_session` class. 

1160 

1161 The "bind" is usually an instance of :class:`_engine.Engine`, 

1162 except in the case where the :class:`.Session` has been 

1163 explicitly bound directly to a :class:`_engine.Connection`. 

1164 

1165 For a multiply-bound or unbound :class:`.Session`, the 

1166 ``mapper`` or ``clause`` arguments are used to determine the 

1167 appropriate bind to return. 

1168 

1169 Note that the "mapper" argument is usually present 

1170 when :meth:`.Session.get_bind` is called via an ORM 

1171 operation such as a :meth:`.Session.query`, each 

1172 individual INSERT/UPDATE/DELETE operation within a 

1173 :meth:`.Session.flush`, call, etc. 

1174 

1175 The order of resolution is: 

1176 

1177 1. if mapper given and :paramref:`.Session.binds` is present, 

1178 locate a bind based first on the mapper in use, then 

1179 on the mapped class in use, then on any base classes that are 

1180 present in the ``__mro__`` of the mapped class, from more specific 

1181 superclasses to more general. 

1182 2. if clause given and ``Session.binds`` is present, 

1183 locate a bind based on :class:`_schema.Table` objects 

1184 found in the given clause present in ``Session.binds``. 

1185 3. if ``Session.binds`` is present, return that. 

1186 4. if clause given, attempt to return a bind 

1187 linked to the :class:`_schema.MetaData` ultimately 

1188 associated with the clause. 

1189 5. if mapper given, attempt to return a bind 

1190 linked to the :class:`_schema.MetaData` ultimately 

1191 associated with the :class:`_schema.Table` or other 

1192 selectable to which the mapper is mapped. 

1193 6. No bind can be found, :exc:`~sqlalchemy.exc.UnboundExecutionError` 

1194 is raised. 

1195 

1196 Note that the :meth:`.Session.get_bind` method can be overridden on 

1197 a user-defined subclass of :class:`.Session` to provide any kind 

1198 of bind resolution scheme. See the example at 

1199 :ref:`session_custom_partitioning`. 

1200 

1201 :param mapper: 

1202 Optional mapped class or corresponding :class:`_orm.Mapper` instance. 

1203 The bind can be derived from a :class:`_orm.Mapper` first by 

1204 consulting the "binds" map associated with this :class:`.Session`, 

1205 and secondly by consulting the :class:`_schema.MetaData` associated 

1206 with the :class:`_schema.Table` to which the :class:`_orm.Mapper` is 

1207 mapped for a bind. 

1208 

1209 :param clause: 

1210 A :class:`_expression.ClauseElement` (i.e. 

1211 :func:`_expression.select`, 

1212 :func:`_expression.text`, 

1213 etc.). If the ``mapper`` argument is not present or could not 

1214 produce a bind, the given expression construct will be searched 

1215 for a bound element, typically a :class:`_schema.Table` 

1216 associated with 

1217 bound :class:`_schema.MetaData`. 

1218 

1219 .. seealso:: 

1220 

1221 :ref:`session_partitioning` 

1222 

1223 :paramref:`.Session.binds` 

1224 

1225 :meth:`.Session.bind_mapper` 

1226 

1227 :meth:`.Session.bind_table` 

1228 

1229 

1230 """ # noqa: E501 

1231 

1232 return self._proxied.get_bind( 

1233 mapper=mapper, 

1234 clause=clause, 

1235 bind=bind, 

1236 _sa_skip_events=_sa_skip_events, 

1237 _sa_skip_for_implicit_returning=_sa_skip_for_implicit_returning, 

1238 **kw, 

1239 ) 

1240 

1241 def is_modified( 

1242 self, instance: object, include_collections: bool = True 

1243 ) -> bool: 

1244 r"""Return ``True`` if the given instance has locally 

1245 modified attributes. 

1246 

1247 .. container:: class_bases 

1248 

1249 Proxied for the :class:`_orm.Session` class on 

1250 behalf of the :class:`_orm.scoping.scoped_session` class. 

1251 

1252 This method retrieves the history for each instrumented 

1253 attribute on the instance and performs a comparison of the current 

1254 value to its previously flushed or committed value, if any. 

1255 

1256 It is in effect a more expensive and accurate 

1257 version of checking for the given instance in the 

1258 :attr:`.Session.dirty` collection; a full test for 

1259 each attribute's net "dirty" status is performed. 

1260 

1261 E.g.:: 

1262 

1263 return session.is_modified(someobject) 

1264 

1265 A few caveats to this method apply: 

1266 

1267 * Instances present in the :attr:`.Session.dirty` collection may 

1268 report ``False`` when tested with this method. This is because 

1269 the object may have received change events via attribute mutation, 

1270 thus placing it in :attr:`.Session.dirty`, but ultimately the state 

1271 is the same as that loaded from the database, resulting in no net 

1272 change here. 

1273 * Scalar attributes may not have recorded the previously set 

1274 value when a new value was applied, if the attribute was not loaded, 

1275 or was expired, at the time the new value was received - in these 

1276 cases, the attribute is assumed to have a change, even if there is 

1277 ultimately no net change against its database value. SQLAlchemy in 

1278 most cases does not need the "old" value when a set event occurs, so 

1279 it skips the expense of a SQL call if the old value isn't present, 

1280 based on the assumption that an UPDATE of the scalar value is 

1281 usually needed, and in those few cases where it isn't, is less 

1282 expensive on average than issuing a defensive SELECT. 

1283 

1284 The "old" value is fetched unconditionally upon set only if the 

1285 attribute container has the ``active_history`` flag set to ``True``. 

1286 This flag is set typically for primary key attributes and scalar 

1287 object references that are not a simple many-to-one. To set this 

1288 flag for any arbitrary mapped column, use the ``active_history`` 

1289 argument with :func:`.column_property`. 

1290 

1291 :param instance: mapped instance to be tested for pending changes. 

1292 :param include_collections: Indicates if multivalued collections 

1293 should be included in the operation. Setting this to ``False`` is a 

1294 way to detect only local-column based properties (i.e. scalar columns 

1295 or many-to-one foreign keys) that would result in an UPDATE for this 

1296 instance upon flush. 

1297 

1298 

1299 """ # noqa: E501 

1300 

1301 return self._proxied.is_modified( 

1302 instance, include_collections=include_collections 

1303 ) 

1304 

1305 def bulk_save_objects( 

1306 self, 

1307 objects: Iterable[object], 

1308 return_defaults: bool = False, 

1309 update_changed_only: bool = True, 

1310 preserve_order: bool = True, 

1311 ) -> None: 

1312 r"""Perform a bulk save of the given list of objects. 

1313 

1314 .. container:: class_bases 

1315 

1316 Proxied for the :class:`_orm.Session` class on 

1317 behalf of the :class:`_orm.scoping.scoped_session` class. 

1318 

1319 .. legacy:: 

1320 

1321 This method is a legacy feature as of the 2.0 series of 

1322 SQLAlchemy. For modern bulk INSERT and UPDATE, see 

1323 the sections :ref:`orm_queryguide_bulk_insert` and 

1324 :ref:`orm_queryguide_bulk_update`. 

1325 

1326 For general INSERT and UPDATE of existing ORM mapped objects, 

1327 prefer standard :term:`unit of work` data management patterns, 

1328 introduced in the :ref:`unified_tutorial` at 

1329 :ref:`tutorial_orm_data_manipulation`. SQLAlchemy 2.0 

1330 now uses :ref:`engine_insertmanyvalues` with modern dialects 

1331 which solves previous issues of bulk INSERT slowness. 

1332 

1333 :param objects: a sequence of mapped object instances. The mapped 

1334 objects are persisted as is, and are **not** associated with the 

1335 :class:`.Session` afterwards. 

1336 

1337 For each object, whether the object is sent as an INSERT or an 

1338 UPDATE is dependent on the same rules used by the :class:`.Session` 

1339 in traditional operation; if the object has the 

1340 :attr:`.InstanceState.key` 

1341 attribute set, then the object is assumed to be "detached" and 

1342 will result in an UPDATE. Otherwise, an INSERT is used. 

1343 

1344 In the case of an UPDATE, statements are grouped based on which 

1345 attributes have changed, and are thus to be the subject of each 

1346 SET clause. If ``update_changed_only`` is False, then all 

1347 attributes present within each object are applied to the UPDATE 

1348 statement, which may help in allowing the statements to be grouped 

1349 together into a larger executemany(), and will also reduce the 

1350 overhead of checking history on attributes. 

1351 

1352 :param return_defaults: when True, rows that are missing values which 

1353 generate defaults, namely integer primary key defaults and sequences, 

1354 will be inserted **one at a time**, so that the primary key value 

1355 is available. In particular this will allow joined-inheritance 

1356 and other multi-table mappings to insert correctly without the need 

1357 to provide primary key values ahead of time; however, 

1358 :paramref:`.Session.bulk_save_objects.return_defaults` **greatly 

1359 reduces the performance gains** of the method overall. It is strongly 

1360 advised to please use the standard :meth:`_orm.Session.add_all` 

1361 approach. 

1362 

1363 :param update_changed_only: when True, UPDATE statements are rendered 

1364 based on those attributes in each state that have logged changes. 

1365 When False, all attributes present are rendered into the SET clause 

1366 with the exception of primary key attributes. 

1367 

1368 :param preserve_order: when True, the order of inserts and updates 

1369 matches exactly the order in which the objects are given. When 

1370 False, common types of objects are grouped into inserts 

1371 and updates, to allow for more batching opportunities. 

1372 

1373 .. seealso:: 

1374 

1375 :doc:`queryguide/dml` 

1376 

1377 :meth:`.Session.bulk_insert_mappings` 

1378 

1379 :meth:`.Session.bulk_update_mappings` 

1380 

1381 

1382 """ # noqa: E501 

1383 

1384 return self._proxied.bulk_save_objects( 

1385 objects, 

1386 return_defaults=return_defaults, 

1387 update_changed_only=update_changed_only, 

1388 preserve_order=preserve_order, 

1389 ) 

1390 

1391 def bulk_insert_mappings( 

1392 self, 

1393 mapper: Mapper[Any], 

1394 mappings: Iterable[Dict[str, Any]], 

1395 return_defaults: bool = False, 

1396 render_nulls: bool = False, 

1397 ) -> None: 

1398 r"""Perform a bulk insert of the given list of mapping dictionaries. 

1399 

1400 .. container:: class_bases 

1401 

1402 Proxied for the :class:`_orm.Session` class on 

1403 behalf of the :class:`_orm.scoping.scoped_session` class. 

1404 

1405 .. legacy:: 

1406 

1407 This method is a legacy feature as of the 2.0 series of 

1408 SQLAlchemy. For modern bulk INSERT and UPDATE, see 

1409 the sections :ref:`orm_queryguide_bulk_insert` and 

1410 :ref:`orm_queryguide_bulk_update`. The 2.0 API shares 

1411 implementation details with this method and adds new features 

1412 as well. 

1413 

1414 :param mapper: a mapped class, or the actual :class:`_orm.Mapper` 

1415 object, 

1416 representing the single kind of object represented within the mapping 

1417 list. 

1418 

1419 :param mappings: a sequence of dictionaries, each one containing the 

1420 state of the mapped row to be inserted, in terms of the attribute 

1421 names on the mapped class. If the mapping refers to multiple tables, 

1422 such as a joined-inheritance mapping, each dictionary must contain all 

1423 keys to be populated into all tables. 

1424 

1425 :param return_defaults: when True, the INSERT process will be altered 

1426 to ensure that newly generated primary key values will be fetched. 

1427 The rationale for this parameter is typically to enable 

1428 :ref:`Joined Table Inheritance <joined_inheritance>` mappings to 

1429 be bulk inserted. 

1430 

1431 .. note:: for backends that don't support RETURNING, the 

1432 :paramref:`_orm.Session.bulk_insert_mappings.return_defaults` 

1433 parameter can significantly decrease performance as INSERT 

1434 statements can no longer be batched. See 

1435 :ref:`engine_insertmanyvalues` 

1436 for background on which backends are affected. 

1437 

1438 :param render_nulls: When True, a value of ``None`` will result 

1439 in a NULL value being included in the INSERT statement, rather 

1440 than the column being omitted from the INSERT. This allows all 

1441 the rows being INSERTed to have the identical set of columns which 

1442 allows the full set of rows to be batched to the DBAPI. Normally, 

1443 each column-set that contains a different combination of NULL values 

1444 than the previous row must omit a different series of columns from 

1445 the rendered INSERT statement, which means it must be emitted as a 

1446 separate statement. By passing this flag, the full set of rows 

1447 are guaranteed to be batchable into one batch; the cost however is 

1448 that server-side defaults which are invoked by an omitted column will 

1449 be skipped, so care must be taken to ensure that these are not 

1450 necessary. 

1451 

1452 .. warning:: 

1453 

1454 When this flag is set, **server side default SQL values will 

1455 not be invoked** for those columns that are inserted as NULL; 

1456 the NULL value will be sent explicitly. Care must be taken 

1457 to ensure that no server-side default functions need to be 

1458 invoked for the operation as a whole. 

1459 

1460 .. seealso:: 

1461 

1462 :doc:`queryguide/dml` 

1463 

1464 :meth:`.Session.bulk_save_objects` 

1465 

1466 :meth:`.Session.bulk_update_mappings` 

1467 

1468 

1469 """ # noqa: E501 

1470 

1471 return self._proxied.bulk_insert_mappings( 

1472 mapper, 

1473 mappings, 

1474 return_defaults=return_defaults, 

1475 render_nulls=render_nulls, 

1476 ) 

1477 

1478 def bulk_update_mappings( 

1479 self, mapper: Mapper[Any], mappings: Iterable[Dict[str, Any]] 

1480 ) -> None: 

1481 r"""Perform a bulk update of the given list of mapping dictionaries. 

1482 

1483 .. container:: class_bases 

1484 

1485 Proxied for the :class:`_orm.Session` class on 

1486 behalf of the :class:`_orm.scoping.scoped_session` class. 

1487 

1488 .. legacy:: 

1489 

1490 This method is a legacy feature as of the 2.0 series of 

1491 SQLAlchemy. For modern bulk INSERT and UPDATE, see 

1492 the sections :ref:`orm_queryguide_bulk_insert` and 

1493 :ref:`orm_queryguide_bulk_update`. The 2.0 API shares 

1494 implementation details with this method and adds new features 

1495 as well. 

1496 

1497 :param mapper: a mapped class, or the actual :class:`_orm.Mapper` 

1498 object, 

1499 representing the single kind of object represented within the mapping 

1500 list. 

1501 

1502 :param mappings: a sequence of dictionaries, each one containing the 

1503 state of the mapped row to be updated, in terms of the attribute names 

1504 on the mapped class. If the mapping refers to multiple tables, such 

1505 as a joined-inheritance mapping, each dictionary may contain keys 

1506 corresponding to all tables. All those keys which are present and 

1507 are not part of the primary key are applied to the SET clause of the 

1508 UPDATE statement; the primary key values, which are required, are 

1509 applied to the WHERE clause. 

1510 

1511 

1512 .. seealso:: 

1513 

1514 :doc:`queryguide/dml` 

1515 

1516 :meth:`.Session.bulk_insert_mappings` 

1517 

1518 :meth:`.Session.bulk_save_objects` 

1519 

1520 

1521 """ # noqa: E501 

1522 

1523 return self._proxied.bulk_update_mappings(mapper, mappings) 

1524 

1525 def merge( 

1526 self, 

1527 instance: _O, 

1528 *, 

1529 load: bool = True, 

1530 options: Optional[Sequence[ORMOption]] = None, 

1531 ) -> _O: 

1532 r"""Copy the state of a given instance into a corresponding instance 

1533 within this :class:`.Session`. 

1534 

1535 .. container:: class_bases 

1536 

1537 Proxied for the :class:`_orm.Session` class on 

1538 behalf of the :class:`_orm.scoping.scoped_session` class. 

1539 

1540 :meth:`.Session.merge` examines the primary key attributes of the 

1541 source instance, and attempts to reconcile it with an instance of the 

1542 same primary key in the session. If not found locally, it attempts 

1543 to load the object from the database based on primary key, and if 

1544 none can be located, creates a new instance. The state of each 

1545 attribute on the source instance is then copied to the target 

1546 instance. The resulting target instance is then returned by the 

1547 method; the original source instance is left unmodified, and 

1548 un-associated with the :class:`.Session` if not already. 

1549 

1550 This operation cascades to associated instances if the association is 

1551 mapped with ``cascade="merge"``. 

1552 

1553 See :ref:`unitofwork_merging` for a detailed discussion of merging. 

1554 

1555 :param instance: Instance to be merged. 

1556 :param load: Boolean, when False, :meth:`.merge` switches into 

1557 a "high performance" mode which causes it to forego emitting history 

1558 events as well as all database access. This flag is used for 

1559 cases such as transferring graphs of objects into a :class:`.Session` 

1560 from a second level cache, or to transfer just-loaded objects 

1561 into the :class:`.Session` owned by a worker thread or process 

1562 without re-querying the database. 

1563 

1564 The ``load=False`` use case adds the caveat that the given 

1565 object has to be in a "clean" state, that is, has no pending changes 

1566 to be flushed - even if the incoming object is detached from any 

1567 :class:`.Session`. This is so that when 

1568 the merge operation populates local attributes and 

1569 cascades to related objects and 

1570 collections, the values can be "stamped" onto the 

1571 target object as is, without generating any history or attribute 

1572 events, and without the need to reconcile the incoming data with 

1573 any existing related objects or collections that might not 

1574 be loaded. The resulting objects from ``load=False`` are always 

1575 produced as "clean", so it is only appropriate that the given objects 

1576 should be "clean" as well, else this suggests a mis-use of the 

1577 method. 

1578 :param options: optional sequence of loader options which will be 

1579 applied to the :meth:`_orm.Session.get` method when the merge 

1580 operation loads the existing version of the object from the database. 

1581 

1582 .. versionadded:: 1.4.24 

1583 

1584 

1585 .. seealso:: 

1586 

1587 :func:`.make_transient_to_detached` - provides for an alternative 

1588 means of "merging" a single object into the :class:`.Session` 

1589 

1590 :meth:`.Session.merge_all` - multiple instance version 

1591 

1592 

1593 """ # noqa: E501 

1594 

1595 return self._proxied.merge(instance, load=load, options=options) 

1596 

1597 def merge_all( 

1598 self, 

1599 instances: Iterable[_O], 

1600 *, 

1601 load: bool = True, 

1602 options: Optional[Sequence[ORMOption]] = None, 

1603 ) -> Sequence[_O]: 

1604 r"""Calls :meth:`.Session.merge` on multiple instances. 

1605 

1606 .. container:: class_bases 

1607 

1608 Proxied for the :class:`_orm.Session` class on 

1609 behalf of the :class:`_orm.scoping.scoped_session` class. 

1610 

1611 .. seealso:: 

1612 

1613 :meth:`.Session.merge` - main documentation on merge 

1614 

1615 .. versionadded:: 2.1 

1616 

1617 

1618 """ # noqa: E501 

1619 

1620 return self._proxied.merge_all(instances, load=load, options=options) 

1621 

1622 @overload 

1623 def query(self, _entity: _EntityType[_O]) -> Query[_O]: ... 

1624 

1625 @overload 

1626 def query( 

1627 self, _colexpr: TypedColumnsClauseRole[_T] 

1628 ) -> RowReturningQuery[_T]: ... 

1629 

1630 # START OVERLOADED FUNCTIONS self.query RowReturningQuery 2-8 

1631 

1632 # code within this block is **programmatically, 

1633 # statically generated** by tools/generate_tuple_map_overloads.py 

1634 

1635 @overload 

1636 def query( 

1637 self, __ent0: _TCCA[_T0], __ent1: _TCCA[_T1], / 

1638 ) -> RowReturningQuery[_T0, _T1]: ... 

1639 

1640 @overload 

1641 def query( 

1642 self, __ent0: _TCCA[_T0], __ent1: _TCCA[_T1], __ent2: _TCCA[_T2], / 

1643 ) -> RowReturningQuery[_T0, _T1, _T2]: ... 

1644 

1645 @overload 

1646 def query( 

1647 self, 

1648 __ent0: _TCCA[_T0], 

1649 __ent1: _TCCA[_T1], 

1650 __ent2: _TCCA[_T2], 

1651 __ent3: _TCCA[_T3], 

1652 /, 

1653 ) -> RowReturningQuery[_T0, _T1, _T2, _T3]: ... 

1654 

1655 @overload 

1656 def query( 

1657 self, 

1658 __ent0: _TCCA[_T0], 

1659 __ent1: _TCCA[_T1], 

1660 __ent2: _TCCA[_T2], 

1661 __ent3: _TCCA[_T3], 

1662 __ent4: _TCCA[_T4], 

1663 /, 

1664 ) -> RowReturningQuery[_T0, _T1, _T2, _T3, _T4]: ... 

1665 

1666 @overload 

1667 def query( 

1668 self, 

1669 __ent0: _TCCA[_T0], 

1670 __ent1: _TCCA[_T1], 

1671 __ent2: _TCCA[_T2], 

1672 __ent3: _TCCA[_T3], 

1673 __ent4: _TCCA[_T4], 

1674 __ent5: _TCCA[_T5], 

1675 /, 

1676 ) -> RowReturningQuery[_T0, _T1, _T2, _T3, _T4, _T5]: ... 

1677 

1678 @overload 

1679 def query( 

1680 self, 

1681 __ent0: _TCCA[_T0], 

1682 __ent1: _TCCA[_T1], 

1683 __ent2: _TCCA[_T2], 

1684 __ent3: _TCCA[_T3], 

1685 __ent4: _TCCA[_T4], 

1686 __ent5: _TCCA[_T5], 

1687 __ent6: _TCCA[_T6], 

1688 /, 

1689 ) -> RowReturningQuery[_T0, _T1, _T2, _T3, _T4, _T5, _T6]: ... 

1690 

1691 @overload 

1692 def query( 

1693 self, 

1694 __ent0: _TCCA[_T0], 

1695 __ent1: _TCCA[_T1], 

1696 __ent2: _TCCA[_T2], 

1697 __ent3: _TCCA[_T3], 

1698 __ent4: _TCCA[_T4], 

1699 __ent5: _TCCA[_T5], 

1700 __ent6: _TCCA[_T6], 

1701 __ent7: _TCCA[_T7], 

1702 /, 

1703 *entities: _ColumnsClauseArgument[Any], 

1704 ) -> RowReturningQuery[ 

1705 _T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, Unpack[TupleAny] 

1706 ]: ... 

1707 

1708 # END OVERLOADED FUNCTIONS self.query 

1709 

1710 @overload 

1711 def query( 

1712 self, *entities: _ColumnsClauseArgument[Any], **kwargs: Any 

1713 ) -> Query[Any]: ... 

1714 

1715 def query( 

1716 self, *entities: _ColumnsClauseArgument[Any], **kwargs: Any 

1717 ) -> Query[Any]: 

1718 r"""Return a new :class:`_query.Query` object corresponding to this 

1719 :class:`_orm.Session`. 

1720 

1721 .. container:: class_bases 

1722 

1723 Proxied for the :class:`_orm.Session` class on 

1724 behalf of the :class:`_orm.scoping.scoped_session` class. 

1725 

1726 Note that the :class:`_query.Query` object is legacy as of 

1727 SQLAlchemy 2.0; the :func:`_sql.select` construct is now used 

1728 to construct ORM queries. 

1729 

1730 .. seealso:: 

1731 

1732 :ref:`unified_tutorial` 

1733 

1734 :ref:`queryguide_toplevel` 

1735 

1736 :ref:`query_api_toplevel` - legacy API doc 

1737 

1738 

1739 """ # noqa: E501 

1740 

1741 return self._proxied.query(*entities, **kwargs) 

1742 

1743 def refresh( 

1744 self, 

1745 instance: object, 

1746 attribute_names: Optional[Iterable[str]] = None, 

1747 with_for_update: ForUpdateParameter = None, 

1748 ) -> None: 

1749 r"""Expire and refresh attributes on the given instance. 

1750 

1751 .. container:: class_bases 

1752 

1753 Proxied for the :class:`_orm.Session` class on 

1754 behalf of the :class:`_orm.scoping.scoped_session` class. 

1755 

1756 The selected attributes will first be expired as they would when using 

1757 :meth:`_orm.Session.expire`; then a SELECT statement will be issued to 

1758 the database to refresh column-oriented attributes with the current 

1759 value available in the current transaction. 

1760 

1761 :func:`_orm.relationship` oriented attributes will also be immediately 

1762 loaded if they were already eagerly loaded on the object, using the 

1763 same eager loading strategy that they were loaded with originally. 

1764 

1765 .. versionadded:: 1.4 - the :meth:`_orm.Session.refresh` method 

1766 can also refresh eagerly loaded attributes. 

1767 

1768 :func:`_orm.relationship` oriented attributes that would normally 

1769 load using the ``select`` (or "lazy") loader strategy will also 

1770 load **if they are named explicitly in the attribute_names 

1771 collection**, emitting a SELECT statement for the attribute using the 

1772 ``immediate`` loader strategy. If lazy-loaded relationships are not 

1773 named in :paramref:`_orm.Session.refresh.attribute_names`, then 

1774 they remain as "lazy loaded" attributes and are not implicitly 

1775 refreshed. 

1776 

1777 .. versionchanged:: 2.0.4 The :meth:`_orm.Session.refresh` method 

1778 will now refresh lazy-loaded :func:`_orm.relationship` oriented 

1779 attributes for those which are named explicitly in the 

1780 :paramref:`_orm.Session.refresh.attribute_names` collection. 

1781 

1782 .. tip:: 

1783 

1784 While the :meth:`_orm.Session.refresh` method is capable of 

1785 refreshing both column and relationship oriented attributes, its 

1786 primary focus is on refreshing of local column-oriented attributes 

1787 on a single instance. For more open ended "refresh" functionality, 

1788 including the ability to refresh the attributes on many objects at 

1789 once while having explicit control over relationship loader 

1790 strategies, use the 

1791 :ref:`populate existing <orm_queryguide_populate_existing>` feature 

1792 instead. 

1793 

1794 Note that a highly isolated transaction will return the same values as 

1795 were previously read in that same transaction, regardless of changes 

1796 in database state outside of that transaction. Refreshing 

1797 attributes usually only makes sense at the start of a transaction 

1798 where database rows have not yet been accessed. 

1799 

1800 :param attribute_names: optional. An iterable collection of 

1801 string attribute names indicating a subset of attributes to 

1802 be refreshed. 

1803 

1804 :param with_for_update: optional boolean ``True`` indicating FOR UPDATE 

1805 should be used, or may be a dictionary containing flags to 

1806 indicate a more specific set of FOR UPDATE flags for the SELECT; 

1807 flags should match the parameters of 

1808 :meth:`_query.Query.with_for_update`. 

1809 Supersedes the :paramref:`.Session.refresh.lockmode` parameter. 

1810 

1811 .. seealso:: 

1812 

1813 :ref:`session_expire` - introductory material 

1814 

1815 :meth:`.Session.expire` 

1816 

1817 :meth:`.Session.expire_all` 

1818 

1819 :ref:`orm_queryguide_populate_existing` - allows any ORM query 

1820 to refresh objects as they would be loaded normally. 

1821 

1822 

1823 """ # noqa: E501 

1824 

1825 return self._proxied.refresh( 

1826 instance, 

1827 attribute_names=attribute_names, 

1828 with_for_update=with_for_update, 

1829 ) 

1830 

1831 def rollback(self) -> None: 

1832 r"""Rollback the current transaction in progress. 

1833 

1834 .. container:: class_bases 

1835 

1836 Proxied for the :class:`_orm.Session` class on 

1837 behalf of the :class:`_orm.scoping.scoped_session` class. 

1838 

1839 If no transaction is in progress, this method is a pass-through. 

1840 

1841 The method always rolls back 

1842 the topmost database transaction, discarding any nested 

1843 transactions that may be in progress. 

1844 

1845 .. seealso:: 

1846 

1847 :ref:`session_rollback` 

1848 

1849 :ref:`unitofwork_transaction` 

1850 

1851 

1852 """ # noqa: E501 

1853 

1854 return self._proxied.rollback() 

1855 

1856 @overload 

1857 def scalar( 

1858 self, 

1859 statement: TypedReturnsRows[Never], 

1860 params: Optional[_CoreSingleExecuteParams] = None, 

1861 *, 

1862 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1863 bind_arguments: Optional[_BindArguments] = None, 

1864 **kw: Any, 

1865 ) -> Optional[Any]: ... 

1866 

1867 @overload 

1868 def scalar( 

1869 self, 

1870 statement: TypedReturnsRows[_T], 

1871 params: Optional[_CoreSingleExecuteParams] = None, 

1872 *, 

1873 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1874 bind_arguments: Optional[_BindArguments] = None, 

1875 **kw: Any, 

1876 ) -> Optional[_T]: ... 

1877 

1878 @overload 

1879 def scalar( 

1880 self, 

1881 statement: Executable, 

1882 params: Optional[_CoreSingleExecuteParams] = None, 

1883 *, 

1884 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1885 bind_arguments: Optional[_BindArguments] = None, 

1886 **kw: Any, 

1887 ) -> Any: ... 

1888 

1889 def scalar( 

1890 self, 

1891 statement: Executable, 

1892 params: Optional[_CoreSingleExecuteParams] = None, 

1893 *, 

1894 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1895 bind_arguments: Optional[_BindArguments] = None, 

1896 **kw: Any, 

1897 ) -> Any: 

1898 r"""Execute a statement and return a scalar result. 

1899 

1900 .. container:: class_bases 

1901 

1902 Proxied for the :class:`_orm.Session` class on 

1903 behalf of the :class:`_orm.scoping.scoped_session` class. 

1904 

1905 Usage and parameters are the same as that of 

1906 :meth:`_orm.Session.execute`; the return result is a scalar Python 

1907 value. 

1908 

1909 

1910 """ # noqa: E501 

1911 

1912 return self._proxied.scalar( 

1913 statement, 

1914 params=params, 

1915 execution_options=execution_options, 

1916 bind_arguments=bind_arguments, 

1917 **kw, 

1918 ) 

1919 

1920 @overload 

1921 def scalars( 

1922 self, 

1923 statement: TypedReturnsRows[_T], 

1924 params: Optional[_CoreAnyExecuteParams] = None, 

1925 *, 

1926 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1927 bind_arguments: Optional[_BindArguments] = None, 

1928 **kw: Any, 

1929 ) -> ScalarResult[_T]: ... 

1930 

1931 @overload 

1932 def scalars( 

1933 self, 

1934 statement: Executable, 

1935 params: Optional[_CoreAnyExecuteParams] = None, 

1936 *, 

1937 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1938 bind_arguments: Optional[_BindArguments] = None, 

1939 **kw: Any, 

1940 ) -> ScalarResult[Any]: ... 

1941 

1942 def scalars( 

1943 self, 

1944 statement: Executable, 

1945 params: Optional[_CoreAnyExecuteParams] = None, 

1946 *, 

1947 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1948 bind_arguments: Optional[_BindArguments] = None, 

1949 **kw: Any, 

1950 ) -> ScalarResult[Any]: 

1951 r"""Execute a statement and return the results as scalars. 

1952 

1953 .. container:: class_bases 

1954 

1955 Proxied for the :class:`_orm.Session` class on 

1956 behalf of the :class:`_orm.scoping.scoped_session` class. 

1957 

1958 Usage and parameters are the same as that of 

1959 :meth:`_orm.Session.execute`; the return result is a 

1960 :class:`_result.ScalarResult` filtering object which 

1961 will return single elements rather than :class:`_row.Row` objects. 

1962 

1963 :return: a :class:`_result.ScalarResult` object 

1964 

1965 .. versionadded:: 1.4.24 Added :meth:`_orm.Session.scalars` 

1966 

1967 .. versionadded:: 1.4.26 Added :meth:`_orm.scoped_session.scalars` 

1968 

1969 .. seealso:: 

1970 

1971 :ref:`orm_queryguide_select_orm_entities` - contrasts the behavior 

1972 of :meth:`_orm.Session.execute` to :meth:`_orm.Session.scalars` 

1973 

1974 

1975 """ # noqa: E501 

1976 

1977 return self._proxied.scalars( 

1978 statement, 

1979 params=params, 

1980 execution_options=execution_options, 

1981 bind_arguments=bind_arguments, 

1982 **kw, 

1983 ) 

1984 

1985 @property 

1986 def bind(self) -> Optional[Union[Engine, Connection]]: 

1987 r"""Proxy for the :attr:`_orm.Session.bind` attribute 

1988 on behalf of the :class:`_orm.scoping.scoped_session` class. 

1989 

1990 """ # noqa: E501 

1991 

1992 return self._proxied.bind 

1993 

1994 @bind.setter 

1995 def bind(self, attr: Optional[Union[Engine, Connection]]) -> None: 

1996 self._proxied.bind = attr 

1997 

1998 @property 

1999 def dirty(self) -> Any: 

2000 r"""The set of all persistent instances considered dirty. 

2001 

2002 .. container:: class_bases 

2003 

2004 Proxied for the :class:`_orm.Session` class 

2005 on behalf of the :class:`_orm.scoping.scoped_session` class. 

2006 

2007 E.g.:: 

2008 

2009 some_mapped_object in session.dirty 

2010 

2011 Instances are considered dirty when they were modified but not 

2012 deleted. 

2013 

2014 Note that this 'dirty' calculation is 'optimistic'; most 

2015 attribute-setting or collection modification operations will 

2016 mark an instance as 'dirty' and place it in this set, even if 

2017 there is no net change to the attribute's value. At flush 

2018 time, the value of each attribute is compared to its 

2019 previously saved value, and if there's no net change, no SQL 

2020 operation will occur (this is a more expensive operation so 

2021 it's only done at flush time). 

2022 

2023 To check if an instance has actionable net changes to its 

2024 attributes, use the :meth:`.Session.is_modified` method. 

2025 

2026 

2027 """ # noqa: E501 

2028 

2029 return self._proxied.dirty 

2030 

2031 @property 

2032 def deleted(self) -> Any: 

2033 r"""The set of all instances marked as 'deleted' within this ``Session`` 

2034 

2035 .. container:: class_bases 

2036 

2037 Proxied for the :class:`_orm.Session` class 

2038 on behalf of the :class:`_orm.scoping.scoped_session` class. 

2039 

2040 """ # noqa: E501 

2041 

2042 return self._proxied.deleted 

2043 

2044 @property 

2045 def new(self) -> Any: 

2046 r"""The set of all instances marked as 'new' within this ``Session``. 

2047 

2048 .. container:: class_bases 

2049 

2050 Proxied for the :class:`_orm.Session` class 

2051 on behalf of the :class:`_orm.scoping.scoped_session` class. 

2052 

2053 """ # noqa: E501 

2054 

2055 return self._proxied.new 

2056 

2057 @property 

2058 def identity_map(self) -> IdentityMap: 

2059 r"""Proxy for the :attr:`_orm.Session.identity_map` attribute 

2060 on behalf of the :class:`_orm.scoping.scoped_session` class. 

2061 

2062 """ # noqa: E501 

2063 

2064 return self._proxied.identity_map 

2065 

2066 @identity_map.setter 

2067 def identity_map(self, attr: IdentityMap) -> None: 

2068 self._proxied.identity_map = attr 

2069 

2070 @property 

2071 def is_active(self) -> Any: 

2072 r"""True if this :class:`.Session` not in "partial rollback" state. 

2073 

2074 .. container:: class_bases 

2075 

2076 Proxied for the :class:`_orm.Session` class 

2077 on behalf of the :class:`_orm.scoping.scoped_session` class. 

2078 

2079 .. versionchanged:: 1.4 The :class:`_orm.Session` no longer begins 

2080 a new transaction immediately, so this attribute will be False 

2081 when the :class:`_orm.Session` is first instantiated. 

2082 

2083 "partial rollback" state typically indicates that the flush process 

2084 of the :class:`_orm.Session` has failed, and that the 

2085 :meth:`_orm.Session.rollback` method must be emitted in order to 

2086 fully roll back the transaction. 

2087 

2088 If this :class:`_orm.Session` is not in a transaction at all, the 

2089 :class:`_orm.Session` will autobegin when it is first used, so in this 

2090 case :attr:`_orm.Session.is_active` will return True. 

2091 

2092 Otherwise, if this :class:`_orm.Session` is within a transaction, 

2093 and that transaction has not been rolled back internally, the 

2094 :attr:`_orm.Session.is_active` will also return True. 

2095 

2096 .. seealso:: 

2097 

2098 :ref:`faq_session_rollback` 

2099 

2100 :meth:`_orm.Session.in_transaction` 

2101 

2102 

2103 """ # noqa: E501 

2104 

2105 return self._proxied.is_active 

2106 

2107 @property 

2108 def autoflush(self) -> bool: 

2109 r"""Proxy for the :attr:`_orm.Session.autoflush` attribute 

2110 on behalf of the :class:`_orm.scoping.scoped_session` class. 

2111 

2112 """ # noqa: E501 

2113 

2114 return self._proxied.autoflush 

2115 

2116 @autoflush.setter 

2117 def autoflush(self, attr: bool) -> None: 

2118 self._proxied.autoflush = attr 

2119 

2120 @property 

2121 def no_autoflush(self) -> Any: 

2122 r"""Return a context manager that disables autoflush. 

2123 

2124 .. container:: class_bases 

2125 

2126 Proxied for the :class:`_orm.Session` class 

2127 on behalf of the :class:`_orm.scoping.scoped_session` class. 

2128 

2129 e.g.:: 

2130 

2131 with session.no_autoflush: 

2132 

2133 some_object = SomeClass() 

2134 session.add(some_object) 

2135 # won't autoflush 

2136 some_object.related_thing = session.query(SomeRelated).first() 

2137 

2138 Operations that proceed within the ``with:`` block 

2139 will not be subject to flushes occurring upon query 

2140 access. This is useful when initializing a series 

2141 of objects which involve existing database queries, 

2142 where the uncompleted object should not yet be flushed. 

2143 

2144 

2145 """ # noqa: E501 

2146 

2147 return self._proxied.no_autoflush 

2148 

2149 @property 

2150 def info(self) -> Any: 

2151 r"""A user-modifiable dictionary. 

2152 

2153 .. container:: class_bases 

2154 

2155 Proxied for the :class:`_orm.Session` class 

2156 on behalf of the :class:`_orm.scoping.scoped_session` class. 

2157 

2158 The initial value of this dictionary can be populated using the 

2159 ``info`` argument to the :class:`.Session` constructor or 

2160 :class:`.sessionmaker` constructor or factory methods. The dictionary 

2161 here is always local to this :class:`.Session` and can be modified 

2162 independently of all other :class:`.Session` objects. 

2163 

2164 

2165 """ # noqa: E501 

2166 

2167 return self._proxied.info 

2168 

2169 @property 

2170 def execution_options(self) -> _ExecuteOptions: 

2171 r"""Proxy for the :attr:`_orm.Session.execution_options` attribute 

2172 on behalf of the :class:`_orm.scoping.scoped_session` class. 

2173 

2174 """ # noqa: E501 

2175 

2176 return self._proxied.execution_options 

2177 

2178 @execution_options.setter 

2179 def execution_options(self, attr: _ExecuteOptions) -> None: 

2180 self._proxied.execution_options = attr 

2181 

2182 @classmethod 

2183 def object_session(cls, instance: object) -> Optional[Session]: 

2184 r"""Return the :class:`.Session` to which an object belongs. 

2185 

2186 .. container:: class_bases 

2187 

2188 Proxied for the :class:`_orm.Session` class on 

2189 behalf of the :class:`_orm.scoping.scoped_session` class. 

2190 

2191 This is an alias of :func:`.object_session`. 

2192 

2193 

2194 """ # noqa: E501 

2195 

2196 return Session.object_session(instance) 

2197 

2198 @classmethod 

2199 def identity_key( 

2200 cls, 

2201 class_: Optional[Type[Any]] = None, 

2202 ident: Union[Any, Tuple[Any, ...]] = None, 

2203 *, 

2204 instance: Optional[Any] = None, 

2205 row: Optional[Union[Row[Unpack[TupleAny]], RowMapping]] = None, 

2206 identity_token: Optional[Any] = None, 

2207 ) -> _IdentityKeyType[Any]: 

2208 r"""Return an identity key. 

2209 

2210 .. container:: class_bases 

2211 

2212 Proxied for the :class:`_orm.Session` class on 

2213 behalf of the :class:`_orm.scoping.scoped_session` class. 

2214 

2215 This is an alias of :func:`.util.identity_key`. 

2216 

2217 

2218 """ # noqa: E501 

2219 

2220 return Session.identity_key( 

2221 class_=class_, 

2222 ident=ident, 

2223 instance=instance, 

2224 row=row, 

2225 identity_token=identity_token, 

2226 ) 

2227 

2228 # END PROXY METHODS scoped_session 

2229 

2230 

2231ScopedSession = scoped_session 

2232"""Old name for backwards compatibility."""