Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/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

254 statements  

1# orm/scoping.py 

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

3# <see AUTHORS file> 

4# 

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

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

7 

8from __future__ import annotations 

9 

10from typing import Any 

11from typing import Callable 

12from typing import Dict 

13from typing import Generic 

14from typing import Iterable 

15from typing import Iterator 

16from typing import Optional 

17from typing import overload 

18from typing import Protocol 

19from typing import Sequence 

20from typing import Tuple 

21from typing import Type 

22from typing import TYPE_CHECKING 

23from typing import TypeVar 

24from typing import Union 

25 

26from .session import _S 

27from .session import Session 

28from .. import exc as sa_exc 

29from .. import util 

30from ..util import create_proxy_methods 

31from ..util import ScopedRegistry 

32from ..util import ThreadLocalRegistry 

33from ..util import warn 

34from ..util import warn_deprecated 

35from ..util.typing import TupleAny 

36from ..util.typing import TypeVarTuple 

37from ..util.typing import Unpack 

38 

39if TYPE_CHECKING: 

40 from ._typing import _EntityType 

41 from ._typing import _IdentityKeyType 

42 from ._typing import OrmExecuteOptionsParameter 

43 from .identity import IdentityMap 

44 from .interfaces import ORMOption 

45 from .mapper import Mapper 

46 from .query import Query 

47 from .query import RowReturningQuery 

48 from .session import _BindArguments 

49 from .session import _EntityBindKey 

50 from .session import _PKIdentityArgument 

51 from .session import _SessionBind 

52 from .session import sessionmaker 

53 from .session import SessionTransaction 

54 from ..engine import Connection 

55 from ..engine import CursorResult 

56 from ..engine import Engine 

57 from ..engine import Result 

58 from ..engine import Row 

59 from ..engine import RowMapping 

60 from ..engine.interfaces import _CoreAnyExecuteParams 

61 from ..engine.interfaces import _CoreSingleExecuteParams 

62 from ..engine.interfaces import CoreExecuteOptionsParameter 

63 from ..engine.result import ScalarResult 

64 from ..sql._typing import _ColumnsClauseArgument 

65 from ..sql._typing import _T0 

66 from ..sql._typing import _T1 

67 from ..sql._typing import _T2 

68 from ..sql._typing import _T3 

69 from ..sql._typing import _T4 

70 from ..sql._typing import _T5 

71 from ..sql._typing import _T6 

72 from ..sql._typing import _T7 

73 from ..sql._typing import _TypedColumnClauseArgument as _TCCA 

74 from ..sql.base import Executable 

75 from ..sql.dml import UpdateBase 

76 from ..sql.elements import ClauseElement 

77 from ..sql.roles import TypedColumnsClauseRole 

78 from ..sql.selectable import ForUpdateParameter 

79 from ..sql.selectable import TypedReturnsRows 

80 

81 

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

83_Ts = TypeVarTuple("_Ts") 

84 

85 

86class QueryPropertyDescriptor(Protocol): 

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

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

89 

90 .. versionadded:: 2.0.5 

91 

92 """ 

93 

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

95 

96 

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

98 

99__all__ = ["scoped_session"] 

100 

101 

102@create_proxy_methods( 

103 Session, 

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

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

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

107 methods=[ 

108 "__contains__", 

109 "__iter__", 

110 "add", 

111 "add_all", 

112 "begin", 

113 "begin_nested", 

114 "close", 

115 "reset", 

116 "commit", 

117 "connection", 

118 "delete", 

119 "execute", 

120 "expire", 

121 "expire_all", 

122 "expunge", 

123 "expunge_all", 

124 "flush", 

125 "get", 

126 "get_one", 

127 "get_bind", 

128 "is_modified", 

129 "bulk_save_objects", 

130 "bulk_insert_mappings", 

131 "bulk_update_mappings", 

132 "merge", 

133 "query", 

134 "refresh", 

135 "rollback", 

136 "scalar", 

137 "scalars", 

138 ], 

139 attributes=[ 

140 "bind", 

141 "dirty", 

142 "deleted", 

143 "new", 

144 "identity_map", 

145 "is_active", 

146 "autoflush", 

147 "no_autoflush", 

148 "info", 

149 ], 

150) 

151class scoped_session(Generic[_S]): 

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

153 

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

155 

156 .. note:: 

157 

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

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

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

161 

162 """ 

163 

164 _support_async: bool = False 

165 

166 session_factory: sessionmaker[_S] 

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

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

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

170 

171 registry: ScopedRegistry[_S] 

172 

173 def __init__( 

174 self, 

175 session_factory: sessionmaker[_S], 

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

177 ): 

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

179 

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

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

182 of :class:`.sessionmaker`. 

183 :param scopefunc: optional function which defines 

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

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

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

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

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

189 dictionary in order to store and retrieve the current 

190 :class:`.Session`. 

191 

192 """ 

193 self.session_factory = session_factory 

194 

195 if scopefunc: 

196 self.registry = ScopedRegistry(session_factory, scopefunc) 

197 else: 

198 self.registry = ThreadLocalRegistry(session_factory) 

199 

200 @property 

201 def _proxied(self) -> _S: 

202 return self.registry() 

203 

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

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

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

207 

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

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

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

211 and keyword arguments have been passed, 

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

213 

214 """ 

215 if kw: 

216 if self.registry.has(): 

217 raise sa_exc.InvalidRequestError( 

218 "Scoped session is already present; " 

219 "no new arguments may be specified." 

220 ) 

221 else: 

222 sess = self.session_factory(**kw) 

