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

248 statements  

1# orm/scoping.py 

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

3# <see AUTHORS file> 

4# 

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

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

7 

8from __future__ import annotations 

9 

10from typing import Any 

11from typing import Callable 

12from typing import Dict 

13from typing import Generic 

14from typing import Iterable 

15from typing import Iterator 

16from typing import Optional 

17from typing import overload 

18from typing import Sequence 

19from typing import Tuple 

20from typing import Type 

21from typing import TYPE_CHECKING 

22from typing import TypeVar 

23from typing import Union 

24 

25from .session import _S 

26from .session import Session 

27from .. import exc as sa_exc 

28from .. import util 

29from ..util import create_proxy_methods 

30from ..util import ScopedRegistry 

31from ..util import ThreadLocalRegistry 

32from ..util import warn 

33from ..util import warn_deprecated 

34from ..util.typing import Protocol 

35 

36if TYPE_CHECKING: 

37 from ._typing import _EntityType 

38 from ._typing import _IdentityKeyType 

39 from ._typing import OrmExecuteOptionsParameter 

40 from .identity import IdentityMap 

41 from .interfaces import ORMOption 

42 from .mapper import Mapper 

43 from .query import Query 

44 from .query import RowReturningQuery 

45 from .session import _BindArguments 

46 from .session import _EntityBindKey 

47 from .session import _PKIdentityArgument 

48 from .session import _SessionBind 

49 from .session import sessionmaker 

50 from .session import SessionTransaction 

51 from ..engine import Connection 

52 from ..engine import Engine 

53 from ..engine import Result 

54 from ..engine import Row 

55 from ..engine import RowMapping 

56 from ..engine.interfaces import _CoreAnyExecuteParams 

57 from ..engine.interfaces import _CoreSingleExecuteParams 

58 from ..engine.interfaces import CoreExecuteOptionsParameter 

59 from ..engine.result import ScalarResult 

60 from ..sql._typing import _ColumnsClauseArgument 

61 from ..sql._typing import _T0 

62 from ..sql._typing import _T1 

63 from ..sql._typing import _T2 

64 from ..sql._typing import _T3 

65 from ..sql._typing import _T4 

66 from ..sql._typing import _T5 

67 from ..sql._typing import _T6 

68 from ..sql._typing import _T7 

69 from ..sql._typing import _TypedColumnClauseArgument as _TCCA 

70 from ..sql.base import Executable 

71 from ..sql.elements import ClauseElement 

72 from ..sql.roles import TypedColumnsClauseRole 

73 from ..sql.selectable import ForUpdateParameter 

74 from ..sql.selectable import TypedReturnsRows 

75 

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

77 

78 

79class QueryPropertyDescriptor(Protocol): 

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

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

82 

83 .. versionadded:: 2.0.5 

84 

85 """ 

86 

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

88 

89 

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

91 

92__all__ = ["scoped_session"] 

93 

94 

95@create_proxy_methods( 

96 Session, 

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

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

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

100 methods=[ 

101 "__contains__", 

102 "__iter__", 

103 "add", 

104 "add_all", 

105 "begin", 

106 "begin_nested", 

107 "close", 

108 "reset", 

109 "commit", 

110 "connection", 

111 "delete", 

112 "execute", 

113 "expire", 

114 "expire_all", 

115 "expunge", 

116 "expunge_all", 

117 "flush", 

118 "get", 

119 "get_one", 

120 "get_bind", 

121 "is_modified", 

122 "bulk_save_objects", 

123 "bulk_insert_mappings", 

124 "bulk_update_mappings", 

125 "merge", 

126 "query", 

127 "refresh", 

128 "rollback", 

129 "scalar", 

130 "scalars", 

131 ], 

132 attributes=[ 

133 "bind", 

134 "dirty", 

135 "deleted", 

136 "new", 

137 "identity_map", 

138 "is_active", 

139 "autoflush", 

140 "no_autoflush", 

141 "info", 

142 ], 

143) 

144class scoped_session(Generic[_S]): 

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

146 

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

148 

149 .. note:: 

150 

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

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

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

154 

155 """ 

156 

157 _support_async: bool = False 

158 

159 session_factory: sessionmaker[_S] 

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

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

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

163 

164 registry: ScopedRegistry[_S] 

165 

166 def __init__( 

167 self, 

168 session_factory: sessionmaker[_S], 

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

170 ): 

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

172 

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

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

175 of :class:`.sessionmaker`. 

176 :param scopefunc: optional function which defines 

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

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

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

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

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

182 dictionary in order to store and retrieve the current 

183 :class:`.Session`. 

184 

185 """ 

186 self.session_factory = session_factory 

187 

188 if scopefunc: 

189 self.registry = ScopedRegistry(session_factory, scopefunc) 

190 else: 

191 self.registry = ThreadLocalRegistry(session_factory) 

192 

193 @property 

194 def _proxied(self) -> _S: 

195 return self.registry() 

196 

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

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

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

200 

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

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

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

204 and keyword arguments have been passed, 

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

206 

207 """ 

208 if kw: 

209 if self.registry.has(): 

210 raise sa_exc.InvalidRequestError( 

211 "Scoped session is already present; " 

212 "no new arguments may be specified." 

213 ) 

214 else: 

215 sess = self.session_factory(**kw) 

216 self.registry.set(sess) 

217 else: 

218 sess = self.registry() 

