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

247 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 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 .query import Query 

43 from .query import RowReturningQuery 

44 from .session import _BindArguments 

45 from .session import _EntityBindKey 

46 from .session import _PKIdentityArgument 

47 from .session import _SessionBind 

48 from .session import sessionmaker 

49 from .session import SessionTransaction 

50 from ..engine import Connection 

51 from ..engine import Engine 

52 from ..engine import Result 

53 from ..engine import Row 

54 from ..engine import RowMapping 

55 from ..engine.interfaces import _CoreAnyExecuteParams 

56 from ..engine.interfaces import _CoreSingleExecuteParams 

57 from ..engine.interfaces import CoreExecuteOptionsParameter 

58 from ..engine.result import ScalarResult 

59 from ..sql._typing import _ColumnsClauseArgument 

60 from ..sql._typing import _T0 

61 from ..sql._typing import _T1 

62 from ..sql._typing import _T2 

63 from ..sql._typing import _T3 

64 from ..sql._typing import _T4 

65 from ..sql._typing import _T5 

66 from ..sql._typing import _T6 

67 from ..sql._typing import _T7 

68 from ..sql._typing import _TypedColumnClauseArgument as _TCCA 

69 from ..sql.base import Executable 

70 from ..sql.elements import ClauseElement 

71 from ..sql.roles import TypedColumnsClauseRole 

72 from ..sql.selectable import ForUpdateParameter 

73 from ..sql.selectable import TypedReturnsRows 

74 

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

76 

77 

78class QueryPropertyDescriptor(Protocol): 

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

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

81 

82 .. versionadded:: 2.0.5 

83 

84 """ 

85 

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

87 

88 

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

90 

91__all__ = ["scoped_session"] 

92 

93 

94@create_proxy_methods( 

95 Session, 

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

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

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

99 methods=[ 

100 "__contains__", 

101 "__iter__", 

102 "add", 

103 "add_all", 

104 "begin", 

105 "begin_nested", 

106 "close", 

107 "reset", 

108 "commit", 

109 "connection", 

110 "delete", 

111 "execute", 

112 "expire", 

113 "expire_all", 

114 "expunge", 

115 "expunge_all", 

116 "flush", 

117 "get", 

118 "get_one", 

119 "get_bind", 

120 "is_modified", 

121 "bulk_save_objects", 

122 "bulk_insert_mappings", 

123 "bulk_update_mappings", 

124 "merge", 

125 "query", 

126 "refresh", 

127 "rollback", 

128 "scalar", 

129 "scalars", 

130 ], 

131 attributes=[ 

132 "bind", 

133 "dirty", 

134 "deleted", 

135 "new", 

136 "identity_map", 

137 "is_active", 

138 "autoflush", 

139 "no_autoflush", 

140 "info", 

141 ], 

142) 

143class scoped_session(Generic[_S]): 

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

145 

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

147 

148 .. note:: 

149 

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

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

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

153 

154 """ 

155 

156 _support_async: bool = False 

157 

158 session_factory: sessionmaker[_S] 

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

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

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

162 

163 registry: ScopedRegistry[_S] 

164 

165 def __init__( 

166 self, 

167 session_factory: sessionmaker[_S], 

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

169 ): 

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

171 

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

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

174 of :class:`.sessionmaker`. 

175 :param scopefunc: optional function which defines 

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

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

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

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

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

181 dictionary in order to store and retrieve the current 

182 :class:`.Session`. 

183 

184 """ 

185 self.session_factory = session_factory 

186 

187 if scopefunc: 

188 self.registry = ScopedRegistry(session_factory, scopefunc) 

189 else: 

190 self.registry = ThreadLocalRegistry(session_factory) 

191 

192 @property 

193 def _proxied(self) -> _S: 

194 return self.registry() 

195 

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

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

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

199 

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

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

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

203 and keyword arguments have been passed, 

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

205 

206 """ 

207 if kw: 

208 if self.registry.has(): 

209 raise sa_exc.InvalidRequestError( 

210 "Scoped session is already present; " 

211 "no new arguments may be specified." 

212 ) 

213 else: 

214 sess = self.session_factory(**kw) 

215 self.registry.set(sess) 

216 else: 

217 sess = self.registry() 

218 if not self._support_async and sess._is_asyncio: 

219 warn_deprecated( 

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

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

222 "Please use `async_scoped_session` instead.", 

223 "1.4.23", 

224 ) 

225 return sess 

226 

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

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

229 :class:`.scoped_session`. 

230 

231 See :meth:`.sessionmaker.configure`. 

232 

233 """ 

234 

235 if self.registry.has(): 

236 warn( 

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

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

239 "already been created." 

240 ) 

241 

242 self.session_factory.configure(**kwargs) 

243 

244 def remove(self) -> None: 

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

246 

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

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

249 transactional/connection resources still being held; transactions 

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

251 discarded. Upon next usage within the same scope, 

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

253 :class:`.Session` object. 

254 

255 """ 

256 

257 if self.registry.has(): 

258 self.registry().close() 

259 self.registry.clear() 

260 

261 def query_property( 

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

263 ) -> QueryPropertyDescriptor: 

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

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

266 :class:`.Session` when called. 

267 

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

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

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

271 

272 e.g.:: 