223 self.registry.set(sess) 

224 else: 

225 sess = self.registry() 

226 if not self._support_async and sess._is_asyncio: 

227 warn_deprecated( 

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

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

230 "Please use `async_scoped_session` instead.", 

231 "1.4.23", 

232 ) 

233 return sess 

234 

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

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

237 :class:`.scoped_session`. 

238 

239 See :meth:`.sessionmaker.configure`. 

240 

241 """ 

242 

243 if self.registry.has(): 

244 warn( 

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

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

247 "already been created." 

248 ) 

249 

250 self.session_factory.configure(**kwargs) 

251 

252 def remove(self) -> None: 

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

254 

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

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

257 transactional/connection resources still being held; transactions 

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

259 discarded. Upon next usage within the same scope, 

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

261 :class:`.Session` object. 

262 

263 """ 

264 

265 if self.registry.has(): 

266 self.registry().close() 

267 self.registry.clear() 

268 

269 def query_property( 

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

271 ) -> QueryPropertyDescriptor: 

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

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

274 :class:`.Session` when called. 

275 

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

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

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

279 

280 e.g.:: 

281 

282 from sqlalchemy.orm import QueryPropertyDescriptor 

283 from sqlalchemy.orm import scoped_session 

284 from sqlalchemy.orm import sessionmaker 

285 

286 Session = scoped_session(sessionmaker()) 

287 

288 class MyClass: 

289 query: QueryPropertyDescriptor = Session.query_property() 

290 

291 # after mappers are defined 

292 result = MyClass.query.filter(MyClass.name=='foo').all() 

293 

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

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

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

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

298 keyword argument. 

299 

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

301 a class. 

302 

303 """ 

304 

305 class query: 

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

307 if query_cls: 

308 # custom query class 

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

310 else: 

311 # session's configured query class 

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

313 

314 return query() 

315 

316 # START PROXY METHODS scoped_session 

317 

318 # code within this block is **programmatically, 

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

320 

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

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

323 

324 .. container:: class_bases 

325 

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

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

328 

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

330 result of True. 

331 

332 

333 """ # noqa: E501 

334 

335 return self._proxied.__contains__(instance) 

336 

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

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

339 Session. 

340 

341 .. container:: class_bases 

342 

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

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

345 

346 

347 """ # noqa: E501 

348 

349 return self._proxied.__iter__() 

350 

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

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

353 

354 .. container:: class_bases 

355 

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

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

358 

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

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

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

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

363 

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

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

366 state directly. 

367 

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

369 objects which were transient when they were passed to 

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

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

372 :class:`_orm.Session`. 

373 

374 .. seealso:: 

375 

376 :meth:`_orm.Session.add_all` 

377 

378 :ref:`session_adding` - at :ref:`session_basics` 

379 

380 

381 """ # noqa: E501 

382 

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

384 

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

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

387 

388 .. container:: class_bases 

389 

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

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

392 

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

394 behavioral description. 

395 

396 .. seealso:: 

397 

398 :meth:`_orm.Session.add` 

399 

400 :ref:`session_adding` - at :ref:`session_basics` 

401 

402 

403 """ # noqa: E501 

404 

405 return self._proxied.add_all(instances) 

406 

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

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

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

410 

411 .. container:: class_bases 

412 

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

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

415 

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

417 so that normally it is not necessary to call the 

418 :meth:`_orm.Session.begin` 

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

420 the scope of when the transactional state is begun. 

421 

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

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

424 

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

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

427 documentation on SAVEPOINT transactions, please see 

428 :ref:`session_begin_nested`. 

429 

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

431 :class:`.SessionTransaction` 

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

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

434 an example. 

435 

436 .. seealso:: 

437 

438 :ref:`session_autobegin` 

439 

440 :ref:`unitofwork_transaction` 

441 

442 :meth:`.Session.begin_nested` 

443 

444 

445 

446 """ # noqa: E501 

447 

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

449 

450 def begin_nested(self) -> SessionTransaction: 

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

452 

453 .. container:: class_bases 

454 

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

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

457 

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

459 SAVEPOINT for this method to function correctly. 

460 

461 For documentation on SAVEPOINT 

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

463 

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

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

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

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

468 

469 .. seealso:: 

470 

471 :ref:`session_begin_nested` 

472 

473 :ref:`pysqlite_serializable` - special workarounds required 

474 with the SQLite driver in order for SAVEPOINT to work 

475 correctly. For asyncio use cases, see the section 

476 :ref:`aiosqlite_serializable`. 

477 

478 

479 """ # noqa: E501 

480 

481 return self._proxied.begin_nested() 

482 

483 def close(self) -> None: 

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

485 :class:`_orm.Session`. 

486 

487 .. container:: class_bases 

488 

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

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

491 

492 This expunges all ORM objects associated with this 

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

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

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

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

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

498 

499 .. tip:: 

500 

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

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

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

504 distinct "closed" state; it merely means 

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

506 and ORM objects. 

507 

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

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

510 any further action on the session will be forbidden. 

511 

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

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

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

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

516 

517 .. seealso:: 

518 

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

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

521 

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

523 ``close()`` with the parameter 

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

525 

526 

527 """ # noqa: E501 

528 

529 return self._proxied.close() 

530 

531 def reset(self) -> None: 

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

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

534 

535 .. container:: class_bases 

536 

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

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

539 

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

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

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

543 brand new, and ready to be used again. 

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

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

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

547 

548 .. versionadded:: 2.0.22 

549 

550 .. seealso:: 

551 

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

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