219 if not self._support_async and sess._is_asyncio: 

220 warn_deprecated( 

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

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

223 "Please use `async_scoped_session` instead.", 

224 "1.4.23", 

225 ) 

226 return sess 

227 

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

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

230 :class:`.scoped_session`. 

231 

232 See :meth:`.sessionmaker.configure`. 

233 

234 """ 

235 

236 if self.registry.has(): 

237 warn( 

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

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

240 "already been created." 

241 ) 

242 

243 self.session_factory.configure(**kwargs) 

244 

245 def remove(self) -> None: 

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

247 

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

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

250 transactional/connection resources still being held; transactions 

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

252 discarded. Upon next usage within the same scope, 

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

254 :class:`.Session` object. 

255 

256 """ 

257 

258 if self.registry.has(): 

259 self.registry().close() 

260 self.registry.clear() 

261 

262 def query_property( 

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

264 ) -> QueryPropertyDescriptor: 

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

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

267 :class:`.Session` when called. 

268 

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

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

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

272 

273 e.g.:: 

274 

275 from sqlalchemy.orm import QueryPropertyDescriptor 

276 from sqlalchemy.orm import scoped_session 

277 from sqlalchemy.orm import sessionmaker 

278 

279 Session = scoped_session(sessionmaker()) 

280 

281 

282 class MyClass: 

283 query: QueryPropertyDescriptor = Session.query_property() 

284 

285 

286 # after mappers are defined 

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

288 

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

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

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

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

293 keyword argument. 

294 

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

296 a class. 

297 

298 """ 

299 

300 class query: 

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

302 if query_cls: 

303 # custom query class 

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

305 else: 

306 # session's configured query class 

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

308 

309 return query() 

310 

311 # START PROXY METHODS scoped_session 

312 

313 # code within this block is **programmatically, 

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

315 

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

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

318 

319 .. container:: class_bases 

320 

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

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

323 

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

325 result of True. 

326 

327 

328 """ # noqa: E501 

329 

330 return self._proxied.__contains__(instance) 

331 

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

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

334 Session. 

335 

336 .. container:: class_bases 

337 

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

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

340 

341 

342 """ # noqa: E501 

343 

344 return self._proxied.__iter__() 

345 

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

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

348 

349 .. container:: class_bases 

350 

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

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

353 

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

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

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

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

358 

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

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

361 state directly. 

362 

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

364 objects which were transient when they were passed to 

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

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

367 :class:`_orm.Session`. 

368 

369 .. seealso:: 

370 

371 :meth:`_orm.Session.add_all` 

372 

373 :ref:`session_adding` - at :ref:`session_basics` 

374 

375 

376 """ # noqa: E501 

377 

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

379 

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

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

382 

383 .. container:: class_bases 

384 

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

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

387 

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

389 behavioral description. 

390 

391 .. seealso:: 

392 

393 :meth:`_orm.Session.add` 

394 

395 :ref:`session_adding` - at :ref:`session_basics` 

396 

397 

398 """ # noqa: E501 

399 

400 return self._proxied.add_all(instances) 

401 

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

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

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

405 

406 .. container:: class_bases 

407 

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

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

410 

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

412 so that normally it is not necessary to call the 

413 :meth:`_orm.Session.begin` 

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

415 the scope of when the transactional state is begun. 

416 

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

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

419 

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

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

422 documentation on SAVEPOINT transactions, please see 

423 :ref:`session_begin_nested`. 

424 

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

426 :class:`.SessionTransaction` 

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

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

429 an example. 

430 

431 .. seealso:: 

432 

433 :ref:`session_autobegin` 

434 

435 :ref:`unitofwork_transaction` 

436 

437 :meth:`.Session.begin_nested` 

438 

439 

440 

441 """ # noqa: E501 

442 

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

444 

445 def begin_nested(self) -> SessionTransaction: 

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

447 

448 .. container:: class_bases 

449 

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

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

452 

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

454 SAVEPOINT for this method to function correctly. 

455 

456 For documentation on SAVEPOINT 

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

458 

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

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

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

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

463 

464 .. seealso:: 

465 

466 :ref:`session_begin_nested` 

467 

468 :ref:`pysqlite_serializable` - special workarounds required 

469 with the SQLite driver in order for SAVEPOINT to work 

470 correctly. For asyncio use cases, see the section 

471 :ref:`aiosqlite_serializable`. 

472 

473 

474 """ # noqa: E501 

475 

476 return self._proxied.begin_nested() 

477 

478 def close(self) -> None: 

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

480 :class:`_orm.Session`. 

481 

482 .. container:: class_bases 

483 

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

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

486 

487 This expunges all ORM objects associated with this 

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

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

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

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

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

493 

494 .. tip:: 

495 

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

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

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

499 distinct "closed" state; it merely means 

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

501 and ORM objects. 

502 

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

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

505 any further action on the session will be forbidden. 

506 

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

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

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

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

511 

512 .. seealso:: 

513 

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

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

516 

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

518 ``close()`` with the parameter 

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

520 

521 

522 """ # noqa: E501 

523 

524 return self._proxied.close() 

525 

526 def reset(self) -> None: 

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

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

529 

530 .. container:: class_bases 

531 

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

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

534 

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

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

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

538 brand new, and ready to be used again. 

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

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

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

542 

543 .. versionadded:: 2.0.22 

544 

545 .. seealso:: 

