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

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

252 statements  

1# orm/scoping.py 

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

3# <see AUTHORS file> 

4# 

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

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

7 

8from __future__ import annotations 

9 

10from typing import Any 

11from typing import Callable 

12from typing import Dict 

13from typing import Generic 

14from typing import Iterable 

15from typing import Iterator 

16from typing import Optional 

17from typing import overload 

18from typing import Sequence 

19from typing import Tuple 

20from typing import Type 

21from typing import TYPE_CHECKING 

22from typing import TypeVar 

23from typing import Union 

24 

25from .session import _S 

26from .session import Session 

27from .. import exc as sa_exc 

28from .. import util 

29from ..util import create_proxy_methods 

30from ..util import ScopedRegistry 

31from ..util import ThreadLocalRegistry 

32from ..util import warn 

33from ..util import warn_deprecated 

34from ..util.typing import Protocol 

35 

36if TYPE_CHECKING: 

37 from ._typing import _EntityType 

38 from ._typing import _IdentityKeyType 

39 from ._typing import OrmExecuteOptionsParameter 

40 from .identity import IdentityMap 

41 from .interfaces import ORMOption 

42 from .mapper import Mapper 

43 from .query import Query 

44 from .query import RowReturningQuery 

45 from .session import _BindArguments 

46 from .session import _EntityBindKey 

47 from .session import _PKIdentityArgument 

48 from .session import _SessionBind 

49 from .session import sessionmaker 

50 from .session import SessionTransaction 

51 from ..engine import Connection 

52 from ..engine import CursorResult 

53 from ..engine import Engine 

54 from ..engine import Result 

55 from ..engine import Row 

56 from ..engine import RowMapping 

57 from ..engine.interfaces import _CoreAnyExecuteParams 

58 from ..engine.interfaces import _CoreSingleExecuteParams 

59 from ..engine.interfaces import CoreExecuteOptionsParameter 

60 from ..engine.result import ScalarResult 

61 from ..sql._typing import _ColumnsClauseArgument 

62 from ..sql._typing import _T0 

63 from ..sql._typing import _T1 

64 from ..sql._typing import _T2 

65 from ..sql._typing import _T3 

66 from ..sql._typing import _T4 

67 from ..sql._typing import _T5 

68 from ..sql._typing import _T6 

69 from ..sql._typing import _T7 

70 from ..sql._typing import _TypedColumnClauseArgument as _TCCA 

71 from ..sql.base import Executable 

72 from ..sql.dml import UpdateBase 

73 from ..sql.elements import ClauseElement 

74 from ..sql.roles import TypedColumnsClauseRole 

75 from ..sql.selectable import ForUpdateParameter 

76 from ..sql.selectable import TypedReturnsRows 

77 

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

79 

80 

81class QueryPropertyDescriptor(Protocol): 

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

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

84 

85 .. versionadded:: 2.0.5 

86 

87 """ 

88 

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

90 

91 

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

93 

94__all__ = ["scoped_session"] 

95 

96 

97@create_proxy_methods( 

98 Session, 

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

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

101 classmethods=["close_all", "object_session", "identity_key"], 

102 methods=[ 

103 "__contains__", 

104 "__iter__", 

105 "add", 

106 "add_all", 

107 "begin", 

108 "begin_nested", 

109 "close", 

110 "reset", 

111 "commit", 

112 "connection", 

113 "delete", 

114 "execute", 

115 "expire", 

116 "expire_all", 

117 "expunge", 

118 "expunge_all", 

119 "flush", 

120 "get", 

121 "get_one", 

122 "get_bind", 

123 "is_modified", 

124 "bulk_save_objects", 

125 "bulk_insert_mappings", 

126 "bulk_update_mappings", 

127 "merge", 

128 "query", 

129 "refresh", 

130 "rollback", 

131 "scalar", 

132 "scalars", 

133 ], 

134 attributes=[ 

135 "bind", 

136 "dirty", 

137 "deleted", 

138 "new", 

139 "identity_map", 

140 "is_active", 

141 "autoflush", 

142 "no_autoflush", 

143 "info", 

144 ], 

145) 

146class scoped_session(Generic[_S]): 

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

148 

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

150 

151 .. note:: 

152 

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

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

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

156 

157 """ 

158 

159 _support_async: bool = False 

160 

161 session_factory: sessionmaker[_S] 

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

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

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

165 

166 registry: ScopedRegistry[_S] 

167 

168 def __init__( 

169 self, 

170 session_factory: sessionmaker[_S], 

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

172 ): 

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

174 

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

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

177 of :class:`.sessionmaker`. 

178 :param scopefunc: optional function which defines 

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

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

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

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

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

184 dictionary in order to store and retrieve the current 

185 :class:`.Session`. 

186 

187 """ 

188 self.session_factory = session_factory 

189 

190 if scopefunc: 

191 self.registry = ScopedRegistry(session_factory, scopefunc) 

192 else: 

193 self.registry = ThreadLocalRegistry(session_factory) 

194 

195 @property 

196 def _proxied(self) -> _S: 

197 return self.registry() 

198 

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

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

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

202 

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

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

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

206 and keyword arguments have been passed, 

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

208 

209 """ 

210 if kw: 

211 if self.registry.has(): 

212 raise sa_exc.InvalidRequestError( 

213 "Scoped session is already present; " 

214 "no new arguments may be specified." 

215 ) 

216 else: 

217 sess = self.session_factory(**kw) 

218 self.registry.set(sess) 

219 else: 

220 sess = self.registry() 