273 

274 from sqlalchemy.orm import QueryPropertyDescriptor 

275 from sqlalchemy.orm import scoped_session 

276 from sqlalchemy.orm import sessionmaker 

277 

278 Session = scoped_session(sessionmaker()) 

279 

280 

281 class MyClass: 

282 query: QueryPropertyDescriptor = Session.query_property() 

283 

284 

285 # after mappers are defined 

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

287 

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

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

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

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

292 keyword argument. 

293 

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

295 a class. 

296 

297 """ 

298 

299 class query: 

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

301 if query_cls: 

302 # custom query class 

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

304 else: 

305 # session's configured query class 

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

307 

308 return query() 

309 

310 # START PROXY METHODS scoped_session 

311 

312 # code within this block is **programmatically, 

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

314 

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

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

317 

318 .. container:: class_bases 

319 

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

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

322 

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

324 result of True. 

325 

326 

327 """ # noqa: E501 

328 

329 return self._proxied.__contains__(instance) 

330 

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

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

333 Session. 

334 

335 .. container:: class_bases 

336 

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

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

339 

340 

341 """ # noqa: E501 

342 

343 return self._proxied.__iter__() 

344 

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

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

347 

348 .. container:: class_bases 

349 

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

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

352 

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

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

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

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

357 

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

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

360 state directly. 

361 

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

363 objects which were transient when they were passed to 

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

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

366 :class:`_orm.Session`. 

367 

368 .. seealso:: 

369 

370 :meth:`_orm.Session.add_all` 

371 

372 :ref:`session_adding` - at :ref:`session_basics` 

373 

374 

375 """ # noqa: E501 

376 

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

378 

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

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

381 

382 .. container:: class_bases 

383 

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

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

386 

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

388 behavioral description. 

389 

390 .. seealso:: 

391 

392 :meth:`_orm.Session.add` 

393 

394 :ref:`session_adding` - at :ref:`session_basics` 

395 

396 

397 """ # noqa: E501 

398 

399 return self._proxied.add_all(instances) 

400 

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

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

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

404 

405 .. container:: class_bases 

406 

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

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

409 

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

411 so that normally it is not necessary to call the 

412 :meth:`_orm.Session.begin` 

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

414 the scope of when the transactional state is begun. 

415 

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

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

418 

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

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

421 documentation on SAVEPOINT transactions, please see 

422 :ref:`session_begin_nested`. 

423 

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

425 :class:`.SessionTransaction` 

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

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

428 an example. 

429 

430 .. seealso:: 

431 

432 :ref:`session_autobegin` 

433 

434 :ref:`unitofwork_transaction` 

435 

436 :meth:`.Session.begin_nested` 

437 

438 

439 

440 """ # noqa: E501 

441 

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

443 

444 def begin_nested(self) -> SessionTransaction: 

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

446 

447 .. container:: class_bases 

448 

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

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

451 

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

453 SAVEPOINT for this method to function correctly. 

454 

455 For documentation on SAVEPOINT 

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

457 

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

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

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

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

462 

463 .. seealso:: 

464 

465 :ref:`session_begin_nested` 

466 

467 :ref:`pysqlite_serializable` - special workarounds required 

468 with the SQLite driver in order for SAVEPOINT to work 

469 correctly. For asyncio use cases, see the section 

470 :ref:`aiosqlite_serializable`. 

471 

472 

473 """ # noqa: E501 

474 

475 return self._proxied.begin_nested() 

476 

477 def close(self) -> None: 

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

479 :class:`_orm.Session`. 

480 

481 .. container:: class_bases 

482 

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

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

485 

486 This expunges all ORM objects associated with this 

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

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

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

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

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

492 

493 .. tip:: 

494 

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

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

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

498 distinct "closed" state; it merely means 

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

500 and ORM objects. 

501 

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

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

504 any further action on the session will be forbidden. 

505 

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

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

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

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

510 

511 .. seealso:: 

512 

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

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

515 

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

517 ``close()`` with the parameter 

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

519 

520 

521 """ # noqa: E501 

522 

523 return self._proxied.close() 

524 

525 def reset(self) -> None: 

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

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

528 

529 .. container:: class_bases 

530 

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

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

533 

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

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

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

537 brand new, and ready to be used again. 

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

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

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

541 

542 .. versionadded:: 2.0.22 

543 

544 .. seealso:: 

545 

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

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

548 

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

550 prevent reuse of the Session when the parameter 

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

552 

553 """ # noqa: E501 

554 

555 return self._proxied.reset() 

556 

557 def commit(self) -> None: 

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

559 

560 .. container:: class_bases 

561 

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

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

564 

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

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

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

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

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

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

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

572 to disable this behavior. 

573 

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

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

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

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

578 normally affect the database unless pending flush changes were 

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

580 rules. 

581 

582 The outermost database transaction is committed unconditionally, 

583 automatically releasing any SAVEPOINTs in effect. 

584 

585 .. seealso:: 

586 

587 :ref:`session_committing` 

588 

589 :ref:`unitofwork_transaction` 

590 

591 :ref:`asyncio_orm_avoid_lazyloads` 

592 

593 

594 """ # noqa: E501 

595 

596 return self._proxied.commit() 

597 

