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 | None = None, 

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 Setting this flag takes precedence over passing it as an 

1052 execution option. 

1053 

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

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

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

1057 flags should match the parameters of 

1058 :meth:`_query.Query.with_for_update`. 

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

1060 

1061 :param execution_options: optional dictionary of execution options, 

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

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

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

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

1066 

1067 .. versionadded:: 1.4.29 

1068 

1069 .. seealso:: 

1070 

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

1072 options 

1073 

1074 :param bind_arguments: dictionary of additional arguments to determine 

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

1076 Contents of this dictionary are passed to the 

1077 :meth:`.Session.get_bind` method. 

1078 

1079 .. versionadded:: 2.0.0rc1 

1080 

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

1082 

1083 

1084 """ # noqa: E501 

1085 

1086 return self._proxied.get( 

1087 entity, 

1088 ident, 

1089 options=options, 

1090 populate_existing=populate_existing, 

1091 with_for_update=with_for_update, 

1092 identity_token=identity_token, 

1093 execution_options=execution_options, 

1094 bind_arguments=bind_arguments, 

1095 ) 

1096 

1097 def get_one( 

1098 self, 

1099 entity: _EntityBindKey[_O], 

1100 ident: _PKIdentityArgument, 

1101 *, 

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

1103 populate_existing: bool | None = None, 

1104 with_for_update: ForUpdateParameter = None, 

1105 identity_token: Optional[Any] = None, 

1106 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1107 bind_arguments: Optional[_BindArguments] = None, 

1108 ) -> _O: 

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

1110 identifier, or raise an exception if not found. 

1111 

1112 .. container:: class_bases 

1113 

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

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

1116 

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

1118 

1119 For a detailed documentation of the arguments see the 

1120 method :meth:`.Session.get`. 

1121 

1122 .. versionadded:: 2.0.22 

1123 

1124 :return: The object instance. 

1125 

1126 .. seealso:: 

1127 

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

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

1130 key 

1131 

1132 

1133 """ # noqa: E501 

1134 

1135 return self._proxied.get_one( 

1136 entity, 

1137 ident, 

1138 options=options, 

1139 populate_existing=populate_existing, 

1140 with_for_update=with_for_update, 

1141 identity_token=identity_token, 

1142 execution_options=execution_options, 

1143 bind_arguments=bind_arguments, 

1144 ) 

1145 

1146 def get_bind( 

1147 self, 

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

1149 *, 

1150 clause: Optional[ClauseElement] = None, 

1151 bind: Optional[_SessionBind] = None, 

1152 _sa_skip_events: Optional[bool] = None, 

1153 _sa_skip_for_implicit_returning: bool = False, 

1154 **kw: Any, 

1155 ) -> Union[Engine, Connection]: 

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

1157 

1158 .. container:: class_bases 

1159 

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

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

1162 

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

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

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

1166 

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

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

1169 appropriate bind to return. 

1170 

1171 Note that the "mapper" argument is usually present 

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

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

1174 individual INSERT/UPDATE/DELETE operation within a 

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

1176 

1177 The order of resolution is: 

1178 

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

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

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

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

1183 superclasses to more general. 

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

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

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

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

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

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

1190 associated with the clause. 

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

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

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

1194 selectable to which the mapper is mapped. 

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

1196 is raised. 

1197 

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

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

1200 of bind resolution scheme. See the example at 

1201 :ref:`session_custom_partitioning`. 

1202 

1203 :param mapper: 

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

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

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

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

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

1209 mapped for a bind. 

1210 

1211 :param clause: 

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

1213 :func:`_expression.select`, 

1214 :func:`_expression.text`, 

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

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

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

1218 associated with 

1219 bound :class:`_schema.MetaData`. 

1220 

1221 .. seealso:: 

1222 

1223 :ref:`session_partitioning` 

1224 

1225 :paramref:`.Session.binds` 

1226 

1227 :meth:`.Session.bind_mapper` 

1228 

1229 :meth:`.Session.bind_table` 

1230 

1231 