546 

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

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

549 

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

551 prevent re-use of the Session when the parameter 

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

553 

554 """ # noqa: E501 

555 

556 return self._proxied.reset() 

557 

558 def commit(self) -> None: 

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

560 

561 .. container:: class_bases 

562 

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

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

565 

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

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

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

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

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

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

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

573 to disable this behavior. 

574 

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

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

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

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

579 normally affect the database unless pending flush changes were 

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

581 rules. 

582 

583 The outermost database transaction is committed unconditionally, 

584 automatically releasing any SAVEPOINTs in effect. 

585 

586 .. seealso:: 

587 

588 :ref:`session_committing` 

589 

590 :ref:`unitofwork_transaction` 

591 

592 :ref:`asyncio_orm_avoid_lazyloads` 

593 

594 

595 """ # noqa: E501 

596 

597 return self._proxied.commit() 

598 

599 def connection( 

600 self, 

601 bind_arguments: Optional[_BindArguments] = None, 

602 execution_options: Optional[CoreExecuteOptionsParameter] = None, 

603 ) -> Connection: 

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

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

606 

607 .. container:: class_bases 

608 

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

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

611 

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

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

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

615 returned (note that no 

616 transactional state is established with the DBAPI until the first 

617 SQL statement is emitted). 

618 

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

620 resolved through any of the optional keyword arguments. This 

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

622 

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

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

625 to :meth:`.Session.get_bind`. 

626 

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

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

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

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

631 the arguments are ignored. 

632 

633 .. seealso:: 

634 

635 :ref:`session_transaction_isolation` 

636 

637 

638 """ # noqa: E501 

639 

640 return self._proxied.connection( 

641 bind_arguments=bind_arguments, execution_options=execution_options 

642 ) 

643 

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

645 r"""Mark an instance as deleted. 

646 

647 .. container:: class_bases 

648 

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

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

651 

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

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

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

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

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

657 

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

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

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

661 is successfully committed, 

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

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

664 

665 .. seealso:: 

666 

667 :ref:`session_deleting` - at :ref:`session_basics` 

668 

669 

670 """ # noqa: E501 

671 

672 return self._proxied.delete(instance) 

673 

674 @overload 

675 def execute( 

676 self, 

677 statement: TypedReturnsRows[_T], 

678 params: Optional[_CoreAnyExecuteParams] = None, 

679 *, 

680 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

681 bind_arguments: Optional[_BindArguments] = None, 

682 _parent_execute_state: Optional[Any] = None, 

683 _add_event: Optional[Any] = None, 

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

685 

686 @overload 

687 def execute( 

688 self, 

689 statement: Executable, 

690 params: Optional[_CoreAnyExecuteParams] = None, 

691 *, 

692 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

693 bind_arguments: Optional[_BindArguments] = None, 

694 _parent_execute_state: Optional[Any] = None, 

695 _add_event: Optional[Any] = None, 

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

697 

698 def execute( 

699 self, 

700 statement: Executable, 

701 params: Optional[_CoreAnyExecuteParams] = None, 

702 *, 

703 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

704 bind_arguments: Optional[_BindArguments] = None, 

705 _parent_execute_state: Optional[Any] = None, 

706 _add_event: Optional[Any] = None, 

707 ) -> Result[Any]: 

708 r"""Execute a SQL expression construct. 

709 

710 .. container:: class_bases 

711 

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

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

714 

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

716 results of the statement execution. 

717 

718 E.g.:: 

719 

720 from sqlalchemy import select 

721 

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

723 

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

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

726 of :class:`_engine.Connection`. 

727 

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

729 now the primary point of ORM statement execution when using 

730 :term:`2.0 style` ORM usage. 

731 

732 :param statement: 

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

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

735 

736 :param params: 

737 Optional dictionary, or list of dictionaries, containing 

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

739 execution occurs; if a list of dictionaries, an 

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

741 must correspond to parameter names present in the statement. 

742 

743 :param execution_options: optional dictionary of execution options, 

744 which will be associated with the statement execution. This 

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

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

747 provide additional options understood only in an ORM context. 

748 

749 .. seealso:: 

750 

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

752 options 

753 

754 :param bind_arguments: dictionary of additional arguments to determine 

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

756 Contents of this dictionary are passed to the 

757 :meth:`.Session.get_bind` method. 

758 

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

760 

761 

762 

763 """ # noqa: E501 

764 

765 return self._proxied.execute( 

766 statement, 

767 params=params, 

768 execution_options=execution_options, 

769 bind_arguments=bind_arguments, 

770 _parent_execute_state=_parent_execute_state, 

771 _add_event=_add_event, 

772 ) 

773 

774 def expire( 

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

776 ) -> None: 

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

778 

779 .. container:: class_bases 

780 

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

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

783 

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

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

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

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

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

789 previously read in that same transaction, regardless of changes 

790 in database state outside of that transaction. 

791 

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

793 use :meth:`Session.expire_all`. 

794 

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

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

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

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

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

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

801 transaction. 

802 

803 :param instance: The instance to be refreshed. 

804 :param attribute_names: optional list of string attribute names 

805 indicating a subset of attributes to be expired. 

806 

807 .. seealso:: 

808 

809 :ref:`session_expire` - introductory material 

810 

811 :meth:`.Session.expire` 

812 

813 :meth:`.Session.refresh` 

814 

815 :meth:`_orm.Query.populate_existing` 

816 

817 

818 """ # noqa: E501 

