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

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

272 statements  

1# orm/scoping.py 

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

3# <see AUTHORS file> 

4# 

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

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

7 

8from __future__ import annotations 

9 

10from typing import Any 

11from typing import Callable 

12from typing import Dict 

13from typing import Generic 

14from typing import Iterable 

15from typing import Iterator 

16from typing import Mapping 

17from typing import Optional 

18from typing import overload 

19from typing import Protocol 

20from typing import Sequence 

21from typing import Tuple 

22from typing import Type 

23from typing import TYPE_CHECKING 

24from typing import TypeVar 

25from typing import Union 

26 

27from .session import _S 

28from .session import Session 

29from .. import exc as sa_exc 

30from .. import util 

31from ..util import create_proxy_methods 

32from ..util import ScopedRegistry 

33from ..util import ThreadLocalRegistry 

34from ..util import warn 

35from ..util import warn_deprecated 

36from ..util.typing import Never 

37from ..util.typing import TupleAny 

38from ..util.typing import TypeVarTuple 

39from ..util.typing import Unpack 

40 

41if TYPE_CHECKING: 

42 from ._typing import _EntityType 

43 from ._typing import _IdentityKeyType 

44 from ._typing import OrmExecuteOptionsParameter 

45 from .identity import IdentityMap 

46 from .interfaces import ORMOption 

47 from .query import Query 

48 from .query import RowReturningQuery 

49 from .session import _BindArguments 

50 from .session import _EntityBindKey 

51 from .session import _PKIdentityArgument 

52 from .session import _SessionBind 

53 from .session import _SessionBindKey 

54 from .session import sessionmaker 

55 from .session import SessionTransaction 

56 from ..engine import Connection 

57 from ..engine import Engine 

58 from ..engine import Result 

59 from ..engine import Row 

60 from ..engine import RowMapping 

61 from ..engine.interfaces import _CoreAnyExecuteParams 

62 from ..engine.interfaces import _CoreSingleExecuteParams 

63 from ..engine.interfaces import _ExecuteOptions 

64 from ..engine.interfaces import CoreExecuteOptionsParameter 

65 from ..engine.result import ScalarResult 

66 from ..sql._typing import _ColumnsClauseArgument 

67 from ..sql._typing import _InfoType 

68 from ..sql._typing import _T0 

69 from ..sql._typing import _T1 

70 from ..sql._typing import _T2 

71 from ..sql._typing import _T3 

72 from ..sql._typing import _T4 

73 from ..sql._typing import _T5 

74 from ..sql._typing import _T6 

75 from ..sql._typing import _T7 

76 from ..sql._typing import _TypedColumnClauseArgument as _TCCA 

77 from ..sql.base import Executable 

78 from ..sql.elements import ClauseElement 

79 from ..sql.roles import TypedColumnsClauseRole 

80 from ..sql.selectable import ForUpdateParameter 

81 from ..sql.selectable import TypedReturnsRows 

82 from ..util import IdentitySet 

83 

84 

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

86_Ts = TypeVarTuple("_Ts") 

87 

88 

89class QueryPropertyDescriptor(Protocol): 

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

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

92 

93 .. versionadded:: 2.0.5 

94 

95 """ 

96 

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

98 

99 

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

101 

102__all__ = ["scoped_session"] 

103 

104 

105@create_proxy_methods( 

106 Session, 

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

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

109 classmethods=["object_session", "identity_key"], 

110 methods=[ 

111 "__contains__", 

112 "__iter__", 

113 "add", 

114 "add_all", 

115 "begin", 

116 "begin_nested", 

117 "close", 

118 "reset", 

119 "commit", 

120 "connection", 

121 "delete", 

122 "delete_all", 

123 "execute", 

124 "expire", 

125 "expire_all", 

126 "expunge", 

127 "expunge_all", 

128 "flush", 

129 "get", 

130 "get_one", 

131 "get_bind", 

132 "is_modified", 

133 "bulk_save_objects", 

134 "bulk_insert_mappings", 

135 "bulk_update_mappings", 

136 "merge", 

137 "merge_all", 

138 "query", 

139 "refresh", 

140 "rollback", 

141 "scalar", 

142 "scalars", 

143 ], 

144 attributes=[ 

145 "bind", 

146 "binds", 

147 "dirty", 

148 "deleted", 

149 "new", 

150 "identity_map", 

151 "is_active", 

152 "autoflush", 

153 "no_autoflush", 

154 "info", 

155 "execution_options", 

156 ], 

157) 

158class scoped_session(Generic[_S]): 

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

160 

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

162 

163 .. note:: 

164 

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

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

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

168 

169 """ 

170 

171 _support_async: bool = False 

172 

173 session_factory: sessionmaker[_S] 

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

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

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

177 

178 registry: ScopedRegistry[_S] 

179 

180 def __init__( 

181 self, 

182 session_factory: sessionmaker[_S], 

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

184 ): 

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

186 

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

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

189 of :class:`.sessionmaker`. 

190 :param scopefunc: optional function which defines 

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

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

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

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

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

196 dictionary in order to store and retrieve the current 

197 :class:`.Session`. 

198 

199 """ 

200 self.session_factory = session_factory 

201 

202 if scopefunc: 

203 self.registry = ScopedRegistry(session_factory, scopefunc) 

204 else: 

205 self.registry = ThreadLocalRegistry(session_factory) 

206 

207 @property 

208 def _proxied(self) -> _S: 

209 return self.registry() 

210 

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

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

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

214 

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

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

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

218 and keyword arguments have been passed, 

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

220 

221 """ 

222 if kw: 

223 if self.registry.has(): 

224 raise sa_exc.InvalidRequestError( 

225 "Scoped session is already present; " 

226 "no new arguments may be specified." 

227 ) 