554 

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

556 prevent re-use of the Session when the parameter 

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

558 

559 """ # noqa: E501 

560 

561 return self._proxied.reset() 

562 

563 def commit(self) -> None: 

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

565 

566 .. container:: class_bases 

567 

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

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

570 

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

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

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

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

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

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

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

578 to disable this behavior. 

579 

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

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

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

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

584 normally affect the database unless pending flush changes were 

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

586 rules. 

587 

588 The outermost database transaction is committed unconditionally, 

589 automatically releasing any SAVEPOINTs in effect. 

590 

591 .. seealso:: 

592 

593 :ref:`session_committing` 

594 

595 :ref:`unitofwork_transaction` 

596 

597 :ref:`asyncio_orm_avoid_lazyloads` 

598 

599 

600 """ # noqa: E501 

601 

602 return self._proxied.commit() 

603 

604 def connection( 

605 self, 

606 bind_arguments: Optional[_BindArguments] = None, 

607 execution_options: Optional[CoreExecuteOptionsParameter] = None, 

608 ) -> Connection: 

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

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

611 

612 .. container:: class_bases 

613 

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

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

616 

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

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

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

620 returned (note that no 

621 transactional state is established with the DBAPI until the first 

622 SQL statement is emitted). 

623 

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

625 resolved through any of the optional keyword arguments. This 

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

627 

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

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

630 to :meth:`.Session.get_bind`. 

631 

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

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

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

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

636 the arguments are ignored. 

637 

638 .. seealso:: 

639 

640 :ref:`session_transaction_isolation` 

641 

642 

643 """ # noqa: E501 

644 

645 return self._proxied.connection( 

646 bind_arguments=bind_arguments, execution_options=execution_options 

647 ) 

648 

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

650 r"""Mark an instance as deleted. 

651 

652 .. container:: class_bases 

653 

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

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

656 

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

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

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

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

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

662 

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

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

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

666 is successfully committed, 

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

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

669 

670 .. seealso:: 

671 

672 :ref:`session_deleting` - at :ref:`session_basics` 

673 

674 

675 """ # noqa: E501 

676 

677 return self._proxied.delete(instance) 

678 

679 @overload 

680 def execute( 

681 self, 

682 statement: TypedReturnsRows[Unpack[_Ts]], 

683 params: Optional[_CoreAnyExecuteParams] = None, 

684 *, 

685 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

686 bind_arguments: Optional[_BindArguments] = None, 

687 _parent_execute_state: Optional[Any] = None, 

688 _add_event: Optional[Any] = None, 

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

690 

691 @overload 

692 def execute( 

693 self, 

694 statement: UpdateBase, 

695 params: Optional[_CoreAnyExecuteParams] = None, 

696 *, 

697 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

698 bind_arguments: Optional[_BindArguments] = None, 

699 _parent_execute_state: Optional[Any] = None, 

700 _add_event: Optional[Any] = None, 

701 ) -> CursorResult[Unpack[TupleAny]]: ... 

702 

703 @overload 

704 def execute( 

705 self, 

706 statement: Executable, 

707 params: Optional[_CoreAnyExecuteParams] = None, 

708 *, 

709 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

710 bind_arguments: Optional[_BindArguments] = None, 

711 _parent_execute_state: Optional[Any] = None, 

712 _add_event: Optional[Any] = None, 

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

714 

715 def execute( 

716 self, 

717 statement: Executable, 

718 params: Optional[_CoreAnyExecuteParams] = None, 

719 *, 

720 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

721 bind_arguments: Optional[_BindArguments] = None, 

722 _parent_execute_state: Optional[Any] = None, 

723 _add_event: Optional[Any] = None, 

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

725 r"""Execute a SQL expression construct. 

726 

727 .. container:: class_bases 

728 

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

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

731 

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

733 results of the statement execution. 

734 

735 E.g.:: 

736 

737 from sqlalchemy import select 

738 result = session.execute( 

739 select(User).where(User.id == 5) 

740 ) 

741 

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

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

744 of :class:`_engine.Connection`. 

745 

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

747 now the primary point of ORM statement execution when using 

748 :term:`2.0 style` ORM usage. 

749 

750 :param statement: 

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

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

753 

754 :param params: 

755 Optional dictionary, or list of dictionaries, containing 

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

757 execution occurs; if a list of dictionaries, an 

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

759 must correspond to parameter names present in the statement. 

760 

761 :param execution_options: optional dictionary of execution options, 

762 which will be associated with the statement execution. This 

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

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

765 provide additional options understood only in an ORM context. 

766 

767 .. seealso:: 

768 

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

770 options 

771 

772 :param bind_arguments: dictionary of additional arguments to determine 

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

774 Contents of this dictionary are passed to the 

775 :meth:`.Session.get_bind` method. 

776 

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

778 

779 

780 

781 """ # noqa: E501 

782 

783 return self._proxied.execute( 

784 statement, 

785 params=params, 

786 execution_options=execution_options, 

787 bind_arguments=bind_arguments, 

788 _parent_execute_state=_parent_execute_state, 

789 _add_event=_add_event, 

790 ) 

791 

792 def expire( 

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

794 ) -> None: 

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

796 

797 .. container:: class_bases 

798 

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

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

801 

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

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

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

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

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

807 previously read in that same transaction, regardless of changes 

808 in database state outside of that transaction. 

809 

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

811 use :meth:`Session.expire_all`. 

812 

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

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

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

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

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

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

819 transaction. 

820 

821 :param instance: The instance to be refreshed. 

822 :param attribute_names: optional list of string attribute names 

823 indicating a subset of attributes to be expired. 

824 

825 .. seealso:: 

826 

827 :ref:`session_expire` - introductory material 

828 

829 :meth:`.Session.expire` 

830 

831 :meth:`.Session.refresh` 

832 

833 :meth:`_orm.Query.populate_existing` 

834 

835 

836 """ # noqa: E501 