221 if not self._support_async and sess._is_asyncio: 

222 warn_deprecated( 

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

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

225 "Please use `async_scoped_session` instead.", 

226 "1.4.23", 

227 ) 

228 return sess 

229 

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

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

232 :class:`.scoped_session`. 

233 

234 See :meth:`.sessionmaker.configure`. 

235 

236 """ 

237 

238 if self.registry.has(): 

239 warn( 

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

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

242 "already been created." 

243 ) 

244 

245 self.session_factory.configure(**kwargs) 

246 

247 def remove(self) -> None: 

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

249 

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

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

252 transactional/connection resources still being held; transactions 

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

254 discarded. Upon next usage within the same scope, 

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

256 :class:`.Session` object. 

257 

258 """ 

259 

260 if self.registry.has(): 

261 self.registry().close() 

262 self.registry.clear() 

263 

264 def query_property( 

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

266 ) -> QueryPropertyDescriptor: 

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

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

269 :class:`.Session` when called. 

270 

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

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

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

274 

275 e.g.:: 

276 

277 from sqlalchemy.orm import QueryPropertyDescriptor 

278 from sqlalchemy.orm import scoped_session 

279 from sqlalchemy.orm import sessionmaker 

280 

281 Session = scoped_session(sessionmaker()) 

282 

283 

284 class MyClass: 

285 query: QueryPropertyDescriptor = Session.query_property() 

286 

287 

288 # after mappers are defined 

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

290 

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

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

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

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

295 keyword argument. 

296 

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

298 a class. 

299 

300 """ 

301 

302 class query: 

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

304 if query_cls: 

305 # custom query class 

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

307 else: 

308 # session's configured query class 

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

310 

311 return query() 

312 

313 # START PROXY METHODS scoped_session 

314 

315 # code within this block is **programmatically, 

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

317 

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

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

320 

321 .. container:: class_bases 

322 

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

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

325 

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

327 result of True. 

328 

329 

330 """ # noqa: E501 

331 

332 return self._proxied.__contains__(instance) 

333 

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

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

336 Session. 

337 

338 .. container:: class_bases 

339 

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

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

342 

343 

344 """ # noqa: E501 

345 

346 return self._proxied.__iter__() 

347 

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

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

350 

351 .. container:: class_bases 

352 

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

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

355 

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

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

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

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

360 

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

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

363 state directly. 

364 

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

366 objects which were transient when they were passed to 

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

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

369 :class:`_orm.Session`. 

370 

371 .. seealso:: 

372 

373 :meth:`_orm.Session.add_all` 

374 

375 :ref:`session_adding` - at :ref:`session_basics` 

376 

377 

378 """ # noqa: E501 

379 

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

381 

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

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

384 

385 .. container:: class_bases 

386 

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

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

389 

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

391 behavioral description. 

392 

393 .. seealso:: 

394 

395 :meth:`_orm.Session.add` 

396 

397 :ref:`session_adding` - at :ref:`session_basics` 

398 

399 

400 """ # noqa: E501 

401 

402 return self._proxied.add_all(instances) 

403 

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

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

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

407 

408 .. container:: class_bases 

409 

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

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

412 

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

414 so that normally it is not necessary to call the 

415 :meth:`_orm.Session.begin` 

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

417 the scope of when the transactional state is begun. 

418 

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

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

421 

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

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

424 documentation on SAVEPOINT transactions, please see 

425 :ref:`session_begin_nested`. 

426 

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

428 :class:`.SessionTransaction` 

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

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

431 an example. 

432 

433 .. seealso:: 

434 

435 :ref:`session_autobegin` 

436 

437 :ref:`unitofwork_transaction` 

438 

439 :meth:`.Session.begin_nested` 

440 

441 

442 

443 """ # noqa: E501 

444 

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

446 

447 def begin_nested(self) -> SessionTransaction: 

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

449 

450 .. container:: class_bases 

451 

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

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

454 

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

456 SAVEPOINT for this method to function correctly. 

457 

458 For documentation on SAVEPOINT 

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

460 

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

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

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

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

465 

466 .. seealso:: 

467 

468 :ref:`session_begin_nested` 

469 

470 :ref:`pysqlite_serializable` - special workarounds required 

471 with the SQLite driver in order for SAVEPOINT to work 

472 correctly. For asyncio use cases, see the section 

473 :ref:`aiosqlite_serializable`. 

474 

475 

476 """ # noqa: E501 

477 

478 return self._proxied.begin_nested() 

479 

480 def close(self) -> None: 

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

482 :class:`_orm.Session`. 

483 

484 .. container:: class_bases 

485 

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

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

488 

489 This expunges all ORM objects associated with this 

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

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

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

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

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

495 

496 .. tip:: 

497 

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

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

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

501 distinct "closed" state; it merely means 

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

503 and ORM objects. 

504 

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

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

507 any further action on the session will be forbidden. 

508 

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

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

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

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

513 

514 .. seealso:: 

515 

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

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

518 

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

520 ``close()`` with the parameter 

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

522 

523 

524 """ # noqa: E501 

525 

526 return self._proxied.close() 

527 

528 def reset(self) -> None: 

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

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

531 

532 .. container:: class_bases 

533 

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

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

536 

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

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

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

540 brand new, and ready to be used again. 

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

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

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

544 

545 .. versionadded:: 2.0.22 

546 

547 .. seealso:: 

548 

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

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

551 

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

553 prevent re-use of the Session when the parameter 

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

555 