228 else: 

229 sess = self.session_factory(**kw) 

230 self.registry.set(sess) 

231 else: 

232 sess = self.registry() 

233 if not self._support_async and sess._is_asyncio: 

234 warn_deprecated( 

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

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

237 "Please use `async_scoped_session` instead.", 

238 "1.4.23", 

239 ) 

240 return sess 

241 

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

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

244 :class:`.scoped_session`. 

245 

246 See :meth:`.sessionmaker.configure`. 

247 

248 """ 

249 

250 if self.registry.has(): 

251 warn( 

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

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

254 "already been created." 

255 ) 

256 

257 self.session_factory.configure(**kwargs) 

258 

259 def remove(self) -> None: 

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

261 

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

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

264 transactional/connection resources still being held; transactions 

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

266 discarded. Upon next usage within the same scope, 

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

268 :class:`.Session` object. 

269 

270 """ 

271 

272 if self.registry.has(): 

273 self.registry().close() 

274 self.registry.clear() 

275 

276 def query_property( 

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

278 ) -> QueryPropertyDescriptor: 

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

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

281 :class:`.Session` when called. 

282 

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

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

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

286 

287 e.g.:: 

288 

289 from sqlalchemy.orm import QueryPropertyDescriptor 

290 from sqlalchemy.orm import scoped_session 

291 from sqlalchemy.orm import sessionmaker 

292 

293 Session = scoped_session(sessionmaker()) 

294 

295 

296 class MyClass: 

297 query: QueryPropertyDescriptor = Session.query_property() 

298 

299 

300 # after mappers are defined 

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

302 

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

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

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

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

307 keyword argument. 

308 

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

310 a class. 

311 

312 """ 

313 

314 class query: 

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

316 if query_cls: 

317 # custom query class 

318 return query_cls(owner, session=self.registry()) # type: ignore[return-value] # noqa: E501 

319 else: 

320 # session's configured query class 

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

322 

323 return query() 

324 

325 # START PROXY METHODS scoped_session 

326 

327 # code within this block is **programmatically, 

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

329 

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

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

332 

333 .. container:: class_bases 

334 

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

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

337 

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

339 result of True. 

340 

341 

342 """ # noqa: E501 

343 

344 return self._proxied.__contains__(instance) 

345 

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

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

348 Session. 

349 

350 .. container:: class_bases 

351 

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

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

354 

355 

356 """ # noqa: E501 

357 

358 return self._proxied.__iter__() 

359 

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

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

362 

363 .. container:: class_bases 

364 

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

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

367 

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

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

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

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

372 

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

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

375 state directly. 

376 

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

378 objects which were transient when they were passed to 

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

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

381 :class:`_orm.Session`. 

382 

383 .. seealso:: 

384 

385 :meth:`_orm.Session.add_all` 

386 

387 :ref:`session_adding` - at :ref:`session_basics` 

388 

389 

390 """ # noqa: E501 

391 

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

393 

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

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

396 

397 .. container:: class_bases 

398 

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

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

401 

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

403 behavioral description. 

404 

405 .. seealso:: 

406 

407 :meth:`_orm.Session.add` 

408 

409 :ref:`session_adding` - at :ref:`session_basics` 

410 

411 

412 """ # noqa: E501 

413 

414 return self._proxied.add_all(instances) 

415 

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

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

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

419 

420 .. container:: class_bases 

421 

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

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

424 

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

426 so that normally it is not necessary to call the 

427 :meth:`_orm.Session.begin` 

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

429 the scope of when the transactional state is begun. 

430 

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

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

433 

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

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

436 documentation on SAVEPOINT transactions, please see 

437 :ref:`session_begin_nested`. 

438 

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

440 :class:`.SessionTransaction` 

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

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

443 an example. 

444 

445 .. seealso:: 

446 

447 :ref:`session_autobegin` 

448 

449 :ref:`unitofwork_transaction` 

450 

451 :meth:`.Session.begin_nested` 

452 

453 

454 

455 """ # noqa: E501 

456 

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

458 

459 def begin_nested(self) -> SessionTransaction: 

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

461 

462 .. container:: class_bases 

463 

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

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

466 

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

468 SAVEPOINT for this method to function correctly. 

469 

470 For documentation on SAVEPOINT 

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

472 

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

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

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

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

477 

478 .. seealso:: 

479 

480 :ref:`session_begin_nested` 

481 

482 :ref:`pysqlite_serializable` - special workarounds required 

483 with the SQLite driver in order for SAVEPOINT to work 

484 correctly. For asyncio use cases, see the section 

485 :ref:`aiosqlite_serializable`. 

486 

487 

488 """ # noqa: E501 

489 

490 return self._proxied.begin_nested() 

491 

492 def close(self) -> None: 

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

494 :class:`_orm.Session`. 

495 

496 .. container:: class_bases 

497 

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

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

500 

501 This expunges all ORM objects associated with this 

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

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

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

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

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

507 

508 .. tip:: 

509 

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

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

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

513 distinct "closed" state; it merely means 

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

515 and ORM objects. 

516 

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

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

519 any further action on the session will be forbidden. 

520 

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

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

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

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

525 

526 .. seealso:: 

527 

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

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

530 

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

532 ``close()`` with the parameter 

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

534 

535 

536 """ # noqa: E501 

537 

538 return self._proxied.close() 

539 

540 def reset(self) -> None: 

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

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

543 

544 .. container:: class_bases 

545 

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

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

548 

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

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

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

552 brand new, and ready to be used again. 

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

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

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

556 

557 .. versionadded:: 2.0.22 

558 

559 .. seealso:: 

560 

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

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

563 

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

565 prevent reuse of the Session when the parameter 

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

567 