819 

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

821 

822 def expire_all(self) -> None: 

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

824 

825 .. container:: class_bases 

826 

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

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

829 

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

831 a query will be issued using the 

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

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

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

835 previously read in that same transaction, regardless of changes 

836 in database state outside of that transaction. 

837 

838 To expire individual objects and individual attributes 

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

840 

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

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

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

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

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

846 assuming the transaction is isolated. 

847 

848 .. seealso:: 

849 

850 :ref:`session_expire` - introductory material 

851 

852 :meth:`.Session.expire` 

853 

854 :meth:`.Session.refresh` 

855 

856 :meth:`_orm.Query.populate_existing` 

857 

858 

859 """ # noqa: E501 

860 

861 return self._proxied.expire_all() 

862 

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

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

865 

866 .. container:: class_bases 

867 

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

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

870 

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

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

873 

874 

875 """ # noqa: E501 

876 

877 return self._proxied.expunge(instance) 

878 

879 def expunge_all(self) -> None: 

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

881 

882 .. container:: class_bases 

883 

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

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

886 

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

888 ``Session``. 

889 

890 

891 """ # noqa: E501 

892 

893 return self._proxied.expunge_all() 

894 

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

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

897 

898 .. container:: class_bases 

899 

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

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

902 

903 Writes out all pending object creations, deletions and modifications 

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

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

906 solver. 

907 

908 Database operations will be issued in the current transactional 

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

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

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

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

913 

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

915 only on elements that are in the given collection. 

916 

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

918 particular objects may need to be operated upon before the 

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

920 

921 

922 """ # noqa: E501 

923 

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

925 

926 def get( 

927 self, 

928 entity: _EntityBindKey[_O], 

929 ident: _PKIdentityArgument, 

930 *, 

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

932 populate_existing: bool = False, 

933 with_for_update: ForUpdateParameter = None, 

934 identity_token: Optional[Any] = None, 

935 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

936 bind_arguments: Optional[_BindArguments] = None, 

937 ) -> Optional[_O]: 

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

939 or ``None`` if not found. 

940 

941 .. container:: class_bases 

942 

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

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

945 

946 E.g.:: 

947 

948 my_user = session.get(User, 5) 

949 

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

951 

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

953 

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

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

956 

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

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

959 If the given primary key identifier is present 

960 in the local identity map, the object is returned 

961 directly from this collection and no SQL is emitted, 

962 unless the object has been marked fully expired. 

963 If not present, 

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

965 

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

967 the object is present in the identity map and 

968 marked as expired - a SELECT 

969 is emitted to refresh the object as well as to 

970 ensure that the row is still present. 

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

972 

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

974 type of entity to be loaded. 

975 

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

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

978 a tuple or dictionary should be passed. 

979 

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

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

982 the call looks like:: 

983 

984 my_object = session.get(SomeClass, 5) 

985 

986 The tuple form contains primary key values typically in 

987 the order in which they correspond to the mapped 

988 :class:`_schema.Table` 

989 object's primary key columns, or if the 

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

991 used, in 

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

993 of a row is represented by the integer 

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

995 

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

997 

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

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

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

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

1002 

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

1004 

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

1006 applied to the query, if one is emitted. 

1007 

1008 :param populate_existing: causes the method to unconditionally emit 

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

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

1011 

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

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

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

1015 flags should match the parameters of 

1016 :meth:`_query.Query.with_for_update`. 

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

1018 

1019 :param execution_options: optional dictionary of execution options, 

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

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

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

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

1024 

1025 .. versionadded:: 1.4.29 

1026 

1027 .. seealso:: 

1028 

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

1030 options 

1031 

1032 :param bind_arguments: dictionary of additional arguments to determine 

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

1034 Contents of this dictionary are passed to the 

1035 :meth:`.Session.get_bind` method. 

1036 

1037 .. versionadded: 2.0.0rc1 

1038 

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

1040 

1041 

1042 """ # noqa: E501 

1043 

1044 return self._proxied.get( 

1045 entity, 

1046 ident, 

1047 options=options, 

1048 populate_existing=populate_existing, 

1049 with_for_update=with_for_update, 

1050 identity_token=identity_token, 

1051 execution_options=execution_options, 

1052 bind_arguments=bind_arguments, 

1053 ) 

1054 

1055 def get_one( 

1056 self, 

1057 entity: _EntityBindKey[_O], 

1058 ident: _PKIdentityArgument, 

1059 *, 

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

1061 populate_existing: bool = False, 

1062 with_for_update: ForUpdateParameter = None, 

1063 identity_token: Optional[Any] = None, 

1064 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1065 bind_arguments: Optional[_BindArguments] = None, 

1066 ) -> _O: 

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

1068 identifier, or raise an exception if not found. 

1069 

1070 .. container:: class_bases 

1071 

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

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

1074 

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

1076 

1077 For a detailed documentation of the arguments see the 

1078 method :meth:`.Session.get`. 

1079 

1080 .. versionadded:: 2.0.22 

1081 

1082 :return: The object instance. 

1083 

1084 .. seealso:: 

1085 

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

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

1088 key 

1089 

1090 

1091 """ # noqa: E501 

1092 