556 """ # noqa: E501 

557 

558 return self._proxied.reset() 

559 

560 def commit(self) -> None: 

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

562 

563 .. container:: class_bases 

564 

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

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

567 

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

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

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

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

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

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

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

575 to disable this behavior. 

576 

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

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

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

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

581 normally affect the database unless pending flush changes were 

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

583 rules. 

584 

585 The outermost database transaction is committed unconditionally, 

586 automatically releasing any SAVEPOINTs in effect. 

587 

588 .. seealso:: 

589 

590 :ref:`session_committing` 

591 

592 :ref:`unitofwork_transaction` 

593 

594 :ref:`asyncio_orm_avoid_lazyloads` 

595 

596 

597 """ # noqa: E501 

598 

599 return self._proxied.commit() 

600 

601 def connection( 

602 self, 

603 bind_arguments: Optional[_BindArguments] = None, 

604 execution_options: Optional[CoreExecuteOptionsParameter] = None, 

605 ) -> Connection: 

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

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

608 

609 .. container:: class_bases 

610 

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

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

613 

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

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

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

617 returned (note that no 

618 transactional state is established with the DBAPI until the first 

619 SQL statement is emitted). 

620 

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

622 resolved through any of the optional keyword arguments. This 

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

624 

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

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

627 to :meth:`.Session.get_bind`. 

628 

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

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

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

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

633 the arguments are ignored. 

634 

635 .. seealso:: 

636 

637 :ref:`session_transaction_isolation` 

638 

639 

640 """ # noqa: E501 

641 

642 return self._proxied.connection( 

643 bind_arguments=bind_arguments, execution_options=execution_options 

644 ) 

645 

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

647 r"""Mark an instance as deleted. 

648 

649 .. container:: class_bases 

650 

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

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

653 

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

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

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

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

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

659 

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

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

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

663 is successfully committed, 

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

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

666 

667 .. seealso:: 

668 

669 :ref:`session_deleting` - at :ref:`session_basics` 

670 

671 

672 """ # noqa: E501 

673 

674 return self._proxied.delete(instance) 

675 

676 @overload 

677 def execute( 

678 self, 

679 statement: TypedReturnsRows[_T], 

680 params: Optional[_CoreAnyExecuteParams] = None, 

681 *, 

682 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

683 bind_arguments: Optional[_BindArguments] = None, 

684 _parent_execute_state: Optional[Any] = None, 

685 _add_event: Optional[Any] = None, 

686 ) -> Result[_T]: ... 

687 

688 @overload 

689 def execute( 

690 self, 

691 statement: UpdateBase, 

692 params: Optional[_CoreAnyExecuteParams] = None, 

693 *, 

694 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

695 bind_arguments: Optional[_BindArguments] = None, 

696 _parent_execute_state: Optional[Any] = None, 

697 _add_event: Optional[Any] = None, 

698 ) -> CursorResult[Any]: ... 

699 

700 @overload 

701 def execute( 

702 self, 

703 statement: Executable, 

704 params: Optional[_CoreAnyExecuteParams] = None, 

705 *, 

706 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

707 bind_arguments: Optional[_BindArguments] = None, 

708 _parent_execute_state: Optional[Any] = None, 

709 _add_event: Optional[Any] = None, 

710 ) -> Result[Any]: ... 

711 

712 def execute( 

713 self, 

714 statement: Executable, 

715 params: Optional[_CoreAnyExecuteParams] = None, 

716 *, 

717 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

718 bind_arguments: Optional[_BindArguments] = None, 

719 _parent_execute_state: Optional[Any] = None, 

720 _add_event: Optional[Any] = None, 

721 ) -> Result[Any]: 

722 r"""Execute a SQL expression construct. 

723 

724 .. container:: class_bases 

725 

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

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

728 

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

730 results of the statement execution. 

731 

732 E.g.:: 

733 

734 from sqlalchemy import select 

735 

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

737 

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

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

740 of :class:`_engine.Connection`. 

741 

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

743 now the primary point of ORM statement execution when using 

744 :term:`2.0 style` ORM usage. 

745 

746 :param statement: 

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

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

749 

750 :param params: 

751 Optional dictionary, or list of dictionaries, containing 

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

753 execution occurs; if a list of dictionaries, an 

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

755 must correspond to parameter names present in the statement. 

756 

757 :param execution_options: optional dictionary of execution options, 

758 which will be associated with the statement execution. This 

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

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

761 provide additional options understood only in an ORM context. 

762 

763 .. seealso:: 

764 

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

766 options 

767 

768 :param bind_arguments: dictionary of additional arguments to determine 

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

770 Contents of this dictionary are passed to the 

771 :meth:`.Session.get_bind` method. 

772 

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

774 

775 

776 

777 """ # noqa: E501 

778 

779 return self._proxied.execute( 

780 statement, 

781 params=params, 

782 execution_options=execution_options, 

783 bind_arguments=bind_arguments, 

784 _parent_execute_state=_parent_execute_state, 

785 _add_event=_add_event, 

786 ) 

787 

788 def expire( 

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

790 ) -> None: 

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

792 

793 .. container:: class_bases 

794 

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

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

797 

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

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

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

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

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

803 previously read in that same transaction, regardless of changes 

804 in database state outside of that transaction. 

805 

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

807 use :meth:`Session.expire_all`. 

808 

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

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

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

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

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

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

815 transaction. 

816 

817 :param instance: The instance to be refreshed. 

818 :param attribute_names: optional list of string attribute names 

819 indicating a subset of attributes to be expired. 

820 

821 .. seealso:: 

822 

823 :ref:`session_expire` - introductory material 

824 

825 :meth:`.Session.expire` 

826 

827 :meth:`.Session.refresh` 

828 

829 :meth:`_orm.Query.populate_existing` 

830 

831 

832 """ # noqa: E501 