568 """ # noqa: E501 

569 

570 return self._proxied.reset() 

571 

572 def commit(self) -> None: 

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

574 

575 .. container:: class_bases 

576 

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

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

579 

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

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

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

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

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

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

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

587 to disable this behavior. 

588 

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

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

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

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

593 normally affect the database unless pending flush changes were 

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

595 rules. 

596 

597 The outermost database transaction is committed unconditionally, 

598 automatically releasing any SAVEPOINTs in effect. 

599 

600 .. seealso:: 

601 

602 :ref:`session_committing` 

603 

604 :ref:`unitofwork_transaction` 

605 

606 :ref:`asyncio_orm_avoid_lazyloads` 

607 

608 

609 """ # noqa: E501 

610 

611 return self._proxied.commit() 

612 

613 def connection( 

614 self, 

615 bind_arguments: Optional[_BindArguments] = None, 

616 execution_options: Optional[CoreExecuteOptionsParameter] = None, 

617 ) -> Connection: 

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

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

620 

621 .. container:: class_bases 

622 

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

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

625 

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

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

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

629 returned (note that no 

630 transactional state is established with the DBAPI until the first 

631 SQL statement is emitted). 

632 

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

634 resolved through any of the optional keyword arguments. This 

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

636 

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

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

639 to :meth:`.Session.get_bind`. 

640 

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

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

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

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

645 the arguments are ignored. 

646 

647 .. seealso:: 

648 

649 :ref:`session_transaction_isolation` 

650 

651 

652 """ # noqa: E501 

653 

654 return self._proxied.connection( 

655 bind_arguments=bind_arguments, execution_options=execution_options 

656 ) 

657 

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

659 r"""Mark an instance as deleted. 

660 

661 .. container:: class_bases 

662 

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

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

665 

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

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

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

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

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

671 

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

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

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

675 is successfully committed, 

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

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

678 

679 .. seealso:: 

680 

681 :ref:`session_deleting` - at :ref:`session_basics` 

682 

683 :meth:`.Session.delete_all` - multiple instance version 

684 

685 

686 """ # noqa: E501 

687 

688 return self._proxied.delete(instance) 

689 

690 def delete_all(self, instances: Iterable[object]) -> None: 

691 r"""Calls :meth:`.Session.delete` on multiple instances. 

692 

693 .. container:: class_bases 

694 

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

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

697 

698 .. seealso:: 

699 

700 :meth:`.Session.delete` - main documentation on delete 

701 

702 .. versionadded:: 2.1 

703 

704 

705 """ # noqa: E501 

706 

707 return self._proxied.delete_all(instances) 

708 

709 @overload 

710 def execute( 

711 self, 

712 statement: TypedReturnsRows[Unpack[_Ts]], 

713 params: Optional[_CoreAnyExecuteParams] = None, 

714 *, 

715 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

716 bind_arguments: Optional[_BindArguments] = None, 

717 _parent_execute_state: Optional[Any] = None, 

718 _add_event: Optional[Any] = None, 

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

720 

721 @overload 

722 def execute( 

723 self, 

724 statement: Executable, 

725 params: Optional[_CoreAnyExecuteParams] = None, 

726 *, 

727 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

728 bind_arguments: Optional[_BindArguments] = None, 

729 _parent_execute_state: Optional[Any] = None, 

730 _add_event: Optional[Any] = None, 

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

732 

733 def execute( 

734 self, 

735 statement: Executable, 

736 params: Optional[_CoreAnyExecuteParams] = None, 

737 *, 

738 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

739 bind_arguments: Optional[_BindArguments] = None, 

740 _parent_execute_state: Optional[Any] = None, 

741 _add_event: Optional[Any] = None, 

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

743 r"""Execute a SQL expression construct. 

744 

745 .. container:: class_bases 

746 

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

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

749 

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

751 results of the statement execution. 

752 

753 E.g.:: 

754 

755 from sqlalchemy import select 

756 

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

758 

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

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

761 of :class:`_engine.Connection`. 

762 

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

764 now the primary point of ORM statement execution when using 

765 :term:`2.0 style` ORM usage. 

766 

767 :param statement: 

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

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

770 

771 :param params: 

772 Optional dictionary, or list of dictionaries, containing 

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

774 execution occurs; if a list of dictionaries, an 

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

776 must correspond to parameter names present in the statement. 

777 

778 :param execution_options: optional dictionary of execution options, 

779 which will be associated with the statement execution. This 

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

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

782 provide additional options understood only in an ORM context. 

783 

784 The execution_options are passed along to methods like 

785 :meth:`.Connection.execute` on :class:`.Connection` giving the 

786 highest priority to execution_options that are passed to this 

787 method explicitly, then the options that are present on the 

788 statement object if any, and finally those options present 

789 session-wide. 

790 

791 .. seealso:: 

792 

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

794 options 

795 

796 :param bind_arguments: dictionary of additional arguments to determine 

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

798 Contents of this dictionary are passed to the 

799 :meth:`.Session.get_bind` method. 

800 

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

802 

803 

804 

805 """ # noqa: E501 

806 

807 return self._proxied.execute( 

808 statement, 

809 params=params, 

810 execution_options=execution_options, 

811 bind_arguments=bind_arguments, 

812 _parent_execute_state=_parent_execute_state, 

813 _add_event=_add_event, 

814 ) 

815 

816 def expire( 

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

818 ) -> None: 

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

820 

821 .. container:: class_bases 

822 

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

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

825 

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

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

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

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

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

831 previously read in that same transaction, regardless of changes 

832 in database state outside of that transaction. 

833 

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

835 use :meth:`Session.expire_all`. 

836 

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

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

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

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

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

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

843 transaction. 

844 

845 :param instance: The instance to be refreshed. 

846 :param attribute_names: optional list of string attribute names 

847 indicating a subset of attributes to be expired. 

848 

849 .. seealso:: 

850 

851 :ref:`session_expire` - introductory material 

852 

853 :meth:`.Session.expire` 

854 

855 :meth:`.Session.refresh` 

856 

857 :meth:`_orm.Query.populate_existing` 

858 

859 

860 """ # noqa: E501 