598 def connection( 

599 self, 

600 bind_arguments: Optional[_BindArguments] = None, 

601 execution_options: Optional[CoreExecuteOptionsParameter] = None, 

602 ) -> Connection: 

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

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

605 

606 .. container:: class_bases 

607 

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

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

610 

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

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

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

614 returned (note that no 

615 transactional state is established with the DBAPI until the first 

616 SQL statement is emitted). 

617 

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

619 resolved through any of the optional keyword arguments. This 

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

621 

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

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

624 to :meth:`.Session.get_bind`. 

625 

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

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

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

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

630 the arguments are ignored. 

631 

632 .. seealso:: 

633 

634 :ref:`session_transaction_isolation` 

635 

636 

637 """ # noqa: E501 

638 

639 return self._proxied.connection( 

640 bind_arguments=bind_arguments, execution_options=execution_options 

641 ) 

642 

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

644 r"""Mark an instance as deleted. 

645 

646 .. container:: class_bases 

647 

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

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

650 

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

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

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

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

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

656 

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

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

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

660 is successfully committed, 

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

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

663 

664 .. seealso:: 

665 

666 :ref:`session_deleting` - at :ref:`session_basics` 

667 

668 

669 """ # noqa: E501 

670 

671 return self._proxied.delete(instance) 

672 

673 @overload 

674 def execute( 

675 self, 

676 statement: TypedReturnsRows[_T], 

677 params: Optional[_CoreAnyExecuteParams] = None, 

678 *, 

679 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

680 bind_arguments: Optional[_BindArguments] = None, 

681 _parent_execute_state: Optional[Any] = None, 

682 _add_event: Optional[Any] = None, 

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

684 

685 @overload 

686 def execute( 

687 self, 

688 statement: Executable, 

689 params: Optional[_CoreAnyExecuteParams] = None, 

690 *, 

691 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

692 bind_arguments: Optional[_BindArguments] = None, 

693 _parent_execute_state: Optional[Any] = None, 

694 _add_event: Optional[Any] = None, 

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

696 

697 def execute( 

698 self, 

699 statement: Executable, 

700 params: Optional[_CoreAnyExecuteParams] = None, 

701 *, 

702 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

703 bind_arguments: Optional[_BindArguments] = None, 

704 _parent_execute_state: Optional[Any] = None, 

705 _add_event: Optional[Any] = None, 

706 ) -> Result[Any]: 

707 r"""Execute a SQL expression construct. 

708 

709 .. container:: class_bases 

710 

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

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

713 

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

715 results of the statement execution. 

716 

717 E.g.:: 

718 

719 from sqlalchemy import select 

720 

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

722 

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

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

725 of :class:`_engine.Connection`. 

726 

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

728 now the primary point of ORM statement execution when using 

729 :term:`2.0 style` ORM usage. 

730 

731 :param statement: 

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

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

734 

735 :param params: 

736 Optional dictionary, or list of dictionaries, containing 

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

738 execution occurs; if a list of dictionaries, an 

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

740 must correspond to parameter names present in the statement. 

741 

742 :param execution_options: optional dictionary of execution options, 

743 which will be associated with the statement execution. This 

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

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

746 provide additional options understood only in an ORM context. 

747 

748 .. seealso:: 

749 

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

751 options 

752 

753 :param bind_arguments: dictionary of additional arguments to determine 

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

755 Contents of this dictionary are passed to the 

756 :meth:`.Session.get_bind` method. 

757 

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

759 

760 

761 

762 """ # noqa: E501 

763 

764 return self._proxied.execute( 

765 statement, 

766 params=params, 

767 execution_options=execution_options, 

768 bind_arguments=bind_arguments, 

769 _parent_execute_state=_parent_execute_state, 

770 _add_event=_add_event, 

771 ) 

772 

773 def expire( 

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

775 ) -> None: 

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

777 

778 .. container:: class_bases 

779 

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

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

782 

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

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

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

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

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

788 previously read in that same transaction, regardless of changes 

789 in database state outside of that transaction. 

790 

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

792 use :meth:`Session.expire_all`. 

793 

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

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

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

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

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

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

800 transaction. 

801 

802 :param instance: The instance to be refreshed. 

803 :param attribute_names: optional list of string attribute names 

804 indicating a subset of attributes to be expired. 

805 

806 .. seealso:: 

807 

808 :ref:`session_expire` - introductory material 

809 

810 :meth:`.Session.expire` 

811 

812 :meth:`.Session.refresh` 

813 

814 :meth:`_orm.Query.populate_existing` 

815 

816 

817 """ # noqa: E501 

818 

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

820 

821 def expire_all(self) -> None: 

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

823 

824 .. container:: class_bases 

825 

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

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

828 

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

830 a query will be issued using the 

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

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

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

834 previously read in that same transaction, regardless of changes 

835 in database state outside of that transaction. 

836 

837 To expire individual objects and individual attributes 

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

839 

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

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

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

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

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

845 assuming the transaction is isolated. 

846 

847 .. seealso:: 

848 

849 :ref:`session_expire` - introductory material 

850 

851 :meth:`.Session.expire` 

852 

853 :meth:`.Session.refresh` 

854 

855 :meth:`_orm.Query.populate_existing` 

856 

857 