833 

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

835 

836 def expire_all(self) -> None: 

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

838 

839 .. container:: class_bases 

840 

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

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

843 

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

845 a query will be issued using the 

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

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

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

849 previously read in that same transaction, regardless of changes 

850 in database state outside of that transaction. 

851 

852 To expire individual objects and individual attributes 

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

854 

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

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

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

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

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

860 assuming the transaction is isolated. 

861 

862 .. seealso:: 

863 

864 :ref:`session_expire` - introductory material 

865 

866 :meth:`.Session.expire` 

867 

868 :meth:`.Session.refresh` 

869 

870 :meth:`_orm.Query.populate_existing` 

871 

872 

873 """ # noqa: E501 

874 

875 return self._proxied.expire_all() 

876 

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

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

879 

880 .. container:: class_bases 

881 

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

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

884 

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

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

887 

888 

889 """ # noqa: E501 

890 

891 return self._proxied.expunge(instance) 

892 

893 def expunge_all(self) -> None: 

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

895 

896 .. container:: class_bases 

897 

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

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

900 

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

902 ``Session``. 

903 

904 

905 """ # noqa: E501 

906 

907 return self._proxied.expunge_all() 

908 

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

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

911 

912 .. container:: class_bases 

913 

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

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

916 

917 Writes out all pending object creations, deletions and modifications 

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

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

920 solver. 

921 

922 Database operations will be issued in the current transactional 

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

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

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

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

927 

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

929 only on elements that are in the given collection. 

930 

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

932 particular objects may need to be operated upon before the 

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

934 

935 

936 """ # noqa: E501 

937 

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

939 

940 def get( 

941 self, 

942 entity: _EntityBindKey[_O], 

943 ident: _PKIdentityArgument, 

944 *, 

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

946 populate_existing: bool = False, 

947 with_for_update: ForUpdateParameter = None, 

948 identity_token: Optional[Any] = None, 

949 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

950 bind_arguments: Optional[_BindArguments] = None, 

951 ) -> Optional[_O]: 

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

953 or ``None`` if not found. 

954 

955 .. container:: class_bases 

956 

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

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

959 

960 E.g.:: 

961 

962 my_user = session.get(User, 5) 

963 

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

965 

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

967 

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

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

970 

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

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

973 If the given primary key identifier is present 

974 in the local identity map, the object is returned 

975 directly from this collection and no SQL is emitted, 

976 unless the object has been marked fully expired. 

977 If not present, 

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

979 

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

981 the object is present in the identity map and 

982 marked as expired - a SELECT 

983 is emitted to refresh the object as well as to 

984 ensure that the row is still present. 

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

986 

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

988 type of entity to be loaded. 

989 

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

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

992 a tuple or dictionary should be passed. 

993 

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

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

996 the call looks like:: 

997 

998 my_object = session.get(SomeClass, 5) 

999 

1000 The tuple form contains primary key values typically in 

1001 the order in which they correspond to the mapped 

1002 :class:`_schema.Table` 

1003 object's primary key columns, or if the 

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

1005 used, in 

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

1007 of a row is represented by the integer 

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

1009 

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

1011 

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

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

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

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

1016 

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

1018 

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

1020 applied to the query, if one is emitted. 

1021 

1022 :param populate_existing: causes the method to unconditionally emit 

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

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

1025 

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

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

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

1029 flags should match the parameters of 

1030 :meth:`_query.Query.with_for_update`. 

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

1032 

1033 :param execution_options: optional dictionary of execution options, 

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

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

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

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

1038 

1039 .. versionadded:: 1.4.29 

1040 

1041 .. seealso:: 

1042 

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

1044 options 

1045 

1046 :param bind_arguments: dictionary of additional arguments to determine 

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

1048 Contents of this dictionary are passed to the 

1049 :meth:`.Session.get_bind` method. 

1050 

1051 .. versionadded: 2.0.0rc1 

1052 

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

1054 

1055 

1056 """ # noqa: E501 

1057 

1058 return self._proxied.get( 

1059 entity, 

1060 ident, 

1061 options=options, 

1062 populate_existing=populate_existing, 

1063 with_for_update=with_for_update, 

1064 identity_token=identity_token, 

1065 execution_options=execution_options, 

1066 bind_arguments=bind_arguments, 

1067 ) 

1068 

1069 def get_one( 

1070 self, 

1071 entity: _EntityBindKey[_O], 

1072 ident: _PKIdentityArgument, 

1073 *, 

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

1075 populate_existing: bool = False, 

1076 with_for_update: ForUpdateParameter = None, 

1077 identity_token: Optional[Any] = None, 

1078 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1079 bind_arguments: Optional[_BindArguments] = None, 

1080 ) -> _O: 

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

1082 identifier, or raise an exception if not found. 

1083 

1084 .. container:: class_bases 

1085 

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

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

1088 

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

1090 

1091 For a detailed documentation of the arguments see the 

1092 method :meth:`.Session.get`. 

1093 

1094 .. versionadded:: 2.0.22 

1095 

1096 :return: The object instance. 

1097 

1098 .. seealso:: 

1099 

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

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

1102 key 

1103 

1104 

1105 """ # noqa: E501 

1106 