1093 return self._proxied.get_one( 

1094 entity, 

1095 ident, 

1096 options=options, 

1097 populate_existing=populate_existing, 

1098 with_for_update=with_for_update, 

1099 identity_token=identity_token, 

1100 execution_options=execution_options, 

1101 bind_arguments=bind_arguments, 

1102 ) 

1103 

1104 def get_bind( 

1105 self, 

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

1107 *, 

1108 clause: Optional[ClauseElement] = None, 

1109 bind: Optional[_SessionBind] = None, 

1110 _sa_skip_events: Optional[bool] = None, 

1111 _sa_skip_for_implicit_returning: bool = False, 

1112 **kw: Any, 

1113 ) -> Union[Engine, Connection]: 

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

1115 

1116 .. container:: class_bases 

1117 

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

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

1120 

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

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

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

1124 

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

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

1127 appropriate bind to return. 

1128 

1129 Note that the "mapper" argument is usually present 

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

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

1132 individual INSERT/UPDATE/DELETE operation within a 

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

1134 

1135 The order of resolution is: 

1136 

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

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

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

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

1141 superclasses to more general. 

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

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

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

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

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

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

1148 associated with the clause. 

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

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

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

1152 selectable to which the mapper is mapped. 

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

1154 is raised. 

1155 

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

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

1158 of bind resolution scheme. See the example at 

1159 :ref:`session_custom_partitioning`. 

1160 

1161 :param mapper: 

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

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

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

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

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

1167 mapped for a bind. 

1168 

1169 :param clause: 

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

1171 :func:`_expression.select`, 

1172 :func:`_expression.text`, 

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

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

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

1176 associated with 

1177 bound :class:`_schema.MetaData`. 

1178 

1179 .. seealso:: 

1180 

1181 :ref:`session_partitioning` 

1182 

1183 :paramref:`.Session.binds` 

1184 

1185 :meth:`.Session.bind_mapper` 

1186 

1187 :meth:`.Session.bind_table` 

1188 

1189 

1190 """ # noqa: E501 

1191 

1192 return self._proxied.get_bind( 

1193 mapper=mapper, 

1194 clause=clause, 

1195 bind=bind, 

1196 _sa_skip_events=_sa_skip_events, 

1197 _sa_skip_for_implicit_returning=_sa_skip_for_implicit_returning, 

1198 **kw, 

1199 ) 

1200 

1201 def is_modified( 

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

1203 ) -> bool: 

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

1205 modified attributes. 

1206 

1207 .. container:: class_bases 

1208 

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

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

1211 

1212 This method retrieves the history for each instrumented 

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

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

1215 

1216 It is in effect a more expensive and accurate 

1217 version of checking for the given instance in the 

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

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

1220 

1221 E.g.:: 

1222 

1223 return session.is_modified(someobject) 

1224 

1225 A few caveats to this method apply: 

1226 

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

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

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

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

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

1232 change here. 

1233 * Scalar attributes may not have recorded the previously set 

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

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

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

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

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

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

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

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

1242 expensive on average than issuing a defensive SELECT. 

1243 

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

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

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

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

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

1249 argument with :func:`.column_property`. 

1250 

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

1252 :param include_collections: Indicates if multivalued collections 

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

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

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

1256 instance upon flush. 

1257 

1258 

1259 """ # noqa: E501 

1260 

1261 return self._proxied.is_modified( 

1262 instance, include_collections=include_collections 

1263 ) 

1264 

1265 def bulk_save_objects( 

1266 self, 

1267 objects: Iterable[object], 

1268 return_defaults: bool = False, 

1269 update_changed_only: bool = True, 

1270 preserve_order: bool = True, 

1271 ) -> None: 

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

1273 

1274 .. container:: class_bases 

1275 

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

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

1278 

1279 .. legacy:: 

1280 

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

1282 SQLAlchemy. For modern bulk INSERT and UPDATE, see 

1283 the sections :ref:`orm_queryguide_bulk_insert` and 

1284 :ref:`orm_queryguide_bulk_update`. 

1285 

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

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

1288 introduced in the :ref:`unified_tutorial` at 

1289 :ref:`tutorial_orm_data_manipulation`. SQLAlchemy 2.0 

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

1291 which solves previous issues of bulk INSERT slowness. 

1292 

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

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

1295 :class:`.Session` afterwards. 

1296 

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

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

1299 in traditional operation; if the object has the 

1300 :attr:`.InstanceState.key` 

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

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

1303 

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

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

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

1307 attributes present within each object are applied to the UPDATE 

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

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

1310 overhead of checking history on attributes. 

1311 

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

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

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

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

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

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

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

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

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

1321 approach. 

1322 

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

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

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

1326 with the exception of primary key attributes. 

1327 

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

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

1330 False, common types of objects are grouped into inserts 

1331 and updates, to allow for more batching opportunities. 

1332 

1333 .. seealso:: 

1334 

1335 :doc:`queryguide/dml` 

1336 

1337 :meth:`.Session.bulk_insert_mappings` 

1338 

1339 :meth:`.Session.bulk_update_mappings` 

1340 

1341 