1232 """ # noqa: E501 

1233 

1234 return self._proxied.get_bind( 

1235 mapper=mapper, 

1236 clause=clause, 

1237 bind=bind, 

1238 _sa_skip_events=_sa_skip_events, 

1239 _sa_skip_for_implicit_returning=_sa_skip_for_implicit_returning, 

1240 **kw, 

1241 ) 

1242 

1243 def is_modified( 

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

1245 ) -> bool: 

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

1247 modified attributes. 

1248 

1249 .. container:: class_bases 

1250 

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

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

1253 

1254 This method retrieves the history for each instrumented 

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

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

1257 

1258 It is in effect a more expensive and accurate 

1259 version of checking for the given instance in the 

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

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

1262 

1263 E.g.:: 

1264 

1265 return session.is_modified(someobject) 

1266 

1267 A few caveats to this method apply: 

1268 

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

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

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

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

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

1274 change here. 

1275 * Scalar attributes may not have recorded the previously set 

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

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

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

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

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

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

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

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

1284 expensive on average than issuing a defensive SELECT. 

1285 

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

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

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

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

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

1291 argument with :func:`.column_property`. 

1292 

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

1294 :param include_collections: Indicates if multivalued collections 

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

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

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

1298 instance upon flush. 

1299 

1300 

1301 """ # noqa: E501 

1302 

1303 return self._proxied.is_modified( 

1304 instance, include_collections=include_collections 

1305 ) 

1306 

1307 def bulk_save_objects( 

1308 self, 

1309 objects: Iterable[object], 

1310 return_defaults: bool = False, 

1311 update_changed_only: bool = True, 

1312 preserve_order: bool = True, 

1313 ) -> None: 

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

1315 

1316 .. container:: class_bases 

1317 

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

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

1320 

1321 .. legacy:: 

1322 

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

1324 SQLAlchemy. For modern bulk INSERT and UPDATE, see 

1325 the sections :ref:`orm_queryguide_bulk_insert` and 

1326 :ref:`orm_queryguide_bulk_update`. 

1327 

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

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

1330 introduced in the :ref:`unified_tutorial` at 

1331 :ref:`tutorial_orm_data_manipulation`. SQLAlchemy 2.0 

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

1333 which solves previous issues of bulk INSERT slowness. 

1334 

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

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

1337 :class:`.Session` afterwards. 

1338 

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

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

1341 in traditional operation; if the object has the 

1342 :attr:`.InstanceState.key` 

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

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

1345 

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

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

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

1349 attributes present within each object are applied to the UPDATE 

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

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

1352 overhead of checking history on attributes. 

1353 

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

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

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

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

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

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

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

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

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

1363 approach. 

1364 

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

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

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

1368 with the exception of primary key attributes. 

1369 

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

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

1372 False, common types of objects are grouped into inserts 

1373 and updates, to allow for more batching opportunities. 

1374 

1375 .. seealso:: 

1376 

1377 :doc:`queryguide/dml` 

1378 

1379 :meth:`.Session.bulk_insert_mappings` 

1380 

1381 :meth:`.Session.bulk_update_mappings` 

1382 

1383 

1384 """ # noqa: E501 

1385 

1386 return self._proxied.bulk_save_objects( 

1387 objects, 

1388 return_defaults=return_defaults, 

1389 update_changed_only=update_changed_only, 

1390 preserve_order=preserve_order, 

1391 ) 

1392 

1393 def bulk_insert_mappings( 

1394 self, 

1395 mapper: Mapper[Any], 

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

1397 return_defaults: bool = False, 

1398 render_nulls: bool = False, 

1399 ) -> None: 

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

1401 

1402 .. container:: class_bases 

1403 

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

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

1406 

1407 .. legacy:: 

1408 

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

1410 SQLAlchemy. For modern bulk INSERT and UPDATE, see 

1411 the sections :ref:`orm_queryguide_bulk_insert` and 

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

1413 implementation details with this method and adds new features 

1414 as well. 

1415 

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

1417 object, 

1418 representing the single kind of object represented within the mapping 

1419 list. 

1420 

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

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

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

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

1425 keys to be populated into all tables. 

1426 

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

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

1429 The rationale for this parameter is typically to enable 

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

1431 be bulk inserted. 

1432 

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

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

1435 parameter can significantly decrease performance as INSERT 

1436 statements can no longer be batched. See 

1437 :ref:`engine_insertmanyvalues` 

1438 for background on which backends are affected. 

1439 

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

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

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

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

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

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

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

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

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

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

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

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

1452 necessary. 

1453 

1454 .. warning:: 

1455 

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

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

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

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

1460 invoked for the operation as a whole. 

1461 

1462 .. seealso:: 

1463 

1464 :doc:`queryguide/dml` 

1465 

1466 :meth:`.Session.bulk_save_objects` 

1467 

1468 :meth:`.Session.bulk_update_mappings` 

1469 

1470 

1471 """ # noqa: E501 