1107 return self._proxied.get_one( 

1108 entity, 

1109 ident, 

1110 options=options, 

1111 populate_existing=populate_existing, 

1112 with_for_update=with_for_update, 

1113 identity_token=identity_token, 

1114 execution_options=execution_options, 

1115 bind_arguments=bind_arguments, 

1116 ) 

1117 

1118 def get_bind( 

1119 self, 

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

1121 *, 

1122 clause: Optional[ClauseElement] = None, 

1123 bind: Optional[_SessionBind] = None, 

1124 _sa_skip_events: Optional[bool] = None, 

1125 _sa_skip_for_implicit_returning: bool = False, 

1126 **kw: Any, 

1127 ) -> Union[Engine, Connection]: 

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

1129 

1130 .. container:: class_bases 

1131 

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

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

1134 

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

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

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

1138 

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

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

1141 appropriate bind to return. 

1142 

1143 Note that the "mapper" argument is usually present 

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

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

1146 individual INSERT/UPDATE/DELETE operation within a 

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

1148 

1149 The order of resolution is: 

1150 

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

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

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

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

1155 superclasses to more general. 

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

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

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

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

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

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

1162 associated with the clause. 

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

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

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

1166 selectable to which the mapper is mapped. 

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

1168 is raised. 

1169 

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

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

1172 of bind resolution scheme. See the example at 

1173 :ref:`session_custom_partitioning`. 

1174 

1175 :param mapper: 

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

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

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

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

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

1181 mapped for a bind. 

1182 

1183 :param clause: 

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

1185 :func:`_expression.select`, 

1186 :func:`_expression.text`, 

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

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

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

1190 associated with 

1191 bound :class:`_schema.MetaData`. 

1192 

1193 .. seealso:: 

1194 

1195 :ref:`session_partitioning` 

1196 

1197 :paramref:`.Session.binds` 

1198 

1199 :meth:`.Session.bind_mapper` 

1200 

1201 :meth:`.Session.bind_table` 

1202 

1203 

1204 """ # noqa: E501 

1205 

1206 return self._proxied.get_bind( 

1207 mapper=mapper, 

1208 clause=clause, 

1209 bind=bind, 

1210 _sa_skip_events=_sa_skip_events, 

1211 _sa_skip_for_implicit_returning=_sa_skip_for_implicit_returning, 

1212 **kw, 

1213 ) 

1214 

1215 def is_modified( 

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

1217 ) -> bool: 

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

1219 modified attributes. 

1220 

1221 .. container:: class_bases 

1222 

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

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

1225 

1226 This method retrieves the history for each instrumented 

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

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

1229 

1230 It is in effect a more expensive and accurate 

1231 version of checking for the given instance in the 

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

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

1234 

1235 E.g.:: 

1236 

1237 return session.is_modified(someobject) 

1238 

1239 A few caveats to this method apply: 

1240 

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

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

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

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

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

1246 change here. 

1247 * Scalar attributes may not have recorded the previously set 

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

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

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

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

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

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

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

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

1256 expensive on average than issuing a defensive SELECT. 

1257 

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

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

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

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

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

1263 argument with :func:`.column_property`. 

1264 

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

1266 :param include_collections: Indicates if multivalued collections 

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

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

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

1270 instance upon flush. 

1271 

1272 

1273 """ # noqa: E501 

1274 

1275 return self._proxied.is_modified( 

1276 instance, include_collections=include_collections 

1277 ) 

1278 

1279 def bulk_save_objects( 

1280 self, 

1281 objects: Iterable[object], 

1282 return_defaults: bool = False, 

1283 update_changed_only: bool = True, 

1284 preserve_order: bool = True, 

1285 ) -> None: 

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

1287 

1288 .. container:: class_bases 

1289 

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

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

1292 

1293 .. legacy:: 

1294 

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

1296 SQLAlchemy. For modern bulk INSERT and UPDATE, see 

1297 the sections :ref:`orm_queryguide_bulk_insert` and 

1298 :ref:`orm_queryguide_bulk_update`. 

1299 

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

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

1302 introduced in the :ref:`unified_tutorial` at 

1303 :ref:`tutorial_orm_data_manipulation`. SQLAlchemy 2.0 

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

1305 which solves previous issues of bulk INSERT slowness. 

1306 

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

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

1309 :class:`.Session` afterwards. 

1310 

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

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

1313 in traditional operation; if the object has the 

1314 :attr:`.InstanceState.key` 

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

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

1317 

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

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

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

1321 attributes present within each object are applied to the UPDATE 

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

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

1324 overhead of checking history on attributes. 

1325 

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

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

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

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

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

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

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

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

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

1335 approach. 

1336 

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

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

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

1340 with the exception of primary key attributes. 

1341 

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

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

1344 False, common types of objects are grouped into inserts 

1345 and updates, to allow for more batching opportunities. 

1346 

1347 .. seealso:: 

1348 

1349 :doc:`queryguide/dml` 

1350 

1351 :meth:`.Session.bulk_insert_mappings` 

1352 

1353 :meth:`.Session.bulk_update_mappings` 

1354 

1355 