861 

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

863 

864 def expire_all(self) -> None: 

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

866 

867 .. container:: class_bases 

868 

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

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

871 

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

873 a query will be issued using the 

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

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

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

877 previously read in that same transaction, regardless of changes 

878 in database state outside of that transaction. 

879 

880 To expire individual objects and individual attributes 

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

882 

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

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

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

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

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

888 assuming the transaction is isolated. 

889 

890 .. seealso:: 

891 

892 :ref:`session_expire` - introductory material 

893 

894 :meth:`.Session.expire` 

895 

896 :meth:`.Session.refresh` 

897 

898 :meth:`_orm.Query.populate_existing` 

899 

900 

901 """ # noqa: E501 

902 

903 return self._proxied.expire_all() 

904 

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

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

907 

908 .. container:: class_bases 

909 

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

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

912 

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

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

915 

916 

917 """ # noqa: E501 

918 

919 return self._proxied.expunge(instance) 

920 

921 def expunge_all(self) -> None: 

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

923 

924 .. container:: class_bases 

925 

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

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

928 

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

930 ``Session``. 

931 

932 

933 """ # noqa: E501 

934 

935 return self._proxied.expunge_all() 

936 

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

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

939 

940 .. container:: class_bases 

941 

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

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

944 

945 Writes out all pending object creations, deletions and modifications 

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

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

948 solver. 

949 

950 Database operations will be issued in the current transactional 

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

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

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

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

955 

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

957 only on elements that are in the given collection. 

958 

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

960 particular objects may need to be operated upon before the 

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

962 

963 .. deprecated:: 2.1 

964 

965 

966 """ # noqa: E501 

967 

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

969 

970 def get( 

971 self, 

972 entity: _EntityBindKey[_O], 

973 ident: _PKIdentityArgument, 

974 *, 

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

976 populate_existing: bool | None = None, 

977 with_for_update: ForUpdateParameter = None, 

978 identity_token: Optional[Any] = None, 

979 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

980 bind_arguments: Optional[_BindArguments] = None, 

981 ) -> Optional[_O]: 

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

983 or ``None`` if not found. 

984 

985 .. container:: class_bases 

986 

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

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

989 

990 E.g.:: 

991 

992 my_user = session.get(User, 5) 

993 

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

995 

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

997 

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

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

1000 

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

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

1003 If the given primary key identifier is present 

1004 in the local identity map, the object is returned 

1005 directly from this collection and no SQL is emitted, 

1006 unless the object has been marked fully expired. 

1007 If not present, 

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

1009 

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

1011 the object is present in the identity map and 

1012 marked as expired - a SELECT 

1013 is emitted to refresh the object as well as to 

1014 ensure that the row is still present. 

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

1016 

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

1018 type of entity to be loaded. 

1019 

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

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

1022 a tuple or dictionary should be passed. 

1023 

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

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

1026 the call looks like:: 

1027 

1028 my_object = session.get(SomeClass, 5) 

1029 

1030 The tuple form contains primary key values typically in 

1031 the order in which they correspond to the mapped 

1032 :class:`_schema.Table` 

1033 object's primary key columns, or if the 

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

1035 used, in 

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

1037 of a row is represented by the integer 

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

1039 

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

1041 

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

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

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

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

1046 

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

1048 

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

1050 applied to the query, if one is emitted. 

1051 

1052 :param populate_existing: causes the method to unconditionally emit 

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

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

1055 Setting this flag takes precedence over passing it as an 

1056 execution option. 

1057 

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

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

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

1061 flags should match the parameters of 

1062 :meth:`_query.Query.with_for_update`. 

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

1064 

1065 :param execution_options: optional dictionary of execution options, 

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

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

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

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

1070 

1071 .. versionadded:: 1.4.29 

1072 

1073 .. seealso:: 

1074 

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

1076 options 

1077 

1078 :param bind_arguments: dictionary of additional arguments to determine 

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

1080 Contents of this dictionary are passed to the 

1081 :meth:`.Session.get_bind` method. 

1082 

1083 .. versionadded:: 2.0.0rc1 

1084 

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

1086 

1087 

1088 """ # noqa: E501 

1089 

1090 return self._proxied.get( 

1091 entity, 

1092 ident, 

1093 options=options, 

1094 populate_existing=populate_existing, 

1095 with_for_update=with_for_update, 

1096 identity_token=identity_token, 

1097 execution_options=execution_options, 

1098 bind_arguments=bind_arguments, 

1099 ) 

1100 

1101 def get_one( 

1102 self, 

1103 entity: _EntityBindKey[_O], 

1104 ident: _PKIdentityArgument, 

1105 *, 

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

1107 populate_existing: bool | None = None, 

1108 with_for_update: ForUpdateParameter = None, 

1109 identity_token: Optional[Any] = None, 

1110 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1111 bind_arguments: Optional[_BindArguments] = None, 

1112 ) -> _O: 

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

1114 identifier, or raise an exception if not found. 

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 Raises :class:`_exc.NoResultFound` if the query selects no rows. 

1122 

1123 For a detailed documentation of the arguments see the 

1124 method :meth:`.Session.get`. 

1125 

1126 .. versionadded:: 2.0.22 

1127 

1128 :return: The object instance. 

1129 

1130 .. seealso:: 

1131 

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

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

1134 key 

1135 

1136 

1137 """ # noqa: E501 

1138 