837 

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

839 

840 def expire_all(self) -> None: 

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

842 

843 .. container:: class_bases 

844 

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

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

847 

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

849 a query will be issued using the 

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

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

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

853 previously read in that same transaction, regardless of changes 

854 in database state outside of that transaction. 

855 

856 To expire individual objects and individual attributes 

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

858 

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

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

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

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

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

864 assuming the transaction is isolated. 

865 

866 .. seealso:: 

867 

868 :ref:`session_expire` - introductory material 

869 

870 :meth:`.Session.expire` 

871 

872 :meth:`.Session.refresh` 

873 

874 :meth:`_orm.Query.populate_existing` 

875 

876 

877 """ # noqa: E501 

878 

879 return self._proxied.expire_all() 

880 

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

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

883 

884 .. container:: class_bases 

885 

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

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

888 

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

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

891 

892 

893 """ # noqa: E501 

894 

895 return self._proxied.expunge(instance) 

896 

897 def expunge_all(self) -> None: 

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

899 

900 .. container:: class_bases 

901 

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

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

904 

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

906 ``Session``. 

907 

908 

909 """ # noqa: E501 

910 

911 return self._proxied.expunge_all() 

912 

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

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

915 

916 .. container:: class_bases 

917 

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

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

920 

921 Writes out all pending object creations, deletions and modifications 

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

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

924 solver. 

925 

926 Database operations will be issued in the current transactional 

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

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

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

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

931 

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

933 only on elements that are in the given collection. 

934 

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

936 particular objects may need to be operated upon before the 

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

938 

939 

940 """ # noqa: E501 

941 

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

943 

944 def get( 

945 self, 

946 entity: _EntityBindKey[_O], 

947 ident: _PKIdentityArgument, 

948 *, 

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

950 populate_existing: bool = False, 

951 with_for_update: ForUpdateParameter = None, 

952 identity_token: Optional[Any] = None, 

953 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

954 bind_arguments: Optional[_BindArguments] = None, 

955 ) -> Optional[_O]: 

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

957 or ``None`` if not found. 

958 

959 .. container:: class_bases 

960 

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

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

963 

964 E.g.:: 

965 

966 my_user = session.get(User, 5) 

967 

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

969 

970 some_object = session.get( 

971 VersionedFoo, 

972 {"id": 5, "version_id": 10} 

973 ) 

974 

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

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

977 

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

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

980 If the given primary key identifier is present 

981 in the local identity map, the object is returned 

982 directly from this collection and no SQL is emitted, 

983 unless the object has been marked fully expired. 

984 If not present, 

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

986 

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

988 the object is present in the identity map and 

989 marked as expired - a SELECT 

990 is emitted to refresh the object as well as to 

991 ensure that the row is still present. 

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

993 

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

995 type of entity to be loaded. 

996 

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

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

999 a tuple or dictionary should be passed. 

1000 

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

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

1003 the call looks like:: 

1004 

1005 my_object = session.get(SomeClass, 5) 

1006 

1007 The tuple form contains primary key values typically in 

1008 the order in which they correspond to the mapped 

1009 :class:`_schema.Table` 

1010 object's primary key columns, or if the 

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

1012 used, in 

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

1014 of a row is represented by the integer 

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

1016 

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

1018 

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

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

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

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

1023 

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

1025 

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

1027 applied to the query, if one is emitted. 

1028 

1029 :param populate_existing: causes the method to unconditionally emit 

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

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

1032 

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

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

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

1036 flags should match the parameters of 

1037 :meth:`_query.Query.with_for_update`. 

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

1039 

1040 :param execution_options: optional dictionary of execution options, 

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

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

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

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

1045 

1046 .. versionadded:: 1.4.29 

1047 

1048 .. seealso:: 

1049 

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

1051 options 

1052 

1053 :param bind_arguments: dictionary of additional arguments to determine 

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

1055 Contents of this dictionary are passed to the 

1056 :meth:`.Session.get_bind` method. 

1057 

1058 .. versionadded: 2.0.0rc1 

1059 

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

1061 

1062 

1063 """ # noqa: E501 

1064 

1065 return self._proxied.get( 

1066 entity, 

1067 ident, 

1068 options=options, 

1069 populate_existing=populate_existing, 

1070 with_for_update=with_for_update, 

1071 identity_token=identity_token, 

1072 execution_options=execution_options, 

1073 bind_arguments=bind_arguments, 

1074 ) 

1075 

1076 def get_one( 

1077 self, 

1078 entity: _EntityBindKey[_O], 

1079 ident: _PKIdentityArgument, 

1080 *, 

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

1082 populate_existing: bool = False, 

1083 with_for_update: ForUpdateParameter = None, 

1084 identity_token: Optional[Any] = None, 

1085 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1086 bind_arguments: Optional[_BindArguments] = None, 

1087 ) -> _O: 

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

1089 identifier, or raise an exception if not found. 

1090 

1091 .. container:: class_bases 

1092 

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

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

1095 

1096 Raises ``sqlalchemy.orm.exc.NoResultFound`` if the query 

1097 selects no rows. 

1098 

1099 For a detailed documentation of the arguments see the 

1100 method :meth:`.Session.get`. 

1101 

1102 .. versionadded:: 2.0.22 

1103 

1104 :return: The object instance. 

1105 

1106 .. seealso:: 

1107 

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

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

1110 key 

1111 

1112 

1113 """ # noqa: E501 