1472 

1473 return self._proxied.bulk_insert_mappings( 

1474 mapper, 

1475 mappings, 

1476 return_defaults=return_defaults, 

1477 render_nulls=render_nulls, 

1478 ) 

1479 

1480 def bulk_update_mappings( 

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

1482 ) -> None: 

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

1484 

1485 .. container:: class_bases 

1486 

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

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

1489 

1490 .. legacy:: 

1491 

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

1493 SQLAlchemy. For modern bulk INSERT and UPDATE, see 

1494 the sections :ref:`orm_queryguide_bulk_insert` and 

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

1496 implementation details with this method and adds new features 

1497 as well. 

1498 

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

1500 object, 

1501 representing the single kind of object represented within the mapping 

1502 list. 

1503 

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

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

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

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

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

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

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

1511 applied to the WHERE clause. 

1512 

1513 

1514 .. seealso:: 

1515 

1516 :doc:`queryguide/dml` 

1517 

1518 :meth:`.Session.bulk_insert_mappings` 

1519 

1520 :meth:`.Session.bulk_save_objects` 

1521 

1522 

1523 """ # noqa: E501 

1524 

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

1526 

1527 def merge( 

1528 self, 

1529 instance: _O, 

1530 *, 

1531 load: bool = True, 

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

1533 ) -> _O: 

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

1535 within this :class:`.Session`. 

1536 

1537 .. container:: class_bases 

1538 

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

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

1541 

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

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

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

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

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

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

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

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

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

1551 

1552 This operation cascades to associated instances if the association is 

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

1554 

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

1556 

1557 :param instance: Instance to be merged. 

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

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

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

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

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

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

1564 without re-querying the database. 

1565 

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

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

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

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

1570 the merge operation populates local attributes and 

1571 cascades to related objects and 

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

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

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

1575 any existing related objects or collections that might not 

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

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

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

1579 method. 

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

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

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

1583 

1584 .. versionadded:: 1.4.24 

1585 

1586 

1587 .. seealso:: 

1588 

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

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

1591 

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

1593 

1594 

1595 """ # noqa: E501 

1596 

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

1598 

1599 def merge_all( 

1600 self, 

1601 instances: Iterable[_O], 

1602 *, 

1603 load: bool = True, 

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

1605 ) -> Sequence[_O]: 

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

1607 

1608 .. container:: class_bases 

1609 

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

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

1612 

1613 .. seealso:: 

1614 

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

1616 

1617 .. versionadded:: 2.1 

1618 

1619 