858 """ # noqa: E501 

859 

860 return self._proxied.expire_all() 

861 

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

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

864 

865 .. container:: class_bases 

866 

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

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

869 

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

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

872 

873 

874 """ # noqa: E501 

875 

876 return self._proxied.expunge(instance) 

877 

878 def expunge_all(self) -> None: 

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

880 

881 .. container:: class_bases 

882 

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

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

885 

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

887 ``Session``. 

888 

889 

890 """ # noqa: E501 

891 

892 return self._proxied.expunge_all() 

893 

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

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

896 

897 .. container:: class_bases 

898 

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

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

901 

902 Writes out all pending object creations, deletions and modifications 

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

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

905 solver. 

906 

907 Database operations will be issued in the current transactional 

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

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

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

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

912 

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

914 only on elements that are in the given collection. 

915 

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

917 particular objects may need to be operated upon before the 

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

919 

920 

921 """ # noqa: E501 

922 

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

924 

925 def get( 

926 self, 

927 entity: _EntityBindKey[_O], 

928 ident: _PKIdentityArgument, 

929 *, 

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

931 populate_existing: bool = False, 

932 with_for_update: ForUpdateParameter = None, 

933 identity_token: Optional[Any] = None, 

934 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

935 bind_arguments: Optional[_BindArguments] = None, 

936 ) -> Optional[_O]: 

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

938 or ``None`` if not found. 

939 

940 .. container:: class_bases 

941 

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

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

944 

945 E.g.:: 

946 

947 my_user = session.get(User, 5) 

948 

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

950 

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

952 

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

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

955 

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

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

958 If the given primary key identifier is present 

959 in the local identity map, the object is returned 

960 directly from this collection and no SQL is emitted, 

961 unless the object has been marked fully expired. 

962 If not present, 

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

964 

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

966 the object is present in the identity map and 

967 marked as expired - a SELECT 

968 is emitted to refresh the object as well as to 

969 ensure that the row is still present. 

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

971 

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

973 type of entity to be loaded. 

974 

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

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

977 a tuple or dictionary should be passed. 

978 

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

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

981 the call looks like:: 

982 

983 my_object = session.get(SomeClass, 5) 

984 

985 The tuple form contains primary key values typically in 

986 the order in which they correspond to the mapped 

987 :class:`_schema.Table` 

988 object's primary key columns, or if the 

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

990 used, in 

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

992 of a row is represented by the integer 

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

994 

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

996 

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

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

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

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

1001 

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

1003 

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

1005 applied to the query, if one is emitted. 

1006 

1007 :param populate_existing: causes the method to unconditionally emit 

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

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

1010 

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

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

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

1014 flags should match the parameters of 

1015 :meth:`_query.Query.with_for_update`. 

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

1017 

1018 :param execution_options: optional dictionary of execution options, 

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

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

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

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

1023 

1024 .. versionadded:: 1.4.29 

1025 

1026 .. seealso:: 

1027 

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

1029 options 

1030 

1031 :param bind_arguments: dictionary of additional arguments to determine 

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

1033 Contents of this dictionary are passed to the 

1034 :meth:`.Session.get_bind` method. 

1035 

1036 .. versionadded: 2.0.0rc1 

1037 

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

1039 

1040 

1041 """ # noqa: E501 

1042 

1043 return self._proxied.get( 

1044 entity, 

1045 ident, 

1046 options=options, 

1047 populate_existing=populate_existing, 

1048 with_for_update=with_for_update, 

1049 identity_token=identity_token, 

1050 execution_options=execution_options, 

1051 bind_arguments=bind_arguments, 

1052 ) 

1053 

1054 def get_one( 

1055 self, 

1056 entity: _EntityBindKey[_O], 

1057 ident: _PKIdentityArgument, 

1058 *, 

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

1060 populate_existing: bool = False, 

1061 with_for_update: ForUpdateParameter = None, 

1062 identity_token: Optional[Any] = None, 

1063 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1064 bind_arguments: Optional[_BindArguments] = None, 

1065 ) -> _O: 

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

1067 identifier, or raise an exception if not found. 

1068 

1069 .. container:: class_bases 

1070 

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

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

1073 

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

1075 

1076 For a detailed documentation of the arguments see the 

1077 method :meth:`.Session.get`. 

1078 

1079 .. versionadded:: 2.0.22 

1080 

1081 :return: The object instance. 

1082 

1083 .. seealso:: 

1084 

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

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

1087 key 

1088 

1089 

1090 """ # noqa: E501 

1091 

1092 return self._proxied.get_one( 

1093 entity, 

1094 ident, 

1095 options=options, 

1096 populate_existing=populate_existing, 

1097 with_for_update=with_for_update, 

1098 identity_token=identity_token, 

1099 execution_options=execution_options, 

1100 bind_arguments=bind_arguments, 

1101 ) 

1102 

1103 def get_bind( 

1104 self, 

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

1106 *, 

1107 clause: Optional[ClauseElement] = None, 

1108 bind: Optional[_SessionBind] = None, 

1109 _sa_skip_events: Optional[bool] = None, 

1110 _sa_skip_for_implicit_returning: bool = False, 

1111 **kw: Any, 

1112 ) -> Union[Engine, Connection]: 

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

1114 