1342 """ # noqa: E501 

1343 

1344 return self._proxied.bulk_save_objects( 

1345 objects, 

1346 return_defaults=return_defaults, 

1347 update_changed_only=update_changed_only, 

1348 preserve_order=preserve_order, 

1349 ) 

1350 

1351 def bulk_insert_mappings( 

1352 self, 

1353 mapper: Mapper[Any], 

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

1355 return_defaults: bool = False, 

1356 render_nulls: bool = False, 

1357 ) -> None: 

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

1359 

1360 .. container:: class_bases 

1361 

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

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

1364 

1365 .. legacy:: 

1366 

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

1368 SQLAlchemy. For modern bulk INSERT and UPDATE, see 

1369 the sections :ref:`orm_queryguide_bulk_insert` and 

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

1371 implementation details with this method and adds new features 

1372 as well. 

1373 

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

1375 object, 

1376 representing the single kind of object represented within the mapping 

1377 list. 

1378 

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

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

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

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

1383 keys to be populated into all tables. 

1384 

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

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

1387 The rationale for this parameter is typically to enable 

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

1389 be bulk inserted. 

1390 

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

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

1393 parameter can significantly decrease performance as INSERT 

1394 statements can no longer be batched. See 

1395 :ref:`engine_insertmanyvalues` 

1396 for background on which backends are affected. 

1397 

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

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

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

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

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

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

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

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

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

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

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

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

1410 necessary. 

1411 

1412 .. warning:: 

1413 

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

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

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

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

1418 invoked for the operation as a whole. 

1419 

1420 .. seealso:: 

1421 

1422 :doc:`queryguide/dml` 

1423 

1424 :meth:`.Session.bulk_save_objects` 

1425 

1426 :meth:`.Session.bulk_update_mappings` 

1427 

1428 

1429 """ # noqa: E501 

1430 

1431 return self._proxied.bulk_insert_mappings( 

1432 mapper, 

1433 mappings, 

1434 return_defaults=return_defaults, 

1435 render_nulls=render_nulls, 

1436 ) 

1437 

1438 def bulk_update_mappings( 

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

1440 ) -> None: 

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

1442 

1443 .. container:: class_bases 

1444 

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

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

1447 

1448 .. legacy:: 

1449 

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

1451 SQLAlchemy. For modern bulk INSERT and UPDATE, see 

1452 the sections :ref:`orm_queryguide_bulk_insert` and 

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

1454 implementation details with this method and adds new features 

1455 as well. 

1456 

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

1458 object, 

1459 representing the single kind of object represented within the mapping 

1460 list. 

1461 

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

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

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

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

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

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

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

1469 applied to the WHERE clause. 

1470 

1471 

1472 .. seealso:: 

1473 

1474 :doc:`queryguide/dml` 

1475 

1476 :meth:`.Session.bulk_insert_mappings` 

1477 

1478 :meth:`.Session.bulk_save_objects` 

1479 

1480 

1481 """ # noqa: E501 

1482 

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

1484 

1485 def merge( 

1486 self, 

1487 instance: _O, 

1488 *, 

1489 load: bool = True, 

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

1491 ) -> _O: 

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

1493 within this :class:`.Session`. 

1494 

1495 .. container:: class_bases 

1496 

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

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

1499 

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

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

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

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

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

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

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

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

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

1509 

1510 This operation cascades to associated instances if the association is 

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

1512 

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

1514 

1515 :param instance: Instance to be merged. 

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

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

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

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

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

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

1522 without re-querying the database. 

1523 

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

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

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

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

1528 the merge operation populates local attributes and 

1529 cascades to related objects and 

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

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

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

1533 any existing related objects or collections that might not 

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

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

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

1537 method. 

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

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

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

1541 

1542 .. versionadded:: 1.4.24 

1543 

1544 

1545 .. seealso:: 

1546 

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

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

1549 

1550 

1551 """ # noqa: E501 

1552 

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

1554 

1555 @overload 

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

1557 

1558 @overload 