1139 return self._proxied.get_one( 

1140 entity, 

1141 ident, 

1142 options=options, 

1143 populate_existing=populate_existing, 

1144 with_for_update=with_for_update, 

1145 identity_token=identity_token, 

1146 execution_options=execution_options, 

1147 bind_arguments=bind_arguments, 

1148 ) 

1149 

1150 def get_bind( 

1151 self, 

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

1153 *, 

1154 clause: Optional[ClauseElement] = None, 

1155 bind: Optional[_SessionBind] = None, 

1156 _sa_skip_events: Optional[bool] = None, 

1157 _sa_skip_for_implicit_returning: bool = False, 

1158 **kw: Any, 

1159 ) -> Union[Engine, Connection]: 

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

1161 

1162 .. container:: class_bases 

1163 

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

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

1166 

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

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

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

1170 

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

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

1173 appropriate bind to return. 

1174 

1175 Note that the "mapper" argument is usually present 

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

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

1178 individual INSERT/UPDATE/DELETE operation within a 

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

1180 

1181 The order of resolution is: 

1182 

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

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

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

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

1187 superclasses to more general. 

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

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

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

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

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

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

1194 associated with the clause. 

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

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

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

1198 selectable to which the mapper is mapped. 

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

1200 is raised. 

1201 

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

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

1204 of bind resolution scheme. See the example at 

1205 :ref:`session_custom_partitioning`. 

1206 

1207 :param mapper: 

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

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

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

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

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

1213 mapped for a bind. 

1214 

1215 :param clause: 

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

1217 :func:`_expression.select`, 

1218 :func:`_expression.text`, 

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

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

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

1222 associated with 

1223 bound :class:`_schema.MetaData`. 

1224 

1225 .. seealso:: 

1226 

1227 :ref:`session_partitioning` 

1228 

1229 :paramref:`.Session.binds` 

1230 

1231 :meth:`.Session.bind_mapper` 

1232 

1233 :meth:`.Session.bind_table` 

1234 

1235 

1236 """ # noqa: E501 

1237 

1238 return self._proxied.get_bind( 

1239 mapper=mapper, 

1240 clause=clause, 

1241 bind=bind, 

1242 _sa_skip_events=_sa_skip_events, 

1243 _sa_skip_for_implicit_returning=_sa_skip_for_implicit_returning, 

1244 **kw, 

1245 ) 

1246 

1247 def is_modified( 

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

1249 ) -> bool: 

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

1251 modified attributes. 

1252 

1253 .. container:: class_bases 

1254 

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

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

1257 

1258 This method retrieves the history for each instrumented 

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

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

1261 

1262 It is in effect a more expensive and accurate 

1263 version of checking for the given instance in the 

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

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

1266 

1267 E.g.:: 

1268 

1269 return session.is_modified(someobject) 

1270 

1271 A few caveats to this method apply: 

1272 

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

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

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

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

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

1278 change here. 

1279 * Scalar attributes may not have recorded the previously set 

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

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

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

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

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

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

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

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

1288 expensive on average than issuing a defensive SELECT. 

1289 

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

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

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

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

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

1295 argument with :func:`.column_property`. 

1296 

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

1298 :param include_collections: Indicates if multivalued collections 

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

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

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

1302 instance upon flush. 

1303 

1304 

1305 """ # noqa: E501 

1306 

1307 return self._proxied.is_modified( 

1308 instance, include_collections=include_collections 

1309 ) 

1310 

1311 def bulk_save_objects( 

1312 self, 

1313 objects: Iterable[object], 

1314 return_defaults: bool = False, 

1315 update_changed_only: bool = True, 

1316 preserve_order: bool = True, 

1317 ) -> None: 

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

1319 

1320 .. container:: class_bases 

1321 

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

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

1324 

1325 .. legacy:: 

1326 

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

1328 SQLAlchemy. For modern bulk INSERT and UPDATE, see 

1329 the sections :ref:`orm_queryguide_bulk_insert` and 

1330 :ref:`orm_queryguide_bulk_update`. 

1331 

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

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

1334 introduced in the :ref:`unified_tutorial` at 

1335 :ref:`tutorial_orm_data_manipulation`. SQLAlchemy 2.0 

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

1337 which solves previous issues of bulk INSERT slowness. 

1338 

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

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

1341 :class:`.Session` afterwards. 

1342 

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

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

1345 in traditional operation; if the object has the 

1346 :attr:`.InstanceState.key` 

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

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

1349 

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

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

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

1353 attributes present within each object are applied to the UPDATE 

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

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

1356 overhead of checking history on attributes. 

1357 

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

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

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

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

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

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

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

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

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

1367 approach. 

1368 

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

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

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

1372 with the exception of primary key attributes. 

1373 

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

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

1376 False, common types of objects are grouped into inserts 

1377 and updates, to allow for more batching opportunities. 

1378 

1379 .. seealso:: 

1380 

1381 :doc:`queryguide/dml` 

1382 

1383 :meth:`.Session.bulk_insert_mappings` 

1384 

1385 :meth:`.Session.bulk_update_mappings` 

1386 

1387 