1620 """ # noqa: E501 

1621 

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

1623 

1624 @overload 

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

1626 

1627 @overload 

1628 def query( 

1629 self, _colexpr: TypedColumnsClauseRole[_T] 

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

1631 

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

1633 

1634 # code within this block is **programmatically, 

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

1636 

1637 @overload 

1638 def query( 

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

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

1641 

1642 @overload 

1643 def query( 

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

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

1646 

1647 @overload 

1648 def query( 

1649 self, 

1650 __ent0: _TCCA[_T0], 

1651 __ent1: _TCCA[_T1], 

1652 __ent2: _TCCA[_T2], 

1653 __ent3: _TCCA[_T3], 

1654 /, 

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

1656 

1657 @overload 

1658 def query( 

1659 self, 

1660 __ent0: _TCCA[_T0], 

1661 __ent1: _TCCA[_T1], 

1662 __ent2: _TCCA[_T2], 

1663 __ent3: _TCCA[_T3], 

1664 __ent4: _TCCA[_T4], 

1665 /, 

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

1667 

1668 @overload 

1669 def query( 

1670 self, 

1671 __ent0: _TCCA[_T0], 

1672 __ent1: _TCCA[_T1], 

1673 __ent2: _TCCA[_T2], 

1674 __ent3: _TCCA[_T3], 

1675 __ent4: _TCCA[_T4], 

1676 __ent5: _TCCA[_T5], 

1677 /, 

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

1679 

1680 @overload 

1681 def query( 

1682 self, 

1683 __ent0: _TCCA[_T0], 

1684 __ent1: _TCCA[_T1], 

1685 __ent2: _TCCA[_T2], 

1686 __ent3: _TCCA[_T3], 

1687 __ent4: _TCCA[_T4], 

1688 __ent5: _TCCA[_T5], 

1689 __ent6: _TCCA[_T6], 

1690 /, 

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

1692 

1693 @overload 

1694 def query( 

1695 self, 

1696 __ent0: _TCCA[_T0], 

1697 __ent1: _TCCA[_T1], 

1698 __ent2: _TCCA[_T2], 

1699 __ent3: _TCCA[_T3], 

1700 __ent4: _TCCA[_T4], 

1701 __ent5: _TCCA[_T5], 

1702 __ent6: _TCCA[_T6], 

1703 __ent7: _TCCA[_T7], 

1704 /, 

1705 *entities: _ColumnsClauseArgument[Any], 

1706 ) -> RowReturningQuery[ 

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

1708 ]: ... 

1709 

1710 # END OVERLOADED FUNCTIONS self.query 

1711 

1712 @overload 

1713 def query( 

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

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

1716 

1717 def query( 

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

1719 ) -> Query[Any]: 

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

1721 :class:`_orm.Session`. 

1722 

1723 .. container:: class_bases 

1724 

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

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

1727 

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

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

1730 to construct ORM queries. 

1731 

1732 .. seealso:: 

1733 

1734 :ref:`unified_tutorial` 

1735 

1736 :ref:`queryguide_toplevel` 

1737 

1738 :ref:`query_api_toplevel` - legacy API doc 

1739 

1740 

1741 """ # noqa: E501 

1742 

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

1744 

1745 def refresh( 

1746 self, 

1747 instance: object, 

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

1749 with_for_update: ForUpdateParameter = None, 

1750 ) -> None: 

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

1752 

1753 .. container:: class_bases 

1754 

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

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

1757 

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

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

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

1761 value available in the current transaction. 

1762 

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

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

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

1766 

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

1768 can also refresh eagerly loaded attributes. 

1769 

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

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

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

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

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

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

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

1777 refreshed. 

1778 

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

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

1781 attributes for those which are named explicitly in the 

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

1783 

1784 .. tip:: 

1785 

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

1787 refreshing both column and relationship oriented attributes, its 

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

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

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

1791 once while having explicit control over relationship loader 

1792 strategies, use the 

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

1794 instead. 

1795 

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

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

1798 in database state outside of that transaction. Refreshing 

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

1800 where database rows have not yet been accessed. 

1801 

1802 :param attribute_names: optional. An iterable collection of 

1803 string attribute names indicating a subset of attributes to 

1804 be refreshed. 

1805 

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

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

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

1809 flags should match the parameters of 

1810 :meth:`_query.Query.with_for_update`. 

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

1812 

1813 .. seealso:: 

1814 

1815 :ref:`session_expire` - introductory material 

1816 

1817 :meth:`.Session.expire` 

1818 

1819 :meth:`.Session.expire_all` 

1820 

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

1822 to refresh objects as they would be loaded normally. 

1823 

1824 

1825 """ # noqa: E501 

1826 

1827 return self._proxied.refresh( 

1828 instance, 

1829 attribute_names=attribute_names, 

1830 with_for_update=with_for_update, 

1831 ) 

1832 

1833 def rollback(self) -> None: 

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

1835 

1836 .. container:: class_bases 

1837 

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

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

1840 

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

1842 

1843 The method always rolls back 

1844 the topmost database transaction, discarding any nested 

1845 transactions that may be in progress. 

1846 

1847 .. seealso:: 

1848 

1849 :ref:`session_rollback` 

1850 

1851 :ref:`unitofwork_transaction` 

1852 

1853 

1854 """ # noqa: E501 