1114 

1115 return self._proxied.get_one( 

1116 entity, 

1117 ident, 

1118 options=options, 

1119 populate_existing=populate_existing, 

1120 with_for_update=with_for_update, 

1121 identity_token=identity_token, 

1122 execution_options=execution_options, 

1123 bind_arguments=bind_arguments, 

1124 ) 

1125 

1126 def get_bind( 

1127 self, 

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

1129 *, 

1130 clause: Optional[ClauseElement] = None, 

1131 bind: Optional[_SessionBind] = None, 

1132 _sa_skip_events: Optional[bool] = None, 

1133 _sa_skip_for_implicit_returning: bool = False, 

1134 **kw: Any, 

1135 ) -> Union[Engine, Connection]: 

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

1137 

1138 .. container:: class_bases 

1139 

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

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

1142 

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

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

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

1146 

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

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

1149 appropriate bind to return. 

1150 

1151 Note that the "mapper" argument is usually present 

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

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

1154 individual INSERT/UPDATE/DELETE operation within a 

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

1156 

1157 The order of resolution is: 

1158 

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

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

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

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

1163 superclasses to more general. 

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

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

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

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

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

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

1170 associated with the clause. 

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

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

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

1174 selectable to which the mapper is mapped. 

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

1176 is raised. 

1177 

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

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

1180 of bind resolution scheme. See the example at 

1181 :ref:`session_custom_partitioning`. 

1182 

1183 :param mapper: 

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

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

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

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

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

1189 mapped for a bind. 

1190 

1191 :param clause: 

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

1193 :func:`_expression.select`, 

1194 :func:`_expression.text`, 

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

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

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

1198 associated with 

1199 bound :class:`_schema.MetaData`. 

1200 

1201 .. seealso:: 

1202 

1203 :ref:`session_partitioning` 

1204 

1205 :paramref:`.Session.binds` 

1206 

1207 :meth:`.Session.bind_mapper` 

1208 

1209 :meth:`.Session.bind_table` 

1210 

1211 

1212 """ # noqa: E501 

1213 

1214 return self._proxied.get_bind( 

1215 mapper=mapper, 

1216 clause=clause, 

1217 bind=bind, 

1218 _sa_skip_events=_sa_skip_events, 

1219 _sa_skip_for_implicit_returning=_sa_skip_for_implicit_returning, 

1220 **kw, 

1221 ) 

1222 

1223 def is_modified( 

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

1225 ) -> bool: 

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

1227 modified attributes. 

1228 

1229 .. container:: class_bases 

1230 

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

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

1233 

1234 This method retrieves the history for each instrumented 

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

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

1237 

1238 It is in effect a more expensive and accurate 

1239 version of checking for the given instance in the 

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

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

1242 

1243 E.g.:: 

1244 

1245 return session.is_modified(someobject) 

1246 

1247 A few caveats to this method apply: 

1248 

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

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

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

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

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

1254 change here. 

1255 * Scalar attributes may not have recorded the previously set 

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

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

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

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

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

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

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

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

1264 expensive on average than issuing a defensive SELECT. 

1265 

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

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

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

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

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

1271 argument with :func:`.column_property`. 

1272 

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

1274 :param include_collections: Indicates if multivalued collections 

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

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

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

1278 instance upon flush. 

1279 

1280 

1281 """ # noqa: E501 

1282 

1283 return self._proxied.is_modified( 

1284 instance, include_collections=include_collections 

1285 ) 

1286 

1287 def bulk_save_objects( 

1288 self, 

1289 objects: Iterable[object], 

1290 return_defaults: bool = False, 

1291 update_changed_only: bool = True, 

1292 preserve_order: bool = True, 

1293 ) -> None: 

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

1295 

1296 .. container:: class_bases 

1297 

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

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

1300 

1301 .. legacy:: 

1302 

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

1304 SQLAlchemy. For modern bulk INSERT and UPDATE, see 

1305 the sections :ref:`orm_queryguide_bulk_insert` and 

1306 :ref:`orm_queryguide_bulk_update`. 

1307 

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

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

1310 introduced in the :ref:`unified_tutorial` at 

1311 :ref:`tutorial_orm_data_manipulation`. SQLAlchemy 2.0 

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

1313 which solves previous issues of bulk INSERT slowness. 

1314 

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

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

1317 :class:`.Session` afterwards. 

1318 

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

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

1321 in traditional operation; if the object has the 

1322 :attr:`.InstanceState.key` 

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

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

1325 

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

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

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

1329 attributes present within each object are applied to the UPDATE 

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

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

1332 overhead of checking history on attributes. 

1333 

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

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

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

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

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

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

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

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

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

1343 approach. 

1344 

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

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

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

1348 with the exception of primary key attributes. 

1349 

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

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

1352 False, common types of objects are grouped into inserts 

1353 and updates, to allow for more batching opportunities. 

1354 

1355 .. seealso:: 

1356 

1357 :doc:`queryguide/dml` 

1358 

1359 :meth:`.Session.bulk_insert_mappings` 

1360 

1361 :meth:`.Session.bulk_update_mappings` 

1362 

1363 