1388 """ # noqa: E501 

1389 

1390 return self._proxied.bulk_save_objects( 

1391 objects, 

1392 return_defaults=return_defaults, 

1393 update_changed_only=update_changed_only, 

1394 preserve_order=preserve_order, 

1395 ) 

1396 

1397 def bulk_insert_mappings( 

1398 self, 

1399 mapper: _EntityBindKey[Any], 

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

1401 return_defaults: bool = False, 

1402 render_nulls: bool = False, 

1403 ) -> None: 

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

1405 

1406 .. container:: class_bases 

1407 

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

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

1410 

1411 .. legacy:: 

1412 

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

1414 SQLAlchemy. For modern bulk INSERT and UPDATE, see 

1415 the sections :ref:`orm_queryguide_bulk_insert` and 

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

1417 implementation details with this method and adds new features 

1418 as well. 

1419 

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

1421 object, 

1422 representing the single kind of object represented within the mapping 

1423 list. 

1424 

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

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

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

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

1429 keys to be populated into all tables. 

1430 

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

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

1433 The rationale for this parameter is typically to enable 

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

1435 be bulk inserted. 

1436 

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

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

1439 parameter can significantly decrease performance as INSERT 

1440 statements can no longer be batched. See 

1441 :ref:`engine_insertmanyvalues` 

1442 for background on which backends are affected. 

1443 

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

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

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

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

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

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

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

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

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

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

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

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

1456 necessary. 

1457 

1458 .. warning:: 

1459 

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

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

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

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

1464 invoked for the operation as a whole. 

1465 

1466 .. seealso:: 

1467 

1468 :doc:`queryguide/dml` 

1469 

1470 :meth:`.Session.bulk_save_objects` 

1471 

1472 :meth:`.Session.bulk_update_mappings` 

1473 

1474 

1475 """ # noqa: E501 

1476 

1477 return self._proxied.bulk_insert_mappings( 

1478 mapper, 

1479 mappings, 

1480 return_defaults=return_defaults, 

1481 render_nulls=render_nulls, 

1482 ) 

1483 

1484 def bulk_update_mappings( 

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

1486 ) -> None: 

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

1488 

1489 .. container:: class_bases 

1490 

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

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

1493 

1494 .. legacy:: 

1495 

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

1497 SQLAlchemy. For modern bulk INSERT and UPDATE, see 

1498 the sections :ref:`orm_queryguide_bulk_insert` and 

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

1500 implementation details with this method and adds new features 

1501 as well. 

1502 

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

1504 object, 

1505 representing the single kind of object represented within the mapping 

1506 list. 

1507 

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

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

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

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

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

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

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

1515 applied to the WHERE clause. 

1516 

1517 

1518 .. seealso:: 

1519 

1520 :doc:`queryguide/dml` 

1521 

1522 :meth:`.Session.bulk_insert_mappings` 

1523 

1524 :meth:`.Session.bulk_save_objects` 

1525 

1526 

1527 """ # noqa: E501 

1528 

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

1530 

1531 def merge( 

1532 self, 

1533 instance: _O, 

1534 *, 

1535 load: bool = True, 

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

1537 ) -> _O: 

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

1539 within this :class:`.Session`. 

1540 

1541 .. container:: class_bases 

1542 

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

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

1545 

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

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

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

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

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

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

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

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

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

1555 

1556 This operation cascades to associated instances if the association is 

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

1558 

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

1560 

1561 :param instance: Instance to be merged. 

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

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

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

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

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

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

1568 without re-querying the database. 

1569 

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

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

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

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

1574 the merge operation populates local attributes and 

1575 cascades to related objects and 

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

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

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

1579 any existing related objects or collections that might not 

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

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

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

1583 method. 

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

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

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

1587 

1588 .. versionadded:: 1.4.24 

1589 

1590 

1591 .. seealso:: 

1592 

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

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

1595 

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

1597 

1598 

1599 """ # noqa: E501 

1600 

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

1602 

1603 def merge_all( 

1604 self, 

1605 instances: Iterable[_O], 

1606 *, 

1607 load: bool = True, 

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

1609 ) -> Sequence[_O]: 

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

1611 

1612 .. container:: class_bases 

1613 

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

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

1616 

1617 .. seealso:: 

1618 

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

1620 

1621 .. versionadded:: 2.1 

1622 

1623 

1624 """ # noqa: E501 

1625 

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

1627 

1628 @overload 

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

1630 

1631 @overload 

1632 def query( 

1633 self, _colexpr: TypedColumnsClauseRole[_T] 

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

1635 

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

1637 

1638 # code within this block is **programmatically, 

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

1640 

1641 @overload 

1642 def query( 

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

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

1645 

1646 @overload 

1647 def query( 

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

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

1650 

1651 @overload 

1652 def query( 

1653 self, 

1654 __ent0: _TCCA[_T0], 

1655 __ent1: _TCCA[_T1], 

1656 __ent2: _TCCA[_T2], 

1657 __ent3: _TCCA[_T3], 

1658 /, 

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

1660 

1661 @overload 

1662 def query( 

1663 self, 

1664 __ent0: _TCCA[_T0], 

1665 __ent1: _TCCA[_T1], 

1666 __ent2: _TCCA[_T2], 

1667 __ent3: _TCCA[_T3], 

1668 __ent4: _TCCA[_T4], 

1669 /, 

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

1671 

1672 @overload 

1673 def query( 

1674 self, 

1675 __ent0: _TCCA[_T0], 

1676 __ent1: _TCCA[_T1], 

1677 __ent2: _TCCA[_T2], 

1678 __ent3: _TCCA[_T3], 

1679 __ent4: _TCCA[_T4], 

1680 __ent5: _TCCA[_T5], 

1681 /, 

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

1683 

1684 @overload 

1685 def query( 

1686 self, 

1687 __ent0: _TCCA[_T0], 

1688 __ent1: _TCCA[_T1], 

1689 __ent2: _TCCA[_T2], 

1690 __ent3: _TCCA[_T3], 

1691 __ent4: _TCCA[_T4], 

1692 __ent5: _TCCA[_T5], 

1693 __ent6: _TCCA[_T6], 

1694 /, 

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

1696 

1697 @overload 

1698 def query( 

1699 self, 

1700 __ent0: _TCCA[_T0], 

1701 __ent1: _TCCA[_T1], 

1702 __ent2: _TCCA[_T2], 

1703 __ent3: _TCCA[_T3], 

1704 __ent4: _TCCA[_T4], 

1705 __ent5: _TCCA[_T5], 

1706 __ent6: _TCCA[_T6], 

1707 __ent7: _TCCA[_T7], 

1708 /, 

1709 *entities: _ColumnsClauseArgument[Any], 

1710 ) -> RowReturningQuery[ 

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

1712 ]: ... 

1713 

1714 # END OVERLOADED FUNCTIONS self.query 

1715 

1716 @overload 

1717 def query( 

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

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

1720 

1721 def query( 

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

1723 ) -> Query[Any]: 

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

1725 :class:`_orm.Session`. 

1726 

1727 .. container:: class_bases 

1728 

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

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

1731 

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

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

1734 to construct ORM queries. 

1735 

1736 .. seealso:: 

1737 

1738 :ref:`unified_tutorial` 

1739 

1740 :ref:`queryguide_toplevel` 

1741 

1742 :ref:`query_api_toplevel` - legacy API doc 

1743 

1744 

1745 """ # noqa: E501 