1855 

1856 return self._proxied.rollback() 

1857 

1858 @overload 

1859 def scalar( 

1860 self, 

1861 statement: TypedReturnsRows[Never], 

1862 params: Optional[_CoreSingleExecuteParams] = None, 

1863 *, 

1864 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1865 bind_arguments: Optional[_BindArguments] = None, 

1866 **kw: Any, 

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

1868 

1869 @overload 

1870 def scalar( 

1871 self, 

1872 statement: TypedReturnsRows[_T], 

1873 params: Optional[_CoreSingleExecuteParams] = None, 

1874 *, 

1875 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1876 bind_arguments: Optional[_BindArguments] = None, 

1877 **kw: Any, 

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

1879 

1880 @overload 

1881 def scalar( 

1882 self, 

1883 statement: Executable, 

1884 params: Optional[_CoreSingleExecuteParams] = None, 

1885 *, 

1886 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1887 bind_arguments: Optional[_BindArguments] = None, 

1888 **kw: Any, 

1889 ) -> Any: ... 

1890 

1891 def scalar( 

1892 self, 

1893 statement: Executable, 

1894 params: Optional[_CoreSingleExecuteParams] = None, 

1895 *, 

1896 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1897 bind_arguments: Optional[_BindArguments] = None, 

1898 **kw: Any, 

1899 ) -> Any: 

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

1901 

1902 .. container:: class_bases 

1903 

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

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

1906 

1907 Usage and parameters are the same as that of 

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

1909 value. 

1910 

1911 

1912 """ # noqa: E501 

1913 

1914 return self._proxied.scalar( 

1915 statement, 

1916 params=params, 

1917 execution_options=execution_options, 

1918 bind_arguments=bind_arguments, 

1919 **kw, 

1920 ) 

1921 

1922 @overload 

1923 def scalars( 

1924 self, 

1925 statement: TypedReturnsRows[_T], 

1926 params: Optional[_CoreAnyExecuteParams] = None, 

1927 *, 

1928 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1929 bind_arguments: Optional[_BindArguments] = None, 

1930 **kw: Any, 

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

1932 

1933 @overload 

1934 def scalars( 

1935 self, 

1936 statement: Executable, 

1937 params: Optional[_CoreAnyExecuteParams] = None, 

1938 *, 

1939 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1940 bind_arguments: Optional[_BindArguments] = None, 

1941 **kw: Any, 

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

1943 

1944 def scalars( 

1945 self, 

1946 statement: Executable, 

1947 params: Optional[_CoreAnyExecuteParams] = None, 

1948 *, 

1949 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1950 bind_arguments: Optional[_BindArguments] = None, 

1951 **kw: Any, 

1952 ) -> ScalarResult[Any]: 

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

1954 

1955 .. container:: class_bases 

1956 

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

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

1959 

1960 Usage and parameters are the same as that of 

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

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

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

1964 

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

1966 

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

1968 

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

1970 

1971 .. seealso:: 

1972 

1973 :ref:`orm_queryguide_select_orm_entities` - contrasts the behavior 

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

1975 

1976 

1977 """ # noqa: E501 

1978 

1979 return self._proxied.scalars( 

1980 statement, 

1981 params=params, 

1982 execution_options=execution_options, 

1983 bind_arguments=bind_arguments, 

1984 **kw, 

1985 ) 

1986 

1987 @property 

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

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

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

1991 

1992 """ # noqa: E501 

1993 

1994 return self._proxied.bind 

1995 

1996 @bind.setter 

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

1998 self._proxied.bind = attr 

1999 

2000 @property 

2001 def dirty(self) -> Any: 

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

2003 

2004 .. container:: class_bases 

2005 

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

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

2008 

2009 E.g.:: 

2010 

2011 some_mapped_object in session.dirty 

2012 

2013 Instances are considered dirty when they were modified but not 

2014 deleted. 

2015 

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

2017 attribute-setting or collection modification operations will 

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

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

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

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

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

2023 it's only done at flush time). 

2024 

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

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

2027 

2028 

2029 """ # noqa: E501 

2030 

2031 return self._proxied.dirty 

2032 

2033 @property 

2034 def deleted(self) -> Any: 

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

2036 

2037 .. container:: class_bases 

2038 

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

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

2041 

2042 """ # noqa: E501 

2043 

2044 return self._proxied.deleted 

2045 

2046 @property 

2047 def new(self) -> Any: 

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

2049 

2050 .. container:: class_bases 

2051 

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

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

2054 

2055 """ # noqa: E501 

2056 

2057 return self._proxied.new 

2058 

2059 @property 

2060 def identity_map(self) -> IdentityMap: 

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

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

2063 

2064 """ # noqa: E501 

2065 

2066 return self._proxied.identity_map 

2067 

2068 @identity_map.setter 

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

2070 self._proxied.identity_map = attr 

2071 

2072 @property 

2073 def is_active(self) -> Any: 

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

2075 

2076 .. container:: class_bases 

2077 

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

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

2080 

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

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

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

2084 

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

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

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

2088 fully roll back the transaction. 

2089 

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

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

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

2093 

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

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

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

2097 

2098 .. seealso:: 

2099 

2100 :ref:`faq_session_rollback` 

2101 

2102 :meth:`_orm.Session.in_transaction` 

2103 

2104 

2105 """ # noqa: E501 

2106 

2107 return self._proxied.is_active 

2108 

2109 @property 

2110 def autoflush(self) -> bool: 

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

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

2113 

2114 """ # noqa: E501 

2115 

2116 return self._proxied.autoflush 

2117 

2118 @autoflush.setter 

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

2120 self._proxied.autoflush = attr 

2121 

2122 @property 

2123 def no_autoflush(self) -> Any: 

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

2125 

2126 .. container:: class_bases 

2127 

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

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

2130 

2131 e.g.:: 

2132 

2133 with session.no_autoflush: 

2134 

2135 some_object = SomeClass() 

2136 session.add(some_object) 

2137 # won't autoflush 

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

2139 

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

2141 will not be subject to flushes occurring upon query 

2142 access. This is useful when initializing a series 

2143 of objects which involve existing database queries, 

2144 where the uncompleted object should not yet be flushed. 

2145 

2146 

2147 """ # noqa: E501 

2148 

2149 return self._proxied.no_autoflush 

2150 

2151 @property 

2152 def info(self) -> Any: 

2153 r"""A user-modifiable dictionary. 

2154 

2155 .. container:: class_bases 

2156 

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

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

2159 

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

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

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

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

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

2165 

2166 

2167 """ # noqa: E501 

2168 

2169 return self._proxied.info 

2170 

2171 @property 

2172 def execution_options(self) -> _ExecuteOptions: 

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

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

2175 

2176 """ # noqa: E501 

2177 

2178 return self._proxied.execution_options 

2179 

2180 @execution_options.setter 

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

2182 self._proxied.execution_options = attr 

2183 

2184 @classmethod 

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

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

2187 

2188 .. container:: class_bases 

2189 

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

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

2192 

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

2194 

2195 

2196 """ # noqa: E501 

2197 

2198 return Session.object_session(instance) 

2199 

2200 @classmethod 

2201 def identity_key( 

2202 cls, 

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

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

2205 *, 

2206 instance: Optional[Any] = None, 

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

2208 identity_token: Optional[Any] = None, 

2209 ) -> _IdentityKeyType[Any]: 

2210 r"""Return an identity key. 

2211 

2212 .. container:: class_bases 

2213 

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

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

2216 

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

2218 

2219 

2220 """ # noqa: E501 

2221 

2222 return Session.identity_key( 

2223 class_=class_, 

2224 ident=ident, 

2225 instance=instance, 

2226 row=row, 

2227 identity_token=identity_token, 

2228 ) 

2229 

2230 # END PROXY METHODS scoped_session 

2231 

2232 

2233ScopedSession = scoped_session 

2234"""Old name for backwards compatibility."""