1364 """ # noqa: E501 

1365 

1366 return self._proxied.bulk_save_objects( 

1367 objects, 

1368 return_defaults=return_defaults, 

1369 update_changed_only=update_changed_only, 

1370 preserve_order=preserve_order, 

1371 ) 

1372 

1373 def bulk_insert_mappings( 

1374 self, 

1375 mapper: Mapper[Any], 

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

1377 return_defaults: bool = False, 

1378 render_nulls: bool = False, 

1379 ) -> None: 

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

1381 

1382 .. container:: class_bases 

1383 

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

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

1386 

1387 .. legacy:: 

1388 

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

1390 SQLAlchemy. For modern bulk INSERT and UPDATE, see 

1391 the sections :ref:`orm_queryguide_bulk_insert` and 

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

1393 implementation details with this method and adds new features 

1394 as well. 

1395 

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

1397 object, 

1398 representing the single kind of object represented within the mapping 

1399 list. 

1400 

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

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

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

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

1405 keys to be populated into all tables. 

1406 

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

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

1409 The rationale for this parameter is typically to enable 

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

1411 be bulk inserted. 

1412 

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

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

1415 parameter can significantly decrease performance as INSERT 

1416 statements can no longer be batched. See 

1417 :ref:`engine_insertmanyvalues` 

1418 for background on which backends are affected. 

1419 

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

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

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

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

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

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

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

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

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

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

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

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

1432 necessary. 

1433 

1434 .. warning:: 

1435 

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

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

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

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

1440 invoked for the operation as a whole. 

1441 

1442 .. seealso:: 

1443 

1444 :doc:`queryguide/dml` 

1445 

1446 :meth:`.Session.bulk_save_objects` 

1447 

1448 :meth:`.Session.bulk_update_mappings` 

1449 

1450 

1451 """ # noqa: E501 

1452 

1453 return self._proxied.bulk_insert_mappings( 

1454 mapper, 

1455 mappings, 

1456 return_defaults=return_defaults, 

1457 render_nulls=render_nulls, 

1458 ) 

1459 

1460 def bulk_update_mappings( 

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

1462 ) -> None: 

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

1464 

1465 .. container:: class_bases 

1466 

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

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

1469 

1470 .. legacy:: 

1471 

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

1473 SQLAlchemy. For modern bulk INSERT and UPDATE, see 

1474 the sections :ref:`orm_queryguide_bulk_insert` and 

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

1476 implementation details with this method and adds new features 

1477 as well. 

1478 

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

1480 object, 

1481 representing the single kind of object represented within the mapping 

1482 list. 

1483 

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

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

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

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

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

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

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

1491 applied to the WHERE clause. 

1492 

1493 

1494 .. seealso:: 

1495 

1496 :doc:`queryguide/dml` 

1497 

1498 :meth:`.Session.bulk_insert_mappings` 

1499 

1500 :meth:`.Session.bulk_save_objects` 

1501 

1502 

1503 """ # noqa: E501 

1504 

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

1506 

1507 def merge( 

1508 self, 

1509 instance: _O, 

1510 *, 

1511 load: bool = True, 

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

1513 ) -> _O: 

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

1515 within this :class:`.Session`. 

1516 

1517 .. container:: class_bases 

1518 

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

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

1521 

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

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

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

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

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

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

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

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

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

1531 

1532 This operation cascades to associated instances if the association is 

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

1534 

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

1536 

1537 :param instance: Instance to be merged. 

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

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

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

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

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

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

1544 without re-querying the database. 

1545 

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

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

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

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

1550 the merge operation populates local attributes and 

1551 cascades to related objects and 

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

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

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

1555 any existing related objects or collections that might not 

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

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

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

1559 method. 

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

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

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

1563 

1564 .. versionadded:: 1.4.24 

1565 

1566 

1567 .. seealso:: 

1568 

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

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

1571 

1572 

1573 """ # noqa: E501 

1574 

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

1576 

1577 @overload 

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

1579 

1580 @overload 