1746 

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

1748 

1749 def refresh( 

1750 self, 

1751 instance: object, 

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

1753 with_for_update: ForUpdateParameter = None, 

1754 ) -> None: 

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

1756 

1757 .. container:: class_bases 

1758 

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

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

1761 

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

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

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

1765 value available in the current transaction. 

1766 

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

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

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

1770 

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

1772 can also refresh eagerly loaded attributes. 

1773 

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

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

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

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

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

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

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

1781 refreshed. 

1782 

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

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

1785 attributes for those which are named explicitly in the 

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

1787 

1788 .. tip:: 

1789 

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

1791 refreshing both column and relationship oriented attributes, its 

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

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

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

1795 once while having explicit control over relationship loader 

1796 strategies, use the 

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

1798 instead. 

1799 

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

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

1802 in database state outside of that transaction. Refreshing 

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

1804 where database rows have not yet been accessed. 

1805 

1806 :param attribute_names: optional. An iterable collection of 

1807 string attribute names indicating a subset of attributes to 

1808 be refreshed. 

1809 

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

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

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

1813 flags should match the parameters of 

1814 :meth:`_query.Query.with_for_update`. 

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

1816 

1817 .. seealso:: 

1818 

1819 :ref:`session_expire` - introductory material 

1820 

1821 :meth:`.Session.expire` 

1822 

1823 :meth:`.Session.expire_all` 

1824 

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

1826 to refresh objects as they would be loaded normally. 

1827 

1828 

1829 """ # noqa: E501 

1830 

1831 return self._proxied.refresh( 

1832 instance, 

1833 attribute_names=attribute_names, 

1834 with_for_update=with_for_update, 

1835 ) 

1836 

1837 def rollback(self) -> None: 

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

1839 

1840 .. container:: class_bases 

1841 

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

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

1844 

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

1846 

1847 The method always rolls back 

1848 the topmost database transaction, discarding any nested 

1849 transactions that may be in progress. 

1850 

1851 .. seealso:: 

1852 

1853 :ref:`session_rollback` 

1854 

1855 :ref:`unitofwork_transaction` 

1856 

1857 

1858 """ # noqa: E501 

1859 

1860 return self._proxied.rollback() 

1861 

1862 @overload 