1356 """ # noqa: E501 

1357 

1358 return self._proxied.bulk_save_objects( 

1359 objects, 

1360 return_defaults=return_defaults, 

1361 update_changed_only=update_changed_only, 

1362 preserve_order=preserve_order, 

1363 ) 

1364 

1365 def bulk_insert_mappings( 

1366 self, 

1367 mapper: Mapper[Any], 

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

1369 return_defaults: bool = False, 

1370 render_nulls: bool = False, 

1371 ) -> None: 

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

1373 

1374 .. container:: class_bases 

1375 

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

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

1378 

1379 .. legacy:: 

1380 

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

1382 SQLAlchemy. For modern bulk INSERT and UPDATE, see 

1383 the sections :ref:`orm_queryguide_bulk_insert` and 

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

1385 implementation details with this method and adds new features 

1386 as well. 

1387 

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

1389 object, 

1390 representing the single kind of object represented within the mapping 

1391 list. 

1392 

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

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

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

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

1397 keys to be populated into all tables. 

1398 

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

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

1401 The rationale for this parameter is typically to enable 

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

1403 be bulk inserted. 

1404 

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

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

1407 parameter can significantly decrease performance as INSERT 

1408 statements can no longer be batched. See 

1409 :ref:`engine_insertmanyvalues` 

1410 for background on which backends are affected. 

1411 

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

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

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

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

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

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

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

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

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

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

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

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

1424 necessary. 

1425 

1426 .. warning:: 

1427 

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

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

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

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

1432 invoked for the operation as a whole. 

1433 

1434 .. seealso:: 

1435 

1436 :doc:`queryguide/dml` 

1437 

1438 :meth:`.Session.bulk_save_objects` 

1439 

1440 :meth:`.Session.bulk_update_mappings` 

1441 

1442 

1443 """ # noqa: E501 

1444 

1445 return self._proxied.bulk_insert_mappings( 

1446 mapper, 

1447 mappings, 

1448 return_defaults=return_defaults, 

1449 render_nulls=render_nulls, 

1450 ) 

1451 

1452 def bulk_update_mappings( 

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

1454 ) -> None: 

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

1456 

1457 .. container:: class_bases 

1458 

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

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

1461 

1462 .. legacy:: 

1463 

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

1465 SQLAlchemy. For modern bulk INSERT and UPDATE, see 

1466 the sections :ref:`orm_queryguide_bulk_insert` and 

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

1468 implementation details with this method and adds new features 

1469 as well. 

1470 

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

1472 object, 

1473 representing the single kind of object represented within the mapping 

1474 list. 

1475 

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

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

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

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

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

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

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

1483 applied to the WHERE clause. 

1484 

1485 

1486 .. seealso:: 

1487 

1488 :doc:`queryguide/dml` 

1489 

1490 :meth:`.Session.bulk_insert_mappings` 

1491 

1492 :meth:`.Session.bulk_save_objects` 

1493 

1494 

1495 """ # noqa: E501 

1496 

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

1498 

1499 def merge( 

1500 self, 

1501 instance: _O, 

1502 *, 

1503 load: bool = True, 

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

1505 ) -> _O: 

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

1507 within this :class:`.Session`. 

1508 

1509 .. container:: class_bases 

1510 

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

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

1513 

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

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

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

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

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

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

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

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

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

1523 

1524 This operation cascades to associated instances if the association is 

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

1526 

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

1528 

1529 :param instance: Instance to be merged. 

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

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

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

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

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

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

1536 without re-querying the database. 

1537 

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

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

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

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

1542 the merge operation populates local attributes and 

1543 cascades to related objects and 

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

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

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

1547 any existing related objects or collections that might not 

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

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

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

1551 method. 

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

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

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

1555 

1556 .. versionadded:: 1.4.24 

1557 

1558 

1559 .. seealso:: 

1560 

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

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

1563 

1564 

1565 """ # noqa: E501 

1566 

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

1568 

1569 @overload 

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

1571 

1572 @overload 

1573 def query( 

1574 self, _colexpr: TypedColumnsClauseRole[_T] 

1575 ) -> RowReturningQuery[Tuple[_T]]: ... 

1576 

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

1578 

1579 # code within this block is **programmatically, 

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

1581 

1582 @overload 

1583 def query( 

1584 self, __ent0: _TCCA[_T0], __ent1: _TCCA[_T1] 

1585 ) -> RowReturningQuery[Tuple[_T0, _T1]]: ... 

1586 

1587 @overload 