1581 def query( 

1582 self, _colexpr: TypedColumnsClauseRole[_T] 

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

1584 

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

1586 

1587 # code within this block is **programmatically, 

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

1589 

1590 @overload 

1591 def query( 

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

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

1594 

1595 @overload 

1596 def query( 

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

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

1599 

1600 @overload 

1601 def query( 

1602 self, 

1603 __ent0: _TCCA[_T0], 

1604 __ent1: _TCCA[_T1], 

1605 __ent2: _TCCA[_T2], 

1606 __ent3: _TCCA[_T3], 

1607 /, 

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

1609 

1610 @overload 

1611 def query( 

1612 self, 

1613 __ent0: _TCCA[_T0], 

1614 __ent1: _TCCA[_T1], 

1615 __ent2: _TCCA[_T2], 

1616 __ent3: _TCCA[_T3], 

1617 __ent4: _TCCA[_T4], 

1618 /, 

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

1620 

1621 @overload 

1622 def query( 

1623 self, 

1624 __ent0: _TCCA[_T0], 

1625 __ent1: _TCCA[_T1], 

1626 __ent2: _TCCA[_T2], 

1627 __ent3: _TCCA[_T3], 

1628 __ent4: _TCCA[_T4], 

1629 __ent5: _TCCA[_T5], 

1630 /, 

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

1632 

1633 @overload 

1634 def query( 

1635 self, 

1636 __ent0: _TCCA[_T0], 

1637 __ent1: _TCCA[_T1], 

1638 __ent2: _TCCA[_T2], 

1639 __ent3: _TCCA[_T3], 

1640 __ent4: _TCCA[_T4], 

1641 __ent5: _TCCA[_T5], 

1642 __ent6: _TCCA[_T6], 

1643 /, 

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

1645 

1646 @overload 

1647 def query( 

1648 self, 

1649 __ent0: _TCCA[_T0], 

1650 __ent1: _TCCA[_T1], 

1651 __ent2: _TCCA[_T2], 

1652 __ent3: _TCCA[_T3], 

1653 __ent4: _TCCA[_T4], 

1654 __ent5: _TCCA[_T5], 

1655 __ent6: _TCCA[_T6], 

1656 __ent7: _TCCA[_T7], 

1657 /, 

1658 *entities: _ColumnsClauseArgument[Any], 

1659 ) -> RowReturningQuery[ 

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

1661 ]: ... 

1662 

1663 # END OVERLOADED FUNCTIONS self.query 

1664 

1665 @overload 

1666 def query( 

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

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

1669 

1670 def query( 

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

1672 ) -> Query[Any]: 

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

1674 :class:`_orm.Session`. 

1675 

1676 .. container:: class_bases 

1677 

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

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

1680 

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

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

1683 to construct ORM queries. 

1684 

1685 .. seealso:: 

1686 

1687 :ref:`unified_tutorial` 

1688 

1689 :ref:`queryguide_toplevel` 

1690 

1691 :ref:`query_api_toplevel` - legacy API doc 

1692 

1693 

1694 """ # noqa: E501 

1695 

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

1697 

1698 def refresh( 

1699 self, 

1700 instance: object, 

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

1702 with_for_update: ForUpdateParameter = None, 

1703 ) -> None: 

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

1705 

1706 .. container:: class_bases 

1707 

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

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

1710 

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

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

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

1714 value available in the current transaction. 

1715 

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

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

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

1719 

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

1721 can also refresh eagerly loaded attributes. 

1722 

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

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

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

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

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

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

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

1730 refreshed. 

1731 

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

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

1734 attributes for those which are named explicitly in the 

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

1736 

1737 .. tip:: 

1738 

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

1740 refreshing both column and relationship oriented attributes, its 

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

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

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

1744 once while having explicit control over relationship loader 

1745 strategies, use the 

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

1747 instead. 

1748 

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

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

1751 in database state outside of that transaction. Refreshing 

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

1753 where database rows have not yet been accessed. 

1754 

1755 :param attribute_names: optional. An iterable collection of 

1756 string attribute names indicating a subset of attributes to 

1757 be refreshed. 

1758 

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

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

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

1762 flags should match the parameters of 

1763 :meth:`_query.Query.with_for_update`. 

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

1765 

1766 .. seealso:: 

1767 

1768 :ref:`session_expire` - introductory material 

1769 

1770 :meth:`.Session.expire` 

1771 

1772 :meth:`.Session.expire_all` 

1773 

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

1775 to refresh objects as they would be loaded normally. 

1776 

1777 

1778 """ # noqa: E501 

1779 

1780 return self._proxied.refresh( 

1781 instance, 

1782 attribute_names=attribute_names, 

1783 with_for_update=with_for_update, 

1784 ) 

1785 

1786 def rollback(self) -> None: 

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

1788 

1789 .. container:: class_bases 

1790 

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

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

1793 

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

1795 

1796 The method always rolls back 

1797 the topmost database transaction, discarding any nested 

1798 transactions that may be in progress. 

1799 

1800 .. seealso:: 

1801 

1802 :ref:`session_rollback` 

1803 

1804 :ref:`unitofwork_transaction` 

1805 

1806 

1807 """ # noqa: E501 

1808 

1809 return self._proxied.rollback() 

1810 

1811 @overload 

1812 def scalar( 

1813 self, 

1814 statement: TypedReturnsRows[_T], 

1815 params: Optional[_CoreSingleExecuteParams] = None, 

1816 *, 

1817 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1818 bind_arguments: Optional[_BindArguments] = None, 

1819 **kw: Any, 

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

1821 

1822 @overload 

1823 def scalar( 

1824 self, 

1825 statement: Executable, 

1826 params: Optional[_CoreSingleExecuteParams] = None, 

1827 *, 

1828 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1829 bind_arguments: Optional[_BindArguments] = None, 

1830 **kw: Any, 

1831 ) -> Any: ... 

1832 

1833 def scalar( 

1834 self, 

1835 statement: Executable, 

1836 params: Optional[_CoreSingleExecuteParams] = None, 

1837 *, 

1838 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1839 bind_arguments: Optional[_BindArguments] = None, 

1840 **kw: Any, 

1841 ) -> Any: 

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

1843 

1844 .. container:: class_bases 

1845 

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

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

1848 

1849 Usage and parameters are the same as that of 

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

1851 value. 

1852 

1853 

1854 """ # noqa: E501 

1855 

1856 return self._proxied.scalar( 

1857 statement, 

1858 params=params, 

1859 execution_options=execution_options, 

1860 bind_arguments=bind_arguments, 

1861 **kw, 

1862 ) 

1863 

1864 @overload 

1865 def scalars( 

1866 self, 

1867 statement: TypedReturnsRows[_T], 

1868 params: Optional[_CoreAnyExecuteParams] = None, 

1869 *, 

1870 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1871 bind_arguments: Optional[_BindArguments] = None, 

1872 **kw: Any, 

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

1874 

1875 @overload 

1876 def scalars( 

1877 self, 

1878 statement: Executable, 

1879 params: Optional[_CoreAnyExecuteParams] = None, 

1880 *, 

1881 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1882 bind_arguments: Optional[_BindArguments] = None, 

1883 **kw: Any, 

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

1885 

1886 def scalars( 

1887 self, 

1888 statement: Executable, 

1889 params: Optional[_CoreAnyExecuteParams] = None, 

1890 *, 

1891 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1892 bind_arguments: Optional[_BindArguments] = None, 

1893 **kw: Any, 

1894 ) -> ScalarResult[Any]: 

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

1896 

1897 .. container:: class_bases 

1898 

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

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

1901 

1902 Usage and parameters are the same as that of 

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

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

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

1906 

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

1908 

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

1910 

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

1912 

1913 .. seealso:: 

1914 

1915 :ref:`orm_queryguide_select_orm_entities` - contrasts the behavior 

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

1917 

1918 

1919 """ # noqa: E501 

1920 

1921 return self._proxied.scalars( 

1922 statement, 

1923 params=params, 

1924 execution_options=execution_options, 

1925 bind_arguments=bind_arguments, 

1926 **kw, 

1927 ) 

1928 

1929 @property 

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

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

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

1933 

1934 """ # noqa: E501 

1935 

1936 return self._proxied.bind 

1937 

1938 @bind.setter 

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

1940 self._proxied.bind = attr 

1941 

1942 @property 

1943 def dirty(self) -> Any: 

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

1945 

1946 .. container:: class_bases 

1947 

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

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

1950 

1951 E.g.:: 

1952 

1953 some_mapped_object in session.dirty 

1954 

1955 Instances are considered dirty when they were modified but not 

1956 deleted. 

1957 

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

1959 attribute-setting or collection modification operations will 

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

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

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

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

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

1965 it's only done at flush time). 

1966 

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

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

1969 

1970 

1971 """ # noqa: E501 

1972 

1973 return self._proxied.dirty 

1974 

1975 @property 

1976 def deleted(self) -> Any: 

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

1978 

1979 .. container:: class_bases 

1980 

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

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

1983 

1984 """ # noqa: E501 

1985 

1986 return self._proxied.deleted 

1987 

1988 @property 

1989 def new(self) -> Any: 

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

1991 

1992 .. container:: class_bases 

1993 

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

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

1996 

1997 """ # noqa: E501 

1998 

1999 return self._proxied.new 

2000 

2001 @property 

2002 def identity_map(self) -> IdentityMap: 

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

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

2005 

2006 """ # noqa: E501 

2007 

2008 return self._proxied.identity_map 

2009 

2010 @identity_map.setter 

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

2012 self._proxied.identity_map = attr 

2013 

2014 @property 

2015 def is_active(self) -> Any: 

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

2017 

2018 .. container:: class_bases 

2019 

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

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

2022 

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

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

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

2026 

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

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

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

2030 fully roll back the transaction. 

2031 

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

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

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

2035 

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

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

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

2039 

2040 .. seealso:: 

2041 

2042 :ref:`faq_session_rollback` 

2043 

2044 :meth:`_orm.Session.in_transaction` 

2045 

2046 

2047 """ # noqa: E501 

2048 

2049 return self._proxied.is_active 

2050 

2051 @property 

2052 def autoflush(self) -> bool: 

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

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

2055 

2056 """ # noqa: E501 

2057 

2058 return self._proxied.autoflush 

2059 

2060 @autoflush.setter 

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

2062 self._proxied.autoflush = attr 

2063 

2064 @property 

2065 def no_autoflush(self) -> Any: 

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

2067 

2068 .. container:: class_bases 

2069 

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

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

2072 

2073 e.g.:: 

2074 

2075 with session.no_autoflush: 

2076 

2077 some_object = SomeClass() 

2078 session.add(some_object) 

2079 # won't autoflush 

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

2081 

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

2083 will not be subject to flushes occurring upon query 

2084 access. This is useful when initializing a series 

2085 of objects which involve existing database queries, 

2086 where the uncompleted object should not yet be flushed. 

2087 

2088 

2089 """ # noqa: E501 

2090 

2091 return self._proxied.no_autoflush 

2092 

2093 @property 

2094 def info(self) -> Any: 

2095 r"""A user-modifiable dictionary. 

2096 

2097 .. container:: class_bases 

2098 

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

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

2101 

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

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

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

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

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

2107 

2108 

2109 """ # noqa: E501 

2110 

2111 return self._proxied.info 

2112 

2113 @classmethod 

2114 def close_all(cls) -> None: 

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

2116 

2117 .. container:: class_bases 

2118 

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

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

2121 

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

2123 

2124 """ # noqa: E501 

2125 

2126 return Session.close_all() 

2127 

2128 @classmethod 

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

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

2131 

2132 .. container:: class_bases 

2133 

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

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

2136 

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

2138 

2139 

2140 """ # noqa: E501 

2141 

2142 return Session.object_session(instance) 

2143 

2144 @classmethod 

2145 def identity_key( 

2146 cls, 

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

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

2149 *, 

2150 instance: Optional[Any] = None, 

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

2152 identity_token: Optional[Any] = None, 

2153 ) -> _IdentityKeyType[Any]: 

2154 r"""Return an identity key. 

2155 

2156 .. container:: class_bases 

2157 

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

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

2160 

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

2162 

2163 

2164 """ # noqa: E501 

2165 

2166 return Session.identity_key( 

2167 class_=class_, 

2168 ident=ident, 

2169 instance=instance, 

2170 row=row, 

2171 identity_token=identity_token, 

2172 ) 

2173 

2174 # END PROXY METHODS scoped_session 

2175 

2176 

2177ScopedSession = scoped_session 

2178"""Old name for backwards compatibility."""