1115 .. container:: class_bases 

1116 

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

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

1119 

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

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

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

1123 

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

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

1126 appropriate bind to return. 

1127 

1128 Note that the "mapper" argument is usually present 

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

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

1131 individual INSERT/UPDATE/DELETE operation within a 

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

1133 

1134 The order of resolution is: 

1135 

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

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

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

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

1140 superclasses to more general. 

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

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

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

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

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

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

1147 associated with the clause. 

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

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

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

1151 selectable to which the mapper is mapped. 

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

1153 is raised. 

1154 

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

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

1157 of bind resolution scheme. See the example at 

1158 :ref:`session_custom_partitioning`. 

1159 

1160 :param mapper: 

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

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

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

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

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

1166 mapped for a bind. 

1167 

1168 :param clause: 

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

1170 :func:`_expression.select`, 

1171 :func:`_expression.text`, 

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

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

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

1175 associated with 

1176 bound :class:`_schema.MetaData`. 

1177 

1178 .. seealso:: 

1179 

1180 :ref:`session_partitioning` 

1181 

1182 :paramref:`.Session.binds` 

1183 

1184 :meth:`.Session.bind_mapper` 

1185 

1186 :meth:`.Session.bind_table` 

1187 

1188 

1189 """ # noqa: E501 

1190 

1191 return self._proxied.get_bind( 

1192 mapper=mapper, 

1193 clause=clause, 

1194 bind=bind, 

1195 _sa_skip_events=_sa_skip_events, 

1196 _sa_skip_for_implicit_returning=_sa_skip_for_implicit_returning, 

1197 **kw, 

1198 ) 

1199 

1200 def is_modified( 

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

1202 ) -> bool: 

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

1204 modified attributes. 

1205 

1206 .. container:: class_bases 

1207 

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

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

1210 

1211 This method retrieves the history for each instrumented 

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

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

1214 

1215 It is in effect a more expensive and accurate 

1216 version of checking for the given instance in the 

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

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

1219 

1220 E.g.:: 

1221 

1222 return session.is_modified(someobject) 

1223 

1224 A few caveats to this method apply: 

1225 

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

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

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

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

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

1231 change here. 

1232 * Scalar attributes may not have recorded the previously set 

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

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

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

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

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

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

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

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

1241 expensive on average than issuing a defensive SELECT. 

1242 

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

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

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

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

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

1248 argument with :func:`.column_property`. 

1249 

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

1251 :param include_collections: Indicates if multivalued collections 

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

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

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

1255 instance upon flush. 

1256 

1257 

1258 """ # noqa: E501 

1259 

1260 return self._proxied.is_modified( 

1261 instance, include_collections=include_collections 

1262 ) 

1263 

1264 def bulk_save_objects( 

1265 self, 

1266 objects: Iterable[object], 

1267 return_defaults: bool = False, 

1268 update_changed_only: bool = True, 

1269 preserve_order: bool = True, 

1270 ) -> None: 

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

1272 

1273 .. container:: class_bases 

1274 

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

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

1277 

1278 .. legacy:: 

1279 

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

1281 SQLAlchemy. For modern bulk INSERT and UPDATE, see 

1282 the sections :ref:`orm_queryguide_bulk_insert` and 

1283 :ref:`orm_queryguide_bulk_update`. 

1284 

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

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

1287 introduced in the :ref:`unified_tutorial` at 

1288 :ref:`tutorial_orm_data_manipulation`. SQLAlchemy 2.0 

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

1290 which solves previous issues of bulk INSERT slowness. 

1291 

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

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

1294 :class:`.Session` afterwards. 

1295 

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

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

1298 in traditional operation; if the object has the 

1299 :attr:`.InstanceState.key` 

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

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

1302 

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

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

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

1306 attributes present within each object are applied to the UPDATE 

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

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

1309 overhead of checking history on attributes. 

1310 

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

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

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

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

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

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

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

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

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

1320 approach. 

1321 

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

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

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

1325 with the exception of primary key attributes. 

1326 

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

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

1329 False, common types of objects are grouped into inserts 

1330 and updates, to allow for more batching opportunities. 

1331 

1332 .. seealso:: 

1333 

1334 :doc:`queryguide/dml` 

1335 

1336 :meth:`.Session.bulk_insert_mappings` 

1337 

1338 :meth:`.Session.bulk_update_mappings` 

1339 

1340 