1863 def scalar( 

1864 self, 

1865 statement: TypedReturnsRows[Never], 

1866 params: Optional[_CoreSingleExecuteParams] = None, 

1867 *, 

1868 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1869 bind_arguments: Optional[_BindArguments] = None, 

1870 **kw: Any, 

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

1872 

1873 @overload 

1874 def scalar( 

1875 self, 

1876 statement: TypedReturnsRows[_T], 

1877 params: Optional[_CoreSingleExecuteParams] = None, 

1878 *, 

1879 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1880 bind_arguments: Optional[_BindArguments] = None, 

1881 **kw: Any, 

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

1883 

1884 @overload 

1885 def scalar( 

1886 self, 

1887 statement: Executable, 

1888 params: Optional[_CoreSingleExecuteParams] = None, 

1889 *, 

1890 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1891 bind_arguments: Optional[_BindArguments] = None, 

1892 **kw: Any, 

1893 ) -> Any: ... 

1894 

1895 def scalar( 

1896 self, 

1897 statement: Executable, 

1898 params: Optional[_CoreSingleExecuteParams] = None, 

1899 *, 

1900 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1901 bind_arguments: Optional[_BindArguments] = None, 

1902 **kw: Any, 

1903 ) -> Any: 

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

1905 

1906 .. container:: class_bases 

1907 

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

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

1910 

1911 Usage and parameters are the same as that of 

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

1913 value. 

1914 

1915 

1916 """ # noqa: E501 

1917 

1918 return self._proxied.scalar( 

1919 statement, 

1920 params=params, 

1921 execution_options=execution_options, 

1922 bind_arguments=bind_arguments, 

1923 **kw, 

1924 ) 

1925 

1926 @overload 

1927 def scalars( 

1928 self, 

1929 statement: TypedReturnsRows[_T], 

1930 params: Optional[_CoreAnyExecuteParams] = None, 

1931 *, 

1932 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1933 bind_arguments: Optional[_BindArguments] = None, 

1934 **kw: Any, 

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

1936 

1937 @overload 

1938 def scalars( 

1939 self, 

1940 statement: Executable, 

1941 params: Optional[_CoreAnyExecuteParams] = None, 

1942 *, 

1943 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1944 bind_arguments: Optional[_BindArguments] = None, 

1945 **kw: Any, 

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

1947 

1948 def scalars( 

1949 self, 

1950 statement: Executable, 

1951 params: Optional[_CoreAnyExecuteParams] = None, 

1952 *, 

1953 execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, 

1954 bind_arguments: Optional[_BindArguments] = None, 

1955 **kw: Any, 

1956 ) -> ScalarResult[Any]: 

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

1958 

1959 .. container:: class_bases 

1960 

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

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

1963 

1964 Usage and parameters are the same as that of 

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

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

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

1968 

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

1970 

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

1972 

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

1974 

1975 .. seealso:: 

1976 

1977 :ref:`orm_queryguide_select_orm_entities` - contrasts the behavior 

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

1979 

1980 

1981 """ # noqa: E501 

1982 

1983 return self._proxied.scalars( 

1984 statement, 

1985 params=params, 

1986 execution_options=execution_options, 

1987 bind_arguments=bind_arguments, 

1988 **kw, 

1989 ) 

1990 

1991 @property 

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

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

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

1995 

1996 """ # noqa: E501 

1997 

1998 return self._proxied.bind 

1999 

2000 @bind.setter 

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

2002 self._proxied.bind = attr 

2003 

2004 @property 

2005 def binds(self) -> Mapping[_SessionBindKey, _SessionBind]: 

2006 r"""Proxy for the :attr:`_orm.Session.binds` attribute 

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

2008 

2009 """ # noqa: E501 

2010 

2011 return self._proxied.binds 

2012 

2013 @binds.setter 

2014 def binds(self, attr: Mapping[_SessionBindKey, _SessionBind]) -> None: 

2015 self._proxied.binds = attr 

2016 

2017 @property 

2018 def dirty(self) -> IdentitySet: 

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

2020 

2021 .. container:: class_bases 

2022 

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

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

2025 

2026 E.g.:: 

2027 

2028 some_mapped_object in session.dirty 

2029 

2030 Instances are considered dirty when they were modified but not 

2031 deleted. 

2032 

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

2034 attribute-setting or collection modification operations will 

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

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

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

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

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

2040 it's only done at flush time). 

2041 

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

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

2044 

2045 

2046 """ # noqa: E501 

2047 

2048 return self._proxied.dirty 

2049 

2050 @property 

2051 def deleted(self) -> IdentitySet: 

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

2053 

2054 .. container:: class_bases 

2055 

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

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

2058 

2059 """ # noqa: E501 

2060 

2061 return self._proxied.deleted 

2062 

2063 @property 

2064 def new(self) -> IdentitySet: 

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

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 """ # noqa: E501 

2073 

2074 return self._proxied.new 

2075 

2076 @property 

2077 def identity_map(self) -> IdentityMap: 

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

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

2080 

2081 """ # noqa: E501 

2082 

2083 return self._proxied.identity_map 

2084 

2085 @identity_map.setter 

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

2087 self._proxied.identity_map = attr 

2088 

2089 @property 

2090 def is_active(self) -> bool: 

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

2092 

2093 .. container:: class_bases 

2094 

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

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

2097 

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

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

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

2101 

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

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

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

2105 fully roll back the transaction. 

2106 

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

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

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

2110 

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

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

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

2114 

2115 .. seealso:: 

2116 

2117 :ref:`faq_session_rollback` 

2118 

2119 :meth:`_orm.Session.in_transaction` 

2120 

2121 

2122 """ # noqa: E501 

2123 

2124 return self._proxied.is_active 

2125 

2126 @property 

2127 def autoflush(self) -> bool: 

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

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

2130 

2131 """ # noqa: E501 

2132 

2133 return self._proxied.autoflush 

2134 

2135 @autoflush.setter 

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

2137 self._proxied.autoflush = attr 

2138 

2139 @property 

2140 def no_autoflush(self) -> Any: 

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

2142 

2143 .. container:: class_bases 

2144 

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

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

2147 

2148 e.g.:: 

2149 

2150 with session.no_autoflush: 

2151 

2152 some_object = SomeClass() 

2153 session.add(some_object) 

2154 # won't autoflush 

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

2156 

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

2158 will not be subject to flushes occurring upon query 

2159 access. This is useful when initializing a series 

2160 of objects which involve existing database queries, 

2161 where the uncompleted object should not yet be flushed. 

2162 

2163 

2164 """ # noqa: E501 

2165 

2166 return self._proxied.no_autoflush 

2167 

2168 @property 

2169 def info(self) -> _InfoType: 

2170 r"""A user-modifiable dictionary. 

2171 

2172 .. container:: class_bases 

2173 

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

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

2176 

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

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

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

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

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

2182 

2183 

2184 """ # noqa: E501 

2185 

2186 return self._proxied.info 

2187 

2188 @property 

2189 def execution_options(self) -> _ExecuteOptions: 

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

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

2192 

2193 """ # noqa: E501 

2194 

2195 return self._proxied.execution_options 

2196 

2197 @execution_options.setter 

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

2199 self._proxied.execution_options = attr 

2200 

2201 @classmethod 

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

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

2204 

2205 .. container:: class_bases 

2206 

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

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

2209 

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

2211 

2212 

2213 """ # noqa: E501 

2214 

2215 return Session.object_session(instance) 

2216 

2217 @classmethod 

2218 def identity_key( 

2219 cls, 

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

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

2222 *, 

2223 instance: Optional[Any] = None, 

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

2225 identity_token: Optional[Any] = None, 

2226 ) -> _IdentityKeyType[Any]: 

2227 r"""Return an identity key. 

2228 

2229 .. container:: class_bases 

2230 

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

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

2233 

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

2235 

2236 

2237 """ # noqa: E501 

2238 

2239 return Session.identity_key( 

2240 class_=class_, 

2241 ident=ident, 

2242 instance=instance, 

2243 row=row, 

2244 identity_token=identity_token, 

2245 ) 

2246 

2247 # END PROXY METHODS scoped_session 

2248 

2249 

2250ScopedSession = scoped_session 

2251"""Old name for backwards compatibility."""