1559 def query( 

1560 self, _colexpr: TypedColumnsClauseRole[_T] 

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

1562 

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

1564 

1565 # code within this block is **programmatically, 

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

1567 

1568 @overload 

1569 def query( 

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

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

1572 

1573 @overload 

1574 def query( 

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

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

1577 

1578 @overload 

1579 def query( 

1580 self, 

1581 __ent0: _TCCA[_T0], 

1582 __ent1: _TCCA[_T1], 

1583 __ent2: _TCCA[_T2], 

1584 __ent3: _TCCA[_T3], 

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

1586 

1587 @overload 

1588 def query( 

1589 self, 

1590 __ent0: _TCCA[_T0], 

1591 __ent1: _TCCA[_T1], 

1592 __ent2: _TCCA[_T2], 

1593 __ent3: _TCCA[_T3], 

1594 __ent4: _TCCA[_T4], 

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

1596 

1597 @overload 

1598 def query( 

1599 self, 

1600 __ent0: _TCCA[_T0], 

1601 __ent1: _TCCA[_T1], 

1602 __ent2: _TCCA[_T2], 

1603 __ent3: _TCCA[_T3], 

1604 __ent4: _TCCA[_T4], 

1605 __ent5: _TCCA[_T5], 

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

1607 

1608 @overload 

1609 def query( 

1610 self, 

1611 __ent0: _TCCA[_T0], 

1612 __ent1: _TCCA[_T1], 

1613 __ent2: _TCCA[_T2], 

1614 __ent3: _TCCA[_T3], 

1615 __ent4: _TCCA[_T4], 

1616 __ent5: _TCCA[_T5], 

1617 __ent6: _TCCA[_T6], 

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

1619 

1620 @overload 

1621 def query( 

1622 self, 

1623 __ent0: _TCCA[_T0], 

1624 __ent1: _TCCA[_T1], 

1625 __ent2: _TCCA[_T2], 

1626 __ent3: _TCCA[_T3], 

1627 __ent4: _TCCA[_T4], 

1628 __ent5: _TCCA[_T5], 

1629 __ent6: _TCCA[_T6], 

1630 __ent7: _TCCA[_T7], 

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

1632 

1633 # END OVERLOADED FUNCTIONS self.query 

1634 

1635 @overload 

1636 def query( 

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

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

1639 

1640 def query( 

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

1642 ) -> Query[Any]: 

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

1644 :class:`_orm.Session`. 

1645 

1646 .. container:: class_bases 

1647 

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

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

1650 

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

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

1653 to construct ORM queries. 

1654 

1655 .. seealso:: 

1656 

1657 :ref:`unified_tutorial` 

1658 

1659 :ref:`queryguide_toplevel` 

1660 

1661 :ref:`query_api_toplevel` - legacy API doc 

1662 

1663 

1664 """ # noqa: E501 

1665 

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

1667 

1668 def refresh( 

1669 self, 

1670 instance: object, 

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

1672 with_for_update: ForUpdateParameter = None, 

1673 ) -> None: 

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

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 The selected attributes will first be expired as they would when using 

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

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

1684 value available in the current transaction. 

1685 

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

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

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

1689 

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

1691 can also refresh eagerly loaded attributes. 

1692 

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

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

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

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

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

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

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

1700 refreshed. 

1701 

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

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

1704 attributes for those which are named explicitly in the 

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

1706 

1707 .. tip:: 

1708 

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

1710 refreshing both column and relationship oriented attributes, its 

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

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

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

1714 once while having explicit control over relationship loader 

1715 strategies, use the 

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

1717 instead. 

1718 

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

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

1721 in database state outside of that transaction. Refreshing 

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

1723 where database rows have not yet been accessed. 

1724 

1725 :param attribute_names: optional. An iterable collection of 

1726 string attribute names indicating a subset of attributes to 

1727 be refreshed. 

1728 

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

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

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

1732 flags should match the parameters of 

1733 :meth:`_query.Query.with_for_update`. 

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

1735 

1736 .. seealso:: 

1737 

1738 :ref:`session_expire` - introductory material 

1739 

1740 :meth:`.Session.expire` 

1741 

1742 :meth:`.Session.expire_all` 

1743 

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

1745 to refresh objects as they would be loaded normally. 

1746 

1747 

1748 """ # noqa: E501 

1749 

1750 return self._proxied.refresh( 

1751 instance, 

1752 attribute_names=attribute_names, 

1753 with_for_update=with_for_update, 

1754 ) 

1755 

1756 def rollback(self) -> None: 

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

1758 

1759 .. container:: class_bases 

1760 

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

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

1763 

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

1765 

1766 The method always rolls back 

1767 the topmost database transaction, discarding any nested 

1768 transactions that may be in progress. 

1769 

1770 .. seealso:: 

1771 

1772 :ref:`session_rollback` 

1773 

1774 :ref:`unitofwork_transaction` 

1775 

1776 

1777 """ # noqa: E501 

1778 

1779 return self._proxied.rollback() 

1780 

1781 @overload 

1782 def scalar( 

1783 self, 

1784 statement: TypedReturnsRows[Tuple[_T]], 

1785 params: Optional[_CoreSingleExecuteParams] = None, 

1786 *, 

1787 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1788 bind_arguments: Optional[_BindArguments] = None, 

1789 **kw: Any, 

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

1791 

1792 @overload 

1793 def scalar( 

1794 self, 

1795 statement: Executable, 

1796 params: Optional[_CoreSingleExecuteParams] = None, 

1797 *, 

1798 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1799 bind_arguments: Optional[_BindArguments] = None, 

1800 **kw: Any, 

1801 ) -> Any: ... 

1802 

1803 def scalar( 

1804 self, 

1805 statement: Executable, 

1806 params: Optional[_CoreSingleExecuteParams] = None, 

1807 *, 

1808 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1809 bind_arguments: Optional[_BindArguments] = None, 

1810 **kw: Any, 

1811 ) -> Any: 

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

1813 

1814 .. container:: class_bases 

1815 

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

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

1818 

1819 Usage and parameters are the same as that of 

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

1821 value. 

1822 

1823 

1824 """ # noqa: E501 

1825 

1826 return self._proxied.scalar( 

1827 statement, 

1828 params=params, 

1829 execution_options=execution_options, 

1830 bind_arguments=bind_arguments, 

1831 **kw, 

1832 ) 

1833 

1834 @overload 

1835 def scalars( 

1836 self, 

1837 statement: TypedReturnsRows[Tuple[_T]], 

1838 params: Optional[_CoreAnyExecuteParams] = None, 

1839 *, 

1840 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1841 bind_arguments: Optional[_BindArguments] = None, 

1842 **kw: Any, 

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

1844 

1845 @overload 

1846 def scalars( 

1847 self, 

1848 statement: Executable, 

1849 params: Optional[_CoreAnyExecuteParams] = None, 

1850 *, 

1851 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1852 bind_arguments: Optional[_BindArguments] = None, 

1853 **kw: Any, 

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

1855 

1856 def scalars( 

1857 self, 

1858 statement: Executable, 

1859 params: Optional[_CoreAnyExecuteParams] = None, 

1860 *, 

1861 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1862 bind_arguments: Optional[_BindArguments] = None, 

1863 **kw: Any, 

1864 ) -> ScalarResult[Any]: 

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

1866 

1867 .. container:: class_bases 

1868 

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

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

1871 

1872 Usage and parameters are the same as that of 

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

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

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

1876 

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

1878 

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

1880 

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

1882 

1883 .. seealso:: 

1884 

1885 :ref:`orm_queryguide_select_orm_entities` - contrasts the behavior 

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

1887 

1888 

1889 """ # noqa: E501 

1890 

1891 return self._proxied.scalars( 

1892 statement, 

1893 params=params, 

1894 execution_options=execution_options, 

1895 bind_arguments=bind_arguments, 

1896 **kw, 

1897 ) 

1898 

1899 @property 

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

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

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

1903 

1904 """ # noqa: E501 

1905 

1906 return self._proxied.bind 

1907 

1908 @bind.setter 

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

1910 self._proxied.bind = attr 

1911 

1912 @property 

1913 def dirty(self) -> Any: 

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

1915 

1916 .. container:: class_bases 

1917 

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

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

1920 

1921 E.g.:: 

1922 

1923 some_mapped_object in session.dirty 

1924 

1925 Instances are considered dirty when they were modified but not 

1926 deleted. 

1927 

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

1929 attribute-setting or collection modification operations will 

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

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

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

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

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

1935 it's only done at flush time). 

1936 

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

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

1939 

1940 

1941 """ # noqa: E501 

1942 

1943 return self._proxied.dirty 

1944 

1945 @property 

1946 def deleted(self) -> Any: 

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

1948 

1949 .. container:: class_bases 

1950 

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

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

1953 

1954 """ # noqa: E501 

1955 

1956 return self._proxied.deleted 

1957 

1958 @property 

1959 def new(self) -> Any: 

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

1961 

1962 .. container:: class_bases 

1963 

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

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

1966 

1967 """ # noqa: E501 

1968 

1969 return self._proxied.new 

1970 

1971 @property 

1972 def identity_map(self) -> IdentityMap: 

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

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

1975 

1976 """ # noqa: E501 

1977 

1978 return self._proxied.identity_map 

1979 

1980 @identity_map.setter 

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

1982 self._proxied.identity_map = attr 

1983 

1984 @property 

1985 def is_active(self) -> Any: 

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

1987 

1988 .. container:: class_bases 

1989 

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

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

1992 

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

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

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

1996 

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

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

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

2000 fully roll back the transaction. 

2001 

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

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

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

2005 

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

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

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

2009 

2010 .. seealso:: 

2011 

2012 :ref:`faq_session_rollback` 

2013 

2014 :meth:`_orm.Session.in_transaction` 

2015 

2016 

2017 """ # noqa: E501 

2018 

2019 return self._proxied.is_active 

2020 

2021 @property 

2022 def autoflush(self) -> bool: 

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

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

2025 

2026 """ # noqa: E501 

2027 

2028 return self._proxied.autoflush 

2029 

2030 @autoflush.setter 

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

2032 self._proxied.autoflush = attr 

2033 

2034 @property 

2035 def no_autoflush(self) -> Any: 

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

2037 

2038 .. container:: class_bases 

2039 

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

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

2042 

2043 e.g.:: 

2044 

2045 with session.no_autoflush: 

2046 

2047 some_object = SomeClass() 

2048 session.add(some_object) 

2049 # won't autoflush 

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

2051 

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

2053 will not be subject to flushes occurring upon query 

2054 access. This is useful when initializing a series 

2055 of objects which involve existing database queries, 

2056 where the uncompleted object should not yet be flushed. 

2057 

2058 

2059 """ # noqa: E501 

2060 

2061 return self._proxied.no_autoflush 

2062 

2063 @property 

2064 def info(self) -> Any: 

2065 r"""A user-modifiable dictionary. 

2066 

2067 .. container:: class_bases 

2068 

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

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

2071 

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

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

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

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

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

2077 

2078 

2079 """ # noqa: E501 

2080 

2081 return self._proxied.info 

2082 

2083 @classmethod 

2084 def close_all(cls) -> None: 

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

2086 

2087 .. container:: class_bases 

2088 

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

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

2091 

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

2093 

2094 """ # noqa: E501 

2095 

2096 return Session.close_all() 

2097 

2098 @classmethod 

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

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

2101 

2102 .. container:: class_bases 

2103 

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

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

2106 

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

2108 

2109 

2110 """ # noqa: E501 

2111 

2112 return Session.object_session(instance) 

2113 

2114 @classmethod 

2115 def identity_key( 

2116 cls, 

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

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

2119 *, 

2120 instance: Optional[Any] = None, 

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

2122 identity_token: Optional[Any] = None, 

2123 ) -> _IdentityKeyType[Any]: 

2124 r"""Return an identity key. 

2125 

2126 .. container:: class_bases 

2127 

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

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

2130 

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

2132 

2133 

2134 """ # noqa: E501 

2135 

2136 return Session.identity_key( 

2137 class_=class_, 

2138 ident=ident, 

2139 instance=instance, 

2140 row=row, 

2141 identity_token=identity_token, 

2142 ) 

2143 

2144 # END PROXY METHODS scoped_session 

2145 

2146 

2147ScopedSession = scoped_session 

2148"""Old name for backwards compatibility."""