1341 """ # noqa: E501 

1342 

1343 return self._proxied.bulk_save_objects( 

1344 objects, 

1345 return_defaults=return_defaults, 

1346 update_changed_only=update_changed_only, 

1347 preserve_order=preserve_order, 

1348 ) 

1349 

1350 def bulk_insert_mappings( 

1351 self, 

1352 mapper: _EntityBindKey[Any], 

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

1354 return_defaults: bool = False, 

1355 render_nulls: bool = False, 

1356 ) -> None: 

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

1358 

1359 .. container:: class_bases 

1360 

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

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

1363 

1364 .. legacy:: 

1365 

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

1367 SQLAlchemy. For modern bulk INSERT and UPDATE, see 

1368 the sections :ref:`orm_queryguide_bulk_insert` and 

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

1370 implementation details with this method and adds new features 

1371 as well. 

1372 

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

1374 object, 

1375 representing the single kind of object represented within the mapping 

1376 list. 

1377 

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

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

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

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

1382 keys to be populated into all tables. 

1383 

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

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

1386 The rationale for this parameter is typically to enable 

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

1388 be bulk inserted. 

1389 

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

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

1392 parameter can significantly decrease performance as INSERT 

1393 statements can no longer be batched. See 

1394 :ref:`engine_insertmanyvalues` 

1395 for background on which backends are affected. 

1396 

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

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

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

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

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

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

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

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

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

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

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

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

1409 necessary. 

1410 

1411 .. warning:: 

1412 

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

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

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

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

1417 invoked for the operation as a whole. 

1418 

1419 .. seealso:: 

1420 

1421 :doc:`queryguide/dml` 

1422 

1423 :meth:`.Session.bulk_save_objects` 

1424 

1425 :meth:`.Session.bulk_update_mappings` 

1426 

1427 

1428 """ # noqa: E501 

1429 

1430 return self._proxied.bulk_insert_mappings( 

1431 mapper, 

1432 mappings, 

1433 return_defaults=return_defaults, 

1434 render_nulls=render_nulls, 

1435 ) 

1436 

1437 def bulk_update_mappings( 

1438 self, mapper: _EntityBindKey[Any], mappings: Iterable[Dict[str, Any]] 

1439 ) -> None: 

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

1441 

1442 .. container:: class_bases 

1443 

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

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

1446 

1447 .. legacy:: 

1448 

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

1450 SQLAlchemy. For modern bulk INSERT and UPDATE, see 

1451 the sections :ref:`orm_queryguide_bulk_insert` and 

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

1453 implementation details with this method and adds new features 

1454 as well. 

1455 

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

1457 object, 

1458 representing the single kind of object represented within the mapping 

1459 list. 

1460 

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

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

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

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

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

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

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

1468 applied to the WHERE clause. 

1469 

1470 

1471 .. seealso:: 

1472 

1473 :doc:`queryguide/dml` 

1474 

1475 :meth:`.Session.bulk_insert_mappings` 

1476 

1477 :meth:`.Session.bulk_save_objects` 

1478 

1479 

1480 """ # noqa: E501 

1481 

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

1483 

1484 def merge( 

1485 self, 

1486 instance: _O, 

1487 *, 

1488 load: bool = True, 

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

1490 ) -> _O: 

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

1492 within this :class:`.Session`. 

1493 

1494 .. container:: class_bases 

1495 

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

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

1498 

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

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

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

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

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

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

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

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

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

1508 

1509 This operation cascades to associated instances if the association is 

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

1511 

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

1513 

1514 :param instance: Instance to be merged. 

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

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

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

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

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

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

1521 without re-querying the database. 

1522 

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

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

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

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

1527 the merge operation populates local attributes and 

1528 cascades to related objects and 

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

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

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

1532 any existing related objects or collections that might not 

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

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

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

1536 method. 

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

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

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

1540 

1541 .. versionadded:: 1.4.24 

1542 

1543 

1544 .. seealso:: 

1545 

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

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

1548 

1549 

1550 """ # noqa: E501 

1551 

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

1553 

1554 @overload 

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

1556 

1557 @overload 