1588 def query( 

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

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

1591 

1592 @overload 

1593 def query( 

1594 self, 

1595 __ent0: _TCCA[_T0], 

1596 __ent1: _TCCA[_T1], 

1597 __ent2: _TCCA[_T2], 

1598 __ent3: _TCCA[_T3], 

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

1600 

1601 @overload 

1602 def query( 

1603 self, 

1604 __ent0: _TCCA[_T0], 

1605 __ent1: _TCCA[_T1], 

1606 __ent2: _TCCA[_T2], 

1607 __ent3: _TCCA[_T3], 

1608 __ent4: _TCCA[_T4], 

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

1610 

1611 @overload 

1612 def query( 

1613 self, 

1614 __ent0: _TCCA[_T0], 

1615 __ent1: _TCCA[_T1], 

1616 __ent2: _TCCA[_T2], 

1617 __ent3: _TCCA[_T3], 

1618 __ent4: _TCCA[_T4], 

1619 __ent5: _TCCA[_T5], 

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

1621 

1622 @overload 

1623 def query( 

1624 self, 

1625 __ent0: _TCCA[_T0], 

1626 __ent1: _TCCA[_T1], 

1627 __ent2: _TCCA[_T2], 

1628 __ent3: _TCCA[_T3], 

1629 __ent4: _TCCA[_T4], 

1630 __ent5: _TCCA[_T5], 

1631 __ent6: _TCCA[_T6], 

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

1633 

1634 @overload 

1635 def query( 

1636 self, 

1637 __ent0: _TCCA[_T0], 

1638 __ent1: _TCCA[_T1], 

1639 __ent2: _TCCA[_T2], 

1640 __ent3: _TCCA[_T3], 

1641 __ent4: _TCCA[_T4], 

1642 __ent5: _TCCA[_T5], 

1643 __ent6: _TCCA[_T6], 

1644 __ent7: _TCCA[_T7], 

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

1646 

1647 # END OVERLOADED FUNCTIONS self.query 

1648 

1649 @overload 

1650 def query( 

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

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

1653 

1654 def query( 

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

1656 ) -> Query[Any]: 

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

1658 :class:`_orm.Session`. 

1659 

1660 .. container:: class_bases 

1661 

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

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

1664 

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

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

1667 to construct ORM queries. 

1668 

1669 .. seealso:: 

1670 

1671 :ref:`unified_tutorial` 

1672 

1673 :ref:`queryguide_toplevel` 

1674 

1675 :ref:`query_api_toplevel` - legacy API doc 

1676 

1677 

1678 """ # noqa: E501 

1679 

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

1681 

1682 def refresh( 

1683 self, 

1684 instance: object, 

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

1686 with_for_update: ForUpdateParameter = None, 

1687 ) -> None: 

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

1689 

1690 .. container:: class_bases 

1691 

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

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

1694 

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

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

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

1698 value available in the current transaction. 

1699 

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

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

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

1703 

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

1705 can also refresh eagerly loaded attributes. 

1706 

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

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

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

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

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

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

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

1714 refreshed. 

1715 

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

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

1718 attributes for those which are named explicitly in the 

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

1720 

1721 .. tip:: 

1722 

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

1724 refreshing both column and relationship oriented attributes, its 

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

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

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

1728 once while having explicit control over relationship loader 

1729 strategies, use the 

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

1731 instead. 

1732 

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

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

1735 in database state outside of that transaction. Refreshing 

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

1737 where database rows have not yet been accessed. 

1738 

1739 :param attribute_names: optional. An iterable collection of 

1740 string attribute names indicating a subset of attributes to 

1741 be refreshed. 

1742 

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

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

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

1746 flags should match the parameters of 

1747 :meth:`_query.Query.with_for_update`. 

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

1749 

1750 .. seealso:: 

1751 

1752 :ref:`session_expire` - introductory material 

1753 

1754 :meth:`.Session.expire` 

1755 

1756 :meth:`.Session.expire_all` 

1757 

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

1759 to refresh objects as they would be loaded normally. 

1760 

1761 

1762 """ # noqa: E501 

1763 

1764 return self._proxied.refresh( 

1765 instance, 

1766 attribute_names=attribute_names, 

1767 with_for_update=with_for_update, 

1768 ) 

1769 

1770 def rollback(self) -> None: 

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

1772 

1773 .. container:: class_bases 

1774 

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

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

1777 

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

1779 

1780 The method always rolls back 

1781 the topmost database transaction, discarding any nested 

1782 transactions that may be in progress. 

1783 

1784 .. seealso:: 

1785 

1786 :ref:`session_rollback` 

1787 

1788 :ref:`unitofwork_transaction` 

1789 

1790 

1791 """ # noqa: E501 

1792 

1793 return self._proxied.rollback() 

1794 

1795 @overload 

1796 def scalar( 

1797 self, 

1798 statement: TypedReturnsRows[Tuple[_T]], 

1799 params: Optional[_CoreSingleExecuteParams] = None, 

1800 *, 

1801 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1802 bind_arguments: Optional[_BindArguments] = None, 

1803 **kw: Any, 

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

1805 

1806 @overload 

1807 def scalar( 

1808 self, 

1809 statement: Executable, 

1810 params: Optional[_CoreSingleExecuteParams] = None, 

1811 *, 

1812 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1813 bind_arguments: Optional[_BindArguments] = None, 

1814 **kw: Any, 

1815 ) -> Any: ... 

1816 

1817 def scalar( 

1818 self, 

1819 statement: Executable, 

1820 params: Optional[_CoreSingleExecuteParams] = None, 

1821 *, 

1822 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1823 bind_arguments: Optional[_BindArguments] = None, 

1824 **kw: Any, 

1825 ) -> Any: 

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

1827 

1828 .. container:: class_bases 

1829 

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

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

1832 

1833 Usage and parameters are the same as that of 

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

1835 value. 

1836 

1837 

1838 """ # noqa: E501 

1839 

1840 return self._proxied.scalar( 

1841 statement, 

1842 params=params, 

1843 execution_options=execution_options, 

1844 bind_arguments=bind_arguments, 

1845 **kw, 

1846 ) 

1847 

1848 @overload 

1849 def scalars( 

1850 self, 

1851 statement: TypedReturnsRows[Tuple[_T]], 

1852 params: Optional[_CoreAnyExecuteParams] = None, 

1853 *, 

1854 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1855 bind_arguments: Optional[_BindArguments] = None, 

1856 **kw: Any, 

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

1858 

1859 @overload 

1860 def scalars( 

1861 self, 

1862 statement: Executable, 

1863 params: Optional[_CoreAnyExecuteParams] = None, 

1864 *, 

1865 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1866 bind_arguments: Optional[_BindArguments] = None, 

1867 **kw: Any, 

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

1869 

1870 def scalars( 

1871 self, 

1872 statement: Executable, 

1873 params: Optional[_CoreAnyExecuteParams] = None, 

1874 *, 

1875 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1876 bind_arguments: Optional[_BindArguments] = None, 

1877 **kw: Any, 

1878 ) -> ScalarResult[Any]: 

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

1880 

1881 .. container:: class_bases 

1882 

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

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

1885 

1886 Usage and parameters are the same as that of 

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

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

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

1890 

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

1892 

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

1894 

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

1896 

1897 .. seealso:: 

1898 

1899 :ref:`orm_queryguide_select_orm_entities` - contrasts the behavior 

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

1901 

1902 

1903 """ # noqa: E501 

1904 

1905 return self._proxied.scalars( 

1906 statement, 

1907 params=params, 

1908 execution_options=execution_options, 

1909 bind_arguments=bind_arguments, 

1910 **kw, 

1911 ) 

1912 

1913 @property 

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

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

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

1917 

1918 """ # noqa: E501 

1919 

1920 return self._proxied.bind 

1921 

1922 @bind.setter 

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

1924 self._proxied.bind = attr 

1925 

1926 @property 

1927 def dirty(self) -> Any: 

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

1929 

1930 .. container:: class_bases 

1931 

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

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

1934 

1935 E.g.:: 

1936 

1937 some_mapped_object in session.dirty 

1938 

1939 Instances are considered dirty when they were modified but not 

1940 deleted. 

1941 

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

1943 attribute-setting or collection modification operations will 

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

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

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

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

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

1949 it's only done at flush time). 

1950 

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

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

1953 

1954 

1955 """ # noqa: E501 

1956 

1957 return self._proxied.dirty 

1958 

1959 @property 

1960 def deleted(self) -> Any: 

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

1962 

1963 .. container:: class_bases 

1964 

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

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

1967 

1968 """ # noqa: E501 

1969 

1970 return self._proxied.deleted 

1971 

1972 @property 

1973 def new(self) -> Any: 

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

1975 

1976 .. container:: class_bases 

1977 

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

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

1980 

1981 """ # noqa: E501 

1982 

1983 return self._proxied.new 

1984 

1985 @property 

1986 def identity_map(self) -> IdentityMap: 

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

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

1989 

1990 """ # noqa: E501 

1991 

1992 return self._proxied.identity_map 

1993 

1994 @identity_map.setter 

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

1996 self._proxied.identity_map = attr 

1997 

1998 @property 

1999 def is_active(self) -> Any: 

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

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 .. versionchanged:: 1.4 The :class:`_orm.Session` no longer begins 

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

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

2010 

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

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

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

2014 fully roll back the transaction. 

2015 

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

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

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

2019 

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

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

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

2023 

2024 .. seealso:: 

2025 

2026 :ref:`faq_session_rollback` 

2027 

2028 :meth:`_orm.Session.in_transaction` 

2029 

2030 

2031 """ # noqa: E501 

2032 

2033 return self._proxied.is_active 

2034 

2035 @property 

2036 def autoflush(self) -> bool: 

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

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

2039 

2040 """ # noqa: E501 

2041 

2042 return self._proxied.autoflush 

2043 

2044 @autoflush.setter 

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

2046 self._proxied.autoflush = attr 

2047 

2048 @property 

2049 def no_autoflush(self) -> Any: 

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

2051 

2052 .. container:: class_bases 

2053 

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

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

2056 

2057 e.g.:: 

2058 

2059 with session.no_autoflush: 

2060 

2061 some_object = SomeClass() 

2062 session.add(some_object) 

2063 # won't autoflush 

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

2065 

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

2067 will not be subject to flushes occurring upon query 

2068 access. This is useful when initializing a series 

2069 of objects which involve existing database queries, 

2070 where the uncompleted object should not yet be flushed. 

2071 

2072 

2073 """ # noqa: E501 

2074 

2075 return self._proxied.no_autoflush 

2076 

2077 @property 

2078 def info(self) -> Any: 

2079 r"""A user-modifiable dictionary. 

2080 

2081 .. container:: class_bases 

2082 

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

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

2085 

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

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

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

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

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

2091 

2092 

2093 """ # noqa: E501 

2094 

2095 return self._proxied.info 

2096 

2097 @classmethod 

2098 def close_all(cls) -> None: 

2099 r"""Close *all* sessions in memory. 

2100 

2101 .. container:: class_bases 

2102 

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

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

2105 

2106 .. deprecated:: 1.3 The :meth:`.Session.close_all` method is deprecated and will be removed in a future release. Please refer to :func:`.session.close_all_sessions`. 

2107 

2108 """ # noqa: E501 

2109 

2110 return Session.close_all() 

2111 

2112 @classmethod 

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

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

2115 

2116 .. container:: class_bases 

2117 

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

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

2120 

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

2122 

2123 

2124 """ # noqa: E501 

2125 

2126 return Session.object_session(instance) 

2127 

2128 @classmethod 

2129 def identity_key( 

2130 cls, 

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

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

2133 *, 

2134 instance: Optional[Any] = None, 

2135 row: Optional[Union[Row[Any], RowMapping]] = None, 

2136 identity_token: Optional[Any] = None, 

2137 ) -> _IdentityKeyType[Any]: 

2138 r"""Return an identity key. 

2139 

2140 .. container:: class_bases 

2141 

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

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

2144 

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

2146 

2147 

2148 """ # noqa: E501 

2149 

2150 return Session.identity_key( 

2151 class_=class_, 

2152 ident=ident, 

2153 instance=instance, 

2154 row=row, 

2155 identity_token=identity_token, 

2156 ) 

2157 

2158 # END PROXY METHODS scoped_session 

2159 

2160 

2161ScopedSession = scoped_session 

2162"""Old name for backwards compatibility."""