1558 def query( 

1559 self, _colexpr: TypedColumnsClauseRole[_T] 

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

1561 

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

1563 

1564 # code within this block is **programmatically, 

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

1566 

1567 @overload 

1568 def query( 

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

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

1571 

1572 @overload 

1573 def query( 

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

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

1576 

1577 @overload 

1578 def query( 

1579 self, 

1580 __ent0: _TCCA[_T0], 

1581 __ent1: _TCCA[_T1], 

1582 __ent2: _TCCA[_T2], 

1583 __ent3: _TCCA[_T3], 

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

1585 

1586 @overload 

1587 def query( 

1588 self, 

1589 __ent0: _TCCA[_T0], 

1590 __ent1: _TCCA[_T1], 

1591 __ent2: _TCCA[_T2], 

1592 __ent3: _TCCA[_T3], 

1593 __ent4: _TCCA[_T4], 

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

1595 

1596 @overload 

1597 def query( 

1598 self, 

1599 __ent0: _TCCA[_T0], 

1600 __ent1: _TCCA[_T1], 

1601 __ent2: _TCCA[_T2], 

1602 __ent3: _TCCA[_T3], 

1603 __ent4: _TCCA[_T4], 

1604 __ent5: _TCCA[_T5], 

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

1606 

1607 @overload 

1608 def query( 

1609 self, 

1610 __ent0: _TCCA[_T0], 

1611 __ent1: _TCCA[_T1], 

1612 __ent2: _TCCA[_T2], 

1613 __ent3: _TCCA[_T3], 

1614 __ent4: _TCCA[_T4], 

1615 __ent5: _TCCA[_T5], 

1616 __ent6: _TCCA[_T6], 

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

1618 

1619 @overload 

1620 def query( 

1621 self, 

1622 __ent0: _TCCA[_T0], 

1623 __ent1: _TCCA[_T1], 

1624 __ent2: _TCCA[_T2], 

1625 __ent3: _TCCA[_T3], 

1626 __ent4: _TCCA[_T4], 

1627 __ent5: _TCCA[_T5], 

1628 __ent6: _TCCA[_T6], 

1629 __ent7: _TCCA[_T7], 

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

1631 

1632 # END OVERLOADED FUNCTIONS self.query 

1633 

1634 @overload 

1635 def query( 

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

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

1638 

1639 def query( 

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

1641 ) -> Query[Any]: 

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

1643 :class:`_orm.Session`. 

1644 

1645 .. container:: class_bases 

1646 

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

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

1649 

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

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

1652 to construct ORM queries. 

1653 

1654 .. seealso:: 

1655 

1656 :ref:`unified_tutorial` 

1657 

1658 :ref:`queryguide_toplevel` 

1659 

1660 :ref:`query_api_toplevel` - legacy API doc 

1661 

1662 

1663 """ # noqa: E501 

1664 

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

1666 

1667 def refresh( 

1668 self, 

1669 instance: object, 

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

1671 with_for_update: ForUpdateParameter = None, 

1672 ) -> None: 

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

1674 

1675 .. container:: class_bases 

1676 

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

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

1679 

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

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

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

1683 value available in the current transaction. 

1684 

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

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

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

1688 

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

1690 can also refresh eagerly loaded attributes. 

1691 

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

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

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

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

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

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

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

1699 refreshed. 

1700 

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

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

1703 attributes for those which are named explicitly in the 

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

1705 

1706 .. tip:: 

1707 

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

1709 refreshing both column and relationship oriented attributes, its 

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

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

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

1713 once while having explicit control over relationship loader 

1714 strategies, use the 

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

1716 instead. 

1717 

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

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

1720 in database state outside of that transaction. Refreshing 

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

1722 where database rows have not yet been accessed. 

1723 

1724 :param attribute_names: optional. An iterable collection of 

1725 string attribute names indicating a subset of attributes to 

1726 be refreshed. 

1727 

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

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

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

1731 flags should match the parameters of 

1732 :meth:`_query.Query.with_for_update`. 

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

1734 

1735 .. seealso:: 

1736 

1737 :ref:`session_expire` - introductory material 

1738 

1739 :meth:`.Session.expire` 

1740 

1741 :meth:`.Session.expire_all` 

1742 

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

1744 to refresh objects as they would be loaded normally. 

1745 

1746 

1747 """ # noqa: E501 

1748 

1749 return self._proxied.refresh( 

1750 instance, 

1751 attribute_names=attribute_names, 

1752 with_for_update=with_for_update, 

1753 ) 

1754 

1755 def rollback(self) -> None: 

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

1757 

1758 .. container:: class_bases 

1759 

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

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

1762 

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

1764 

1765 The method always rolls back 

1766 the topmost database transaction, discarding any nested 

1767 transactions that may be in progress. 

1768 

1769 .. seealso:: 

1770 

1771 :ref:`session_rollback` 

1772 

1773 :ref:`unitofwork_transaction` 

1774 

1775 

1776 """ # noqa: E501 

1777 

1778 return self._proxied.rollback() 

1779 

1780 @overload 

1781 def scalar( 

1782 self, 

1783 statement: TypedReturnsRows[Tuple[_T]], 

1784 params: Optional[_CoreSingleExecuteParams] = None, 

1785 *, 

1786 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1787 bind_arguments: Optional[_BindArguments] = None, 

1788 **kw: Any, 

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

1790 

1791 @overload 

1792 def scalar( 

1793 self, 

1794 statement: Executable, 

1795 params: Optional[_CoreSingleExecuteParams] = None, 

1796 *, 

1797 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1798 bind_arguments: Optional[_BindArguments] = None, 

1799 **kw: Any, 

1800 ) -> Any: ... 

1801 

1802 def scalar( 

1803 self, 

1804 statement: Executable, 

1805 params: Optional[_CoreSingleExecuteParams] = None, 

1806 *, 

1807 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1808 bind_arguments: Optional[_BindArguments] = None, 

1809 **kw: Any, 

1810 ) -> Any: 

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

1812 

1813 .. container:: class_bases 

1814 

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

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

1817 

1818 Usage and parameters are the same as that of 

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

1820 value. 

1821 

1822 

1823 """ # noqa: E501 

1824 

1825 return self._proxied.scalar( 

1826 statement, 

1827 params=params, 

1828 execution_options=execution_options, 

1829 bind_arguments=bind_arguments, 

1830 **kw, 

1831 ) 

1832 

1833 @overload 

1834 def scalars( 

1835 self, 

1836 statement: TypedReturnsRows[Tuple[_T]], 

1837 params: Optional[_CoreAnyExecuteParams] = None, 

1838 *, 

1839 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1840 bind_arguments: Optional[_BindArguments] = None, 

1841 **kw: Any, 

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

1843 

1844 @overload 

1845 def scalars( 

1846 self, 

1847 statement: Executable, 

1848 params: Optional[_CoreAnyExecuteParams] = None, 

1849 *, 

1850 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1851 bind_arguments: Optional[_BindArguments] = None, 

1852 **kw: Any, 

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

1854 

1855 def scalars( 

1856 self, 

1857 statement: Executable, 

1858 params: Optional[_CoreAnyExecuteParams] = None, 

1859 *, 

1860 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1861 bind_arguments: Optional[_BindArguments] = None, 

1862 **kw: Any, 

1863 ) -> ScalarResult[Any]: 

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

1865 

1866 .. container:: class_bases 

1867 

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

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

1870 

1871 Usage and parameters are the same as that of 

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

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

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

1875 

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

1877 

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

1879 

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

1881 

1882 .. seealso:: 

1883 

1884 :ref:`orm_queryguide_select_orm_entities` - contrasts the behavior 

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

1886 

1887 

1888 """ # noqa: E501 

1889 

1890 return self._proxied.scalars( 

1891 statement, 

1892 params=params, 

1893 execution_options=execution_options, 

1894 bind_arguments=bind_arguments, 

1895 **kw, 

1896 ) 

1897 

1898 @property 

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

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

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

1902 

1903 """ # noqa: E501 

1904 

1905 return self._proxied.bind 

1906 

1907 @bind.setter 

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

1909 self._proxied.bind = attr 

1910 

1911 @property 

1912 def dirty(self) -> Any: 

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

1914 

1915 .. container:: class_bases 

1916 

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

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

1919 

1920 E.g.:: 

1921 

1922 some_mapped_object in session.dirty 

1923 

1924 Instances are considered dirty when they were modified but not 

1925 deleted. 

1926 

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

1928 attribute-setting or collection modification operations will 

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

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

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

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

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

1934 it's only done at flush time). 

1935 

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

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

1938 

1939 

1940 """ # noqa: E501 

1941 

1942 return self._proxied.dirty 

1943 

1944 @property 

1945 def deleted(self) -> Any: 

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

1947 

1948 .. container:: class_bases 

1949 

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

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

1952 

1953 """ # noqa: E501 

1954 

1955 return self._proxied.deleted 

1956 

1957 @property 

1958 def new(self) -> Any: 

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

1960 

1961 .. container:: class_bases 

1962 

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

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

1965 

1966 """ # noqa: E501 

1967 

1968 return self._proxied.new 

1969 

1970 @property 

1971 def identity_map(self) -> IdentityMap: 

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

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

1974 

1975 """ # noqa: E501 

1976 

1977 return self._proxied.identity_map 

1978 

1979 @identity_map.setter 

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

1981 self._proxied.identity_map = attr 

1982 

1983 @property 

1984 def is_active(self) -> Any: 

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

1986 

1987 .. container:: class_bases 

1988 

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

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

1991 

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

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

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

1995 

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

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

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

1999 fully roll back the transaction. 

2000 

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

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

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

2004 

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

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

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

2008 

2009 .. seealso:: 

2010 

2011 :ref:`faq_session_rollback` 

2012 

2013 :meth:`_orm.Session.in_transaction` 

2014 

2015 

2016 """ # noqa: E501 

2017 

2018 return self._proxied.is_active 

2019 

2020 @property 

2021 def autoflush(self) -> bool: 

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

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

2024 

2025 """ # noqa: E501 

2026 

2027 return self._proxied.autoflush 

2028 

2029 @autoflush.setter 

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

2031 self._proxied.autoflush = attr 

2032 

2033 @property 

2034 def no_autoflush(self) -> Any: 

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

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 e.g.:: 

2043 

2044 with session.no_autoflush: 

2045 

2046 some_object = SomeClass() 

2047 session.add(some_object) 

2048 # won't autoflush 

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

2050 

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

2052 will not be subject to flushes occurring upon query 

2053 access. This is useful when initializing a series 

2054 of objects which involve existing database queries, 

2055 where the uncompleted object should not yet be flushed. 

2056 

2057 

2058 """ # noqa: E501 

2059 

2060 return self._proxied.no_autoflush 

2061 

2062 @property 

2063 def info(self) -> Any: 

2064 r"""A user-modifiable dictionary. 

2065 

2066 .. container:: class_bases 

2067 

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

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

2070 

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

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

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

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

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

2076 

2077 

2078 """ # noqa: E501 

2079 

2080 return self._proxied.info 

2081 

2082 @classmethod 

2083 def close_all(cls) -> None: 

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

2085 

2086 .. container:: class_bases 

2087 

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

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

2090 

2091 .. 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`. 

2092 

2093 """ # noqa: E501 

2094 

2095 return Session.close_all() 

2096 

2097 @classmethod 

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

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

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 This is an alias of :func:`.object_session`. 

2107 

2108 

2109 """ # noqa: E501 

2110 

2111 return Session.object_session(instance) 

2112 

2113 @classmethod 

2114 def identity_key( 

2115 cls, 

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

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

2118 *, 

2119 instance: Optional[Any] = None, 

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

2121 identity_token: Optional[Any] = None, 

2122 ) -> _IdentityKeyType[Any]: 

2123 r"""Return an identity key. 

2124 

2125 .. container:: class_bases 

2126 

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

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

2129 

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

2131 

2132 

2133 """ # noqa: E501 

2134 

2135 return Session.identity_key( 

2136 class_=class_, 

2137 ident=ident, 

2138 instance=instance, 

2139 row=row, 

2140 identity_token=identity_token, 

2141 ) 

2142 

2143 # END PROXY METHODS scoped_session 

2144 

2145 

2146ScopedSession = scoped_session 

2147"""Old name for backwards compatibility."""