SQLAlchemy 2.0.36__cp313-cp313-win32.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. SQLAlchemy-2.0.36.dist-info/LICENSE +19 -0
  2. SQLAlchemy-2.0.36.dist-info/METADATA +243 -0
  3. SQLAlchemy-2.0.36.dist-info/RECORD +273 -0
  4. SQLAlchemy-2.0.36.dist-info/WHEEL +5 -0
  5. SQLAlchemy-2.0.36.dist-info/top_level.txt +1 -0
  6. sqlalchemy/__init__.py +294 -0
  7. sqlalchemy/connectors/__init__.py +18 -0
  8. sqlalchemy/connectors/aioodbc.py +174 -0
  9. sqlalchemy/connectors/asyncio.py +213 -0
  10. sqlalchemy/connectors/pyodbc.py +249 -0
  11. sqlalchemy/cyextension/__init__.py +6 -0
  12. sqlalchemy/cyextension/collections.cp313-win32.pyd +0 -0
  13. sqlalchemy/cyextension/collections.pyx +409 -0
  14. sqlalchemy/cyextension/immutabledict.cp313-win32.pyd +0 -0
  15. sqlalchemy/cyextension/immutabledict.pxd +8 -0
  16. sqlalchemy/cyextension/immutabledict.pyx +133 -0
  17. sqlalchemy/cyextension/processors.cp313-win32.pyd +0 -0
  18. sqlalchemy/cyextension/processors.pyx +68 -0
  19. sqlalchemy/cyextension/resultproxy.cp313-win32.pyd +0 -0
  20. sqlalchemy/cyextension/resultproxy.pyx +102 -0
  21. sqlalchemy/cyextension/util.cp313-win32.pyd +0 -0
  22. sqlalchemy/cyextension/util.pyx +91 -0
  23. sqlalchemy/dialects/__init__.py +61 -0
  24. sqlalchemy/dialects/_typing.py +25 -0
  25. sqlalchemy/dialects/mssql/__init__.py +88 -0
  26. sqlalchemy/dialects/mssql/aioodbc.py +64 -0
  27. sqlalchemy/dialects/mssql/base.py +4010 -0
  28. sqlalchemy/dialects/mssql/information_schema.py +254 -0
  29. sqlalchemy/dialects/mssql/json.py +133 -0
  30. sqlalchemy/dialects/mssql/provision.py +162 -0
  31. sqlalchemy/dialects/mssql/pymssql.py +126 -0
  32. sqlalchemy/dialects/mssql/pyodbc.py +745 -0
  33. sqlalchemy/dialects/mysql/__init__.py +101 -0
  34. sqlalchemy/dialects/mysql/aiomysql.py +333 -0
  35. sqlalchemy/dialects/mysql/asyncmy.py +337 -0
  36. sqlalchemy/dialects/mysql/base.py +3494 -0
  37. sqlalchemy/dialects/mysql/cymysql.py +84 -0
  38. sqlalchemy/dialects/mysql/dml.py +219 -0
  39. sqlalchemy/dialects/mysql/enumerated.py +244 -0
  40. sqlalchemy/dialects/mysql/expression.py +141 -0
  41. sqlalchemy/dialects/mysql/json.py +81 -0
  42. sqlalchemy/dialects/mysql/mariadb.py +32 -0
  43. sqlalchemy/dialects/mysql/mariadbconnector.py +277 -0
  44. sqlalchemy/dialects/mysql/mysqlconnector.py +180 -0
  45. sqlalchemy/dialects/mysql/mysqldb.py +303 -0
  46. sqlalchemy/dialects/mysql/provision.py +110 -0
  47. sqlalchemy/dialects/mysql/pymysql.py +137 -0
  48. sqlalchemy/dialects/mysql/pyodbc.py +138 -0
  49. sqlalchemy/dialects/mysql/reflection.py +677 -0
  50. sqlalchemy/dialects/mysql/reserved_words.py +571 -0
  51. sqlalchemy/dialects/mysql/types.py +774 -0
  52. sqlalchemy/dialects/oracle/__init__.py +67 -0
  53. sqlalchemy/dialects/oracle/base.py +3271 -0
  54. sqlalchemy/dialects/oracle/cx_oracle.py +1483 -0
  55. sqlalchemy/dialects/oracle/dictionary.py +507 -0
  56. sqlalchemy/dialects/oracle/oracledb.py +431 -0
  57. sqlalchemy/dialects/oracle/provision.py +220 -0
  58. sqlalchemy/dialects/oracle/types.py +287 -0
  59. sqlalchemy/dialects/postgresql/__init__.py +167 -0
  60. sqlalchemy/dialects/postgresql/_psycopg_common.py +187 -0
  61. sqlalchemy/dialects/postgresql/array.py +425 -0
  62. sqlalchemy/dialects/postgresql/asyncpg.py +1274 -0
  63. sqlalchemy/dialects/postgresql/base.py +5008 -0
  64. sqlalchemy/dialects/postgresql/dml.py +310 -0
  65. sqlalchemy/dialects/postgresql/ext.py +496 -0
  66. sqlalchemy/dialects/postgresql/hstore.py +397 -0
  67. sqlalchemy/dialects/postgresql/json.py +333 -0
  68. sqlalchemy/dialects/postgresql/named_types.py +509 -0
  69. sqlalchemy/dialects/postgresql/operators.py +129 -0
  70. sqlalchemy/dialects/postgresql/pg8000.py +662 -0
  71. sqlalchemy/dialects/postgresql/pg_catalog.py +300 -0
  72. sqlalchemy/dialects/postgresql/provision.py +175 -0
  73. sqlalchemy/dialects/postgresql/psycopg.py +772 -0
  74. sqlalchemy/dialects/postgresql/psycopg2.py +886 -0
  75. sqlalchemy/dialects/postgresql/psycopg2cffi.py +61 -0
  76. sqlalchemy/dialects/postgresql/ranges.py +1029 -0
  77. sqlalchemy/dialects/postgresql/types.py +303 -0
  78. sqlalchemy/dialects/sqlite/__init__.py +57 -0
  79. sqlalchemy/dialects/sqlite/aiosqlite.py +396 -0
  80. sqlalchemy/dialects/sqlite/base.py +2805 -0
  81. sqlalchemy/dialects/sqlite/dml.py +240 -0
  82. sqlalchemy/dialects/sqlite/json.py +92 -0
  83. sqlalchemy/dialects/sqlite/provision.py +198 -0
  84. sqlalchemy/dialects/sqlite/pysqlcipher.py +155 -0
  85. sqlalchemy/dialects/sqlite/pysqlite.py +756 -0
  86. sqlalchemy/dialects/type_migration_guidelines.txt +145 -0
  87. sqlalchemy/engine/__init__.py +62 -0
  88. sqlalchemy/engine/_py_processors.py +136 -0
  89. sqlalchemy/engine/_py_row.py +128 -0
  90. sqlalchemy/engine/_py_util.py +74 -0
  91. sqlalchemy/engine/base.py +3375 -0
  92. sqlalchemy/engine/characteristics.py +155 -0
  93. sqlalchemy/engine/create.py +875 -0
  94. sqlalchemy/engine/cursor.py +2181 -0
  95. sqlalchemy/engine/default.py +2365 -0
  96. sqlalchemy/engine/events.py +951 -0
  97. sqlalchemy/engine/interfaces.py +3403 -0
  98. sqlalchemy/engine/mock.py +131 -0
  99. sqlalchemy/engine/processors.py +61 -0
  100. sqlalchemy/engine/reflection.py +2098 -0
  101. sqlalchemy/engine/result.py +2382 -0
  102. sqlalchemy/engine/row.py +401 -0
  103. sqlalchemy/engine/strategies.py +19 -0
  104. sqlalchemy/engine/url.py +910 -0
  105. sqlalchemy/engine/util.py +167 -0
  106. sqlalchemy/event/__init__.py +25 -0
  107. sqlalchemy/event/api.py +225 -0
  108. sqlalchemy/event/attr.py +655 -0
  109. sqlalchemy/event/base.py +470 -0
  110. sqlalchemy/event/legacy.py +246 -0
  111. sqlalchemy/event/registry.py +386 -0
  112. sqlalchemy/events.py +17 -0
  113. sqlalchemy/exc.py +830 -0
  114. sqlalchemy/ext/__init__.py +11 -0
  115. sqlalchemy/ext/associationproxy.py +2013 -0
  116. sqlalchemy/ext/asyncio/__init__.py +25 -0
  117. sqlalchemy/ext/asyncio/base.py +279 -0
  118. sqlalchemy/ext/asyncio/engine.py +1466 -0
  119. sqlalchemy/ext/asyncio/exc.py +21 -0
  120. sqlalchemy/ext/asyncio/result.py +961 -0
  121. sqlalchemy/ext/asyncio/scoping.py +1614 -0
  122. sqlalchemy/ext/asyncio/session.py +1936 -0
  123. sqlalchemy/ext/automap.py +1691 -0
  124. sqlalchemy/ext/baked.py +574 -0
  125. sqlalchemy/ext/compiler.py +570 -0
  126. sqlalchemy/ext/declarative/__init__.py +65 -0
  127. sqlalchemy/ext/declarative/extensions.py +548 -0
  128. sqlalchemy/ext/horizontal_shard.py +481 -0
  129. sqlalchemy/ext/hybrid.py +1514 -0
  130. sqlalchemy/ext/indexable.py +341 -0
  131. sqlalchemy/ext/instrumentation.py +450 -0
  132. sqlalchemy/ext/mutable.py +1073 -0
  133. sqlalchemy/ext/mypy/__init__.py +6 -0
  134. sqlalchemy/ext/mypy/apply.py +320 -0
  135. sqlalchemy/ext/mypy/decl_class.py +515 -0
  136. sqlalchemy/ext/mypy/infer.py +590 -0
  137. sqlalchemy/ext/mypy/names.py +335 -0
  138. sqlalchemy/ext/mypy/plugin.py +303 -0
  139. sqlalchemy/ext/mypy/util.py +357 -0
  140. sqlalchemy/ext/orderinglist.py +416 -0
  141. sqlalchemy/ext/serializer.py +181 -0
  142. sqlalchemy/future/__init__.py +16 -0
  143. sqlalchemy/future/engine.py +15 -0
  144. sqlalchemy/inspection.py +174 -0
  145. sqlalchemy/log.py +288 -0
  146. sqlalchemy/orm/__init__.py +170 -0
  147. sqlalchemy/orm/_orm_constructors.py +2571 -0
  148. sqlalchemy/orm/_typing.py +179 -0
  149. sqlalchemy/orm/attributes.py +2835 -0
  150. sqlalchemy/orm/base.py +973 -0
  151. sqlalchemy/orm/bulk_persistence.py +2123 -0
  152. sqlalchemy/orm/clsregistry.py +571 -0
  153. sqlalchemy/orm/collections.py +1620 -0
  154. sqlalchemy/orm/context.py +3268 -0
  155. sqlalchemy/orm/decl_api.py +1883 -0
  156. sqlalchemy/orm/decl_base.py +2190 -0
  157. sqlalchemy/orm/dependency.py +1304 -0
  158. sqlalchemy/orm/descriptor_props.py +1076 -0
  159. sqlalchemy/orm/dynamic.py +300 -0
  160. sqlalchemy/orm/evaluator.py +379 -0
  161. sqlalchemy/orm/events.py +3261 -0
  162. sqlalchemy/orm/exc.py +228 -0
  163. sqlalchemy/orm/identity.py +302 -0
  164. sqlalchemy/orm/instrumentation.py +754 -0
  165. sqlalchemy/orm/interfaces.py +1474 -0
  166. sqlalchemy/orm/loading.py +1682 -0
  167. sqlalchemy/orm/mapped_collection.py +557 -0
  168. sqlalchemy/orm/mapper.py +4432 -0
  169. sqlalchemy/orm/path_registry.py +811 -0
  170. sqlalchemy/orm/persistence.py +1782 -0
  171. sqlalchemy/orm/properties.py +886 -0
  172. sqlalchemy/orm/query.py +3396 -0
  173. sqlalchemy/orm/relationships.py +3500 -0
  174. sqlalchemy/orm/scoping.py +2165 -0
  175. sqlalchemy/orm/session.py +5301 -0
  176. sqlalchemy/orm/state.py +1143 -0
  177. sqlalchemy/orm/state_changes.py +198 -0
  178. sqlalchemy/orm/strategies.py +3473 -0
  179. sqlalchemy/orm/strategy_options.py +2569 -0
  180. sqlalchemy/orm/sync.py +164 -0
  181. sqlalchemy/orm/unitofwork.py +796 -0
  182. sqlalchemy/orm/util.py +2424 -0
  183. sqlalchemy/orm/writeonly.py +678 -0
  184. sqlalchemy/pool/__init__.py +44 -0
  185. sqlalchemy/pool/base.py +1515 -0
  186. sqlalchemy/pool/events.py +370 -0
  187. sqlalchemy/pool/impl.py +581 -0
  188. sqlalchemy/py.typed +0 -0
  189. sqlalchemy/schema.py +70 -0
  190. sqlalchemy/sql/__init__.py +145 -0
  191. sqlalchemy/sql/_dml_constructors.py +140 -0
  192. sqlalchemy/sql/_elements_constructors.py +1850 -0
  193. sqlalchemy/sql/_orm_types.py +20 -0
  194. sqlalchemy/sql/_py_util.py +75 -0
  195. sqlalchemy/sql/_selectable_constructors.py +635 -0
  196. sqlalchemy/sql/_typing.py +460 -0
  197. sqlalchemy/sql/annotation.py +585 -0
  198. sqlalchemy/sql/base.py +2185 -0
  199. sqlalchemy/sql/cache_key.py +1057 -0
  200. sqlalchemy/sql/coercions.py +1405 -0
  201. sqlalchemy/sql/compiler.py +7818 -0
  202. sqlalchemy/sql/crud.py +1669 -0
  203. sqlalchemy/sql/ddl.py +1378 -0
  204. sqlalchemy/sql/default_comparator.py +552 -0
  205. sqlalchemy/sql/dml.py +1817 -0
  206. sqlalchemy/sql/elements.py +5499 -0
  207. sqlalchemy/sql/events.py +455 -0
  208. sqlalchemy/sql/expression.py +162 -0
  209. sqlalchemy/sql/functions.py +2055 -0
  210. sqlalchemy/sql/lambdas.py +1449 -0
  211. sqlalchemy/sql/naming.py +212 -0
  212. sqlalchemy/sql/operators.py +2579 -0
  213. sqlalchemy/sql/roles.py +323 -0
  214. sqlalchemy/sql/schema.py +6158 -0
  215. sqlalchemy/sql/selectable.py +7004 -0
  216. sqlalchemy/sql/sqltypes.py +3827 -0
  217. sqlalchemy/sql/traversals.py +1024 -0
  218. sqlalchemy/sql/type_api.py +2339 -0
  219. sqlalchemy/sql/util.py +1486 -0
  220. sqlalchemy/sql/visitors.py +1165 -0
  221. sqlalchemy/testing/__init__.py +96 -0
  222. sqlalchemy/testing/assertions.py +989 -0
  223. sqlalchemy/testing/assertsql.py +516 -0
  224. sqlalchemy/testing/asyncio.py +135 -0
  225. sqlalchemy/testing/config.py +427 -0
  226. sqlalchemy/testing/engines.py +472 -0
  227. sqlalchemy/testing/entities.py +117 -0
  228. sqlalchemy/testing/exclusions.py +435 -0
  229. sqlalchemy/testing/fixtures/__init__.py +28 -0
  230. sqlalchemy/testing/fixtures/base.py +366 -0
  231. sqlalchemy/testing/fixtures/mypy.py +312 -0
  232. sqlalchemy/testing/fixtures/orm.py +227 -0
  233. sqlalchemy/testing/fixtures/sql.py +503 -0
  234. sqlalchemy/testing/pickleable.py +155 -0
  235. sqlalchemy/testing/plugin/__init__.py +6 -0
  236. sqlalchemy/testing/plugin/bootstrap.py +51 -0
  237. sqlalchemy/testing/plugin/plugin_base.py +779 -0
  238. sqlalchemy/testing/plugin/pytestplugin.py +868 -0
  239. sqlalchemy/testing/profiling.py +324 -0
  240. sqlalchemy/testing/provision.py +496 -0
  241. sqlalchemy/testing/requirements.py +1818 -0
  242. sqlalchemy/testing/schema.py +224 -0
  243. sqlalchemy/testing/suite/__init__.py +19 -0
  244. sqlalchemy/testing/suite/test_cte.py +211 -0
  245. sqlalchemy/testing/suite/test_ddl.py +389 -0
  246. sqlalchemy/testing/suite/test_deprecations.py +153 -0
  247. sqlalchemy/testing/suite/test_dialect.py +740 -0
  248. sqlalchemy/testing/suite/test_insert.py +630 -0
  249. sqlalchemy/testing/suite/test_reflection.py +3225 -0
  250. sqlalchemy/testing/suite/test_results.py +502 -0
  251. sqlalchemy/testing/suite/test_rowcount.py +258 -0
  252. sqlalchemy/testing/suite/test_select.py +1999 -0
  253. sqlalchemy/testing/suite/test_sequence.py +317 -0
  254. sqlalchemy/testing/suite/test_types.py +2141 -0
  255. sqlalchemy/testing/suite/test_unicode_ddl.py +189 -0
  256. sqlalchemy/testing/suite/test_update_delete.py +139 -0
  257. sqlalchemy/testing/util.py +537 -0
  258. sqlalchemy/testing/warnings.py +52 -0
  259. sqlalchemy/types.py +76 -0
  260. sqlalchemy/util/__init__.py +160 -0
  261. sqlalchemy/util/_collections.py +715 -0
  262. sqlalchemy/util/_concurrency_py3k.py +288 -0
  263. sqlalchemy/util/_has_cy.py +40 -0
  264. sqlalchemy/util/_py_collections.py +541 -0
  265. sqlalchemy/util/compat.py +301 -0
  266. sqlalchemy/util/concurrency.py +108 -0
  267. sqlalchemy/util/deprecations.py +401 -0
  268. sqlalchemy/util/langhelpers.py +2218 -0
  269. sqlalchemy/util/preloaded.py +150 -0
  270. sqlalchemy/util/queue.py +322 -0
  271. sqlalchemy/util/tool_support.py +201 -0
  272. sqlalchemy/util/topological.py +120 -0
  273. sqlalchemy/util/typing.py +629 -0
@@ -0,0 +1,1614 @@
1
+ # ext/asyncio/scoping.py
2
+ # Copyright (C) 2005-2024 the SQLAlchemy authors and contributors
3
+ # <see AUTHORS file>
4
+ #
5
+ # This module is part of SQLAlchemy and is released under
6
+ # the MIT License: https://www.opensource.org/licenses/mit-license.php
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import Any
11
+ from typing import Callable
12
+ from typing import Generic
13
+ from typing import Iterable
14
+ from typing import Iterator
15
+ from typing import Optional
16
+ from typing import overload
17
+ from typing import Sequence
18
+ from typing import Tuple
19
+ from typing import Type
20
+ from typing import TYPE_CHECKING
21
+ from typing import TypeVar
22
+ from typing import Union
23
+
24
+ from .session import _AS
25
+ from .session import async_sessionmaker
26
+ from .session import AsyncSession
27
+ from ... import exc as sa_exc
28
+ from ... import util
29
+ from ...orm.session import Session
30
+ from ...util import create_proxy_methods
31
+ from ...util import ScopedRegistry
32
+ from ...util import warn
33
+ from ...util import warn_deprecated
34
+
35
+ if TYPE_CHECKING:
36
+ from .engine import AsyncConnection
37
+ from .result import AsyncResult
38
+ from .result import AsyncScalarResult
39
+ from .session import AsyncSessionTransaction
40
+ from ...engine import Connection
41
+ from ...engine import CursorResult
42
+ from ...engine import Engine
43
+ from ...engine import Result
44
+ from ...engine import Row
45
+ from ...engine import RowMapping
46
+ from ...engine.interfaces import _CoreAnyExecuteParams
47
+ from ...engine.interfaces import CoreExecuteOptionsParameter
48
+ from ...engine.result import ScalarResult
49
+ from ...orm._typing import _IdentityKeyType
50
+ from ...orm._typing import _O
51
+ from ...orm._typing import OrmExecuteOptionsParameter
52
+ from ...orm.interfaces import ORMOption
53
+ from ...orm.session import _BindArguments
54
+ from ...orm.session import _EntityBindKey
55
+ from ...orm.session import _PKIdentityArgument
56
+ from ...orm.session import _SessionBind
57
+ from ...sql.base import Executable
58
+ from ...sql.dml import UpdateBase
59
+ from ...sql.elements import ClauseElement
60
+ from ...sql.selectable import ForUpdateParameter
61
+ from ...sql.selectable import TypedReturnsRows
62
+
63
+ _T = TypeVar("_T", bound=Any)
64
+
65
+
66
+ @create_proxy_methods(
67
+ AsyncSession,
68
+ ":class:`_asyncio.AsyncSession`",
69
+ ":class:`_asyncio.scoping.async_scoped_session`",
70
+ classmethods=["close_all", "object_session", "identity_key"],
71
+ methods=[
72
+ "__contains__",
73
+ "__iter__",
74
+ "aclose",
75
+ "add",
76
+ "add_all",
77
+ "begin",
78
+ "begin_nested",
79
+ "close",
80
+ "reset",
81
+ "commit",
82
+ "connection",
83
+ "delete",
84
+ "execute",
85
+ "expire",
86
+ "expire_all",
87
+ "expunge",
88
+ "expunge_all",
89
+ "flush",
90
+ "get_bind",
91
+ "is_modified",
92
+ "invalidate",
93
+ "merge",
94
+ "refresh",
95
+ "rollback",
96
+ "scalar",
97
+ "scalars",
98
+ "get",
99
+ "get_one",
100
+ "stream",
101
+ "stream_scalars",
102
+ ],
103
+ attributes=[
104
+ "bind",
105
+ "dirty",
106
+ "deleted",
107
+ "new",
108
+ "identity_map",
109
+ "is_active",
110
+ "autoflush",
111
+ "no_autoflush",
112
+ "info",
113
+ ],
114
+ use_intermediate_variable=["get"],
115
+ )
116
+ class async_scoped_session(Generic[_AS]):
117
+ """Provides scoped management of :class:`.AsyncSession` objects.
118
+
119
+ See the section :ref:`asyncio_scoped_session` for usage details.
120
+
121
+ .. versionadded:: 1.4.19
122
+
123
+
124
+ """
125
+
126
+ _support_async = True
127
+
128
+ session_factory: async_sessionmaker[_AS]
129
+ """The `session_factory` provided to `__init__` is stored in this
130
+ attribute and may be accessed at a later time. This can be useful when
131
+ a new non-scoped :class:`.AsyncSession` is needed."""
132
+
133
+ registry: ScopedRegistry[_AS]
134
+
135
+ def __init__(
136
+ self,
137
+ session_factory: async_sessionmaker[_AS],
138
+ scopefunc: Callable[[], Any],
139
+ ):
140
+ """Construct a new :class:`_asyncio.async_scoped_session`.
141
+
142
+ :param session_factory: a factory to create new :class:`_asyncio.AsyncSession`
143
+ instances. This is usually, but not necessarily, an instance
144
+ of :class:`_asyncio.async_sessionmaker`.
145
+
146
+ :param scopefunc: function which defines
147
+ the current scope. A function such as ``asyncio.current_task``
148
+ may be useful here.
149
+
150
+ """ # noqa: E501
151
+
152
+ self.session_factory = session_factory
153
+ self.registry = ScopedRegistry(session_factory, scopefunc)
154
+
155
+ @property
156
+ def _proxied(self) -> _AS:
157
+ return self.registry()
158
+
159
+ def __call__(self, **kw: Any) -> _AS:
160
+ r"""Return the current :class:`.AsyncSession`, creating it
161
+ using the :attr:`.scoped_session.session_factory` if not present.
162
+
163
+ :param \**kw: Keyword arguments will be passed to the
164
+ :attr:`.scoped_session.session_factory` callable, if an existing
165
+ :class:`.AsyncSession` is not present. If the
166
+ :class:`.AsyncSession` is present
167
+ and keyword arguments have been passed,
168
+ :exc:`~sqlalchemy.exc.InvalidRequestError` is raised.
169
+
170
+ """
171
+ if kw:
172
+ if self.registry.has():
173
+ raise sa_exc.InvalidRequestError(
174
+ "Scoped session is already present; "
175
+ "no new arguments may be specified."
176
+ )
177
+ else:
178
+ sess = self.session_factory(**kw)
179
+ self.registry.set(sess)
180
+ else:
181
+ sess = self.registry()
182
+ if not self._support_async and sess._is_asyncio:
183
+ warn_deprecated(
184
+ "Using `scoped_session` with asyncio is deprecated and "
185
+ "will raise an error in a future version. "
186
+ "Please use `async_scoped_session` instead.",
187
+ "1.4.23",
188
+ )
189
+ return sess
190
+
191
+ def configure(self, **kwargs: Any) -> None:
192
+ """reconfigure the :class:`.sessionmaker` used by this
193
+ :class:`.scoped_session`.
194
+
195
+ See :meth:`.sessionmaker.configure`.
196
+
197
+ """
198
+
199
+ if self.registry.has():
200
+ warn(
201
+ "At least one scoped session is already present. "
202
+ " configure() can not affect sessions that have "
203
+ "already been created."
204
+ )
205
+
206
+ self.session_factory.configure(**kwargs)
207
+
208
+ async def remove(self) -> None:
209
+ """Dispose of the current :class:`.AsyncSession`, if present.
210
+
211
+ Different from scoped_session's remove method, this method would use
212
+ await to wait for the close method of AsyncSession.
213
+
214
+ """
215
+
216
+ if self.registry.has():
217
+ await self.registry().close()
218
+ self.registry.clear()
219
+
220
+ # START PROXY METHODS async_scoped_session
221
+
222
+ # code within this block is **programmatically,
223
+ # statically generated** by tools/generate_proxy_methods.py
224
+
225
+ def __contains__(self, instance: object) -> bool:
226
+ r"""Return True if the instance is associated with this session.
227
+
228
+ .. container:: class_bases
229
+
230
+ Proxied for the :class:`_asyncio.AsyncSession` class on
231
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
232
+
233
+ .. container:: class_bases
234
+
235
+ Proxied for the :class:`_orm.Session` class on
236
+ behalf of the :class:`_asyncio.AsyncSession` class.
237
+
238
+ The instance may be pending or persistent within the Session for a
239
+ result of True.
240
+
241
+
242
+
243
+ """ # noqa: E501
244
+
245
+ return self._proxied.__contains__(instance)
246
+
247
+ def __iter__(self) -> Iterator[object]:
248
+ r"""Iterate over all pending or persistent instances within this
249
+ Session.
250
+
251
+ .. container:: class_bases
252
+
253
+ Proxied for the :class:`_asyncio.AsyncSession` class on
254
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
255
+
256
+ .. container:: class_bases
257
+
258
+ Proxied for the :class:`_orm.Session` class on
259
+ behalf of the :class:`_asyncio.AsyncSession` class.
260
+
261
+
262
+
263
+ """ # noqa: E501
264
+
265
+ return self._proxied.__iter__()
266
+
267
+ async def aclose(self) -> None:
268
+ r"""A synonym for :meth:`_asyncio.AsyncSession.close`.
269
+
270
+ .. container:: class_bases
271
+
272
+ Proxied for the :class:`_asyncio.AsyncSession` class on
273
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
274
+
275
+ The :meth:`_asyncio.AsyncSession.aclose` name is specifically
276
+ to support the Python standard library ``@contextlib.aclosing``
277
+ context manager function.
278
+
279
+ .. versionadded:: 2.0.20
280
+
281
+
282
+ """ # noqa: E501
283
+
284
+ return await self._proxied.aclose()
285
+
286
+ def add(self, instance: object, _warn: bool = True) -> None:
287
+ r"""Place an object into this :class:`_orm.Session`.
288
+
289
+ .. container:: class_bases
290
+
291
+ Proxied for the :class:`_asyncio.AsyncSession` class on
292
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
293
+
294
+ .. container:: class_bases
295
+
296
+ Proxied for the :class:`_orm.Session` class on
297
+ behalf of the :class:`_asyncio.AsyncSession` class.
298
+
299
+ Objects that are in the :term:`transient` state when passed to the
300
+ :meth:`_orm.Session.add` method will move to the
301
+ :term:`pending` state, until the next flush, at which point they
302
+ will move to the :term:`persistent` state.
303
+
304
+ Objects that are in the :term:`detached` state when passed to the
305
+ :meth:`_orm.Session.add` method will move to the :term:`persistent`
306
+ state directly.
307
+
308
+ If the transaction used by the :class:`_orm.Session` is rolled back,
309
+ objects which were transient when they were passed to
310
+ :meth:`_orm.Session.add` will be moved back to the
311
+ :term:`transient` state, and will no longer be present within this
312
+ :class:`_orm.Session`.
313
+
314
+ .. seealso::
315
+
316
+ :meth:`_orm.Session.add_all`
317
+
318
+ :ref:`session_adding` - at :ref:`session_basics`
319
+
320
+
321
+
322
+ """ # noqa: E501
323
+
324
+ return self._proxied.add(instance, _warn=_warn)
325
+
326
+ def add_all(self, instances: Iterable[object]) -> None:
327
+ r"""Add the given collection of instances to this :class:`_orm.Session`.
328
+
329
+ .. container:: class_bases
330
+
331
+ Proxied for the :class:`_asyncio.AsyncSession` class on
332
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
333
+
334
+ .. container:: class_bases
335
+
336
+ Proxied for the :class:`_orm.Session` class on
337
+ behalf of the :class:`_asyncio.AsyncSession` class.
338
+
339
+ See the documentation for :meth:`_orm.Session.add` for a general
340
+ behavioral description.
341
+
342
+ .. seealso::
343
+
344
+ :meth:`_orm.Session.add`
345
+
346
+ :ref:`session_adding` - at :ref:`session_basics`
347
+
348
+
349
+
350
+ """ # noqa: E501
351
+
352
+ return self._proxied.add_all(instances)
353
+
354
+ def begin(self) -> AsyncSessionTransaction:
355
+ r"""Return an :class:`_asyncio.AsyncSessionTransaction` object.
356
+
357
+ .. container:: class_bases
358
+
359
+ Proxied for the :class:`_asyncio.AsyncSession` class on
360
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
361
+
362
+ The underlying :class:`_orm.Session` will perform the
363
+ "begin" action when the :class:`_asyncio.AsyncSessionTransaction`
364
+ object is entered::
365
+
366
+ async with async_session.begin():
367
+ # .. ORM transaction is begun
368
+
369
+ Note that database IO will not normally occur when the session-level
370
+ transaction is begun, as database transactions begin on an
371
+ on-demand basis. However, the begin block is async to accommodate
372
+ for a :meth:`_orm.SessionEvents.after_transaction_create`
373
+ event hook that may perform IO.
374
+
375
+ For a general description of ORM begin, see
376
+ :meth:`_orm.Session.begin`.
377
+
378
+
379
+ """ # noqa: E501
380
+
381
+ return self._proxied.begin()
382
+
383
+ def begin_nested(self) -> AsyncSessionTransaction:
384
+ r"""Return an :class:`_asyncio.AsyncSessionTransaction` object
385
+ which will begin a "nested" transaction, e.g. SAVEPOINT.
386
+
387
+ .. container:: class_bases
388
+
389
+ Proxied for the :class:`_asyncio.AsyncSession` class on
390
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
391
+
392
+ Behavior is the same as that of :meth:`_asyncio.AsyncSession.begin`.
393
+
394
+ For a general description of ORM begin nested, see
395
+ :meth:`_orm.Session.begin_nested`.
396
+
397
+ .. seealso::
398
+
399
+ :ref:`aiosqlite_serializable` - special workarounds required
400
+ with the SQLite asyncio driver in order for SAVEPOINT to work
401
+ correctly.
402
+
403
+
404
+ """ # noqa: E501
405
+
406
+ return self._proxied.begin_nested()
407
+
408
+ async def close(self) -> None:
409
+ r"""Close out the transactional resources and ORM objects used by this
410
+ :class:`_asyncio.AsyncSession`.
411
+
412
+ .. container:: class_bases
413
+
414
+ Proxied for the :class:`_asyncio.AsyncSession` class on
415
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
416
+
417
+ .. seealso::
418
+
419
+ :meth:`_orm.Session.close` - main documentation for
420
+ "close"
421
+
422
+ :ref:`session_closing` - detail on the semantics of
423
+ :meth:`_asyncio.AsyncSession.close` and
424
+ :meth:`_asyncio.AsyncSession.reset`.
425
+
426
+
427
+ """ # noqa: E501
428
+
429
+ return await self._proxied.close()
430
+
431
+ async def reset(self) -> None:
432
+ r"""Close out the transactional resources and ORM objects used by this
433
+ :class:`_orm.Session`, resetting the session to its initial state.
434
+
435
+ .. container:: class_bases
436
+
437
+ Proxied for the :class:`_asyncio.AsyncSession` class on
438
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
439
+
440
+ .. versionadded:: 2.0.22
441
+
442
+ .. seealso::
443
+
444
+ :meth:`_orm.Session.reset` - main documentation for
445
+ "reset"
446
+
447
+ :ref:`session_closing` - detail on the semantics of
448
+ :meth:`_asyncio.AsyncSession.close` and
449
+ :meth:`_asyncio.AsyncSession.reset`.
450
+
451
+
452
+ """ # noqa: E501
453
+
454
+ return await self._proxied.reset()
455
+
456
+ async def commit(self) -> None:
457
+ r"""Commit the current transaction in progress.
458
+
459
+ .. container:: class_bases
460
+
461
+ Proxied for the :class:`_asyncio.AsyncSession` class on
462
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
463
+
464
+ .. seealso::
465
+
466
+ :meth:`_orm.Session.commit` - main documentation for
467
+ "commit"
468
+
469
+ """ # noqa: E501
470
+
471
+ return await self._proxied.commit()
472
+
473
+ async def connection(
474
+ self,
475
+ bind_arguments: Optional[_BindArguments] = None,
476
+ execution_options: Optional[CoreExecuteOptionsParameter] = None,
477
+ **kw: Any,
478
+ ) -> AsyncConnection:
479
+ r"""Return a :class:`_asyncio.AsyncConnection` object corresponding to
480
+ this :class:`.Session` object's transactional state.
481
+
482
+ .. container:: class_bases
483
+
484
+ Proxied for the :class:`_asyncio.AsyncSession` class on
485
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
486
+
487
+ This method may also be used to establish execution options for the
488
+ database connection used by the current transaction.
489
+
490
+ .. versionadded:: 1.4.24 Added \**kw arguments which are passed
491
+ through to the underlying :meth:`_orm.Session.connection` method.
492
+
493
+ .. seealso::
494
+
495
+ :meth:`_orm.Session.connection` - main documentation for
496
+ "connection"
497
+
498
+
499
+ """ # noqa: E501
500
+
501
+ return await self._proxied.connection(
502
+ bind_arguments=bind_arguments,
503
+ execution_options=execution_options,
504
+ **kw,
505
+ )
506
+
507
+ async def delete(self, instance: object) -> None:
508
+ r"""Mark an instance as deleted.
509
+
510
+ .. container:: class_bases
511
+
512
+ Proxied for the :class:`_asyncio.AsyncSession` class on
513
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
514
+
515
+ The database delete operation occurs upon ``flush()``.
516
+
517
+ As this operation may need to cascade along unloaded relationships,
518
+ it is awaitable to allow for those queries to take place.
519
+
520
+ .. seealso::
521
+
522
+ :meth:`_orm.Session.delete` - main documentation for delete
523
+
524
+
525
+ """ # noqa: E501
526
+
527
+ return await self._proxied.delete(instance)
528
+
529
+ @overload
530
+ async def execute(
531
+ self,
532
+ statement: TypedReturnsRows[_T],
533
+ params: Optional[_CoreAnyExecuteParams] = None,
534
+ *,
535
+ execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
536
+ bind_arguments: Optional[_BindArguments] = None,
537
+ _parent_execute_state: Optional[Any] = None,
538
+ _add_event: Optional[Any] = None,
539
+ ) -> Result[_T]: ...
540
+
541
+ @overload
542
+ async def execute(
543
+ self,
544
+ statement: UpdateBase,
545
+ params: Optional[_CoreAnyExecuteParams] = None,
546
+ *,
547
+ execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
548
+ bind_arguments: Optional[_BindArguments] = None,
549
+ _parent_execute_state: Optional[Any] = None,
550
+ _add_event: Optional[Any] = None,
551
+ ) -> CursorResult[Any]: ...
552
+
553
+ @overload
554
+ async def execute(
555
+ self,
556
+ statement: Executable,
557
+ params: Optional[_CoreAnyExecuteParams] = None,
558
+ *,
559
+ execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
560
+ bind_arguments: Optional[_BindArguments] = None,
561
+ _parent_execute_state: Optional[Any] = None,
562
+ _add_event: Optional[Any] = None,
563
+ ) -> Result[Any]: ...
564
+
565
+ async def execute(
566
+ self,
567
+ statement: Executable,
568
+ params: Optional[_CoreAnyExecuteParams] = None,
569
+ *,
570
+ execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
571
+ bind_arguments: Optional[_BindArguments] = None,
572
+ **kw: Any,
573
+ ) -> Result[Any]:
574
+ r"""Execute a statement and return a buffered
575
+ :class:`_engine.Result` object.
576
+
577
+ .. container:: class_bases
578
+
579
+ Proxied for the :class:`_asyncio.AsyncSession` class on
580
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
581
+
582
+ .. seealso::
583
+
584
+ :meth:`_orm.Session.execute` - main documentation for execute
585
+
586
+
587
+ """ # noqa: E501
588
+
589
+ return await self._proxied.execute(
590
+ statement,
591
+ params=params,
592
+ execution_options=execution_options,
593
+ bind_arguments=bind_arguments,
594
+ **kw,
595
+ )
596
+
597
+ def expire(
598
+ self, instance: object, attribute_names: Optional[Iterable[str]] = None
599
+ ) -> None:
600
+ r"""Expire the attributes on an instance.
601
+
602
+ .. container:: class_bases
603
+
604
+ Proxied for the :class:`_asyncio.AsyncSession` class on
605
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
606
+
607
+ .. container:: class_bases
608
+
609
+ Proxied for the :class:`_orm.Session` class on
610
+ behalf of the :class:`_asyncio.AsyncSession` class.
611
+
612
+ Marks the attributes of an instance as out of date. When an expired
613
+ attribute is next accessed, a query will be issued to the
614
+ :class:`.Session` object's current transactional context in order to
615
+ load all expired attributes for the given instance. Note that
616
+ a highly isolated transaction will return the same values as were
617
+ previously read in that same transaction, regardless of changes
618
+ in database state outside of that transaction.
619
+
620
+ To expire all objects in the :class:`.Session` simultaneously,
621
+ use :meth:`Session.expire_all`.
622
+
623
+ The :class:`.Session` object's default behavior is to
624
+ expire all state whenever the :meth:`Session.rollback`
625
+ or :meth:`Session.commit` methods are called, so that new
626
+ state can be loaded for the new transaction. For this reason,
627
+ calling :meth:`Session.expire` only makes sense for the specific
628
+ case that a non-ORM SQL statement was emitted in the current
629
+ transaction.
630
+
631
+ :param instance: The instance to be refreshed.
632
+ :param attribute_names: optional list of string attribute names
633
+ indicating a subset of attributes to be expired.
634
+
635
+ .. seealso::
636
+
637
+ :ref:`session_expire` - introductory material
638
+
639
+ :meth:`.Session.expire`
640
+
641
+ :meth:`.Session.refresh`
642
+
643
+ :meth:`_orm.Query.populate_existing`
644
+
645
+
646
+
647
+ """ # noqa: E501
648
+
649
+ return self._proxied.expire(instance, attribute_names=attribute_names)
650
+
651
+ def expire_all(self) -> None:
652
+ r"""Expires all persistent instances within this Session.
653
+
654
+ .. container:: class_bases
655
+
656
+ Proxied for the :class:`_asyncio.AsyncSession` class on
657
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
658
+
659
+ .. container:: class_bases
660
+
661
+ Proxied for the :class:`_orm.Session` class on
662
+ behalf of the :class:`_asyncio.AsyncSession` class.
663
+
664
+ When any attributes on a persistent instance is next accessed,
665
+ a query will be issued using the
666
+ :class:`.Session` object's current transactional context in order to
667
+ load all expired attributes for the given instance. Note that
668
+ a highly isolated transaction will return the same values as were
669
+ previously read in that same transaction, regardless of changes
670
+ in database state outside of that transaction.
671
+
672
+ To expire individual objects and individual attributes
673
+ on those objects, use :meth:`Session.expire`.
674
+
675
+ The :class:`.Session` object's default behavior is to
676
+ expire all state whenever the :meth:`Session.rollback`
677
+ or :meth:`Session.commit` methods are called, so that new
678
+ state can be loaded for the new transaction. For this reason,
679
+ calling :meth:`Session.expire_all` is not usually needed,
680
+ assuming the transaction is isolated.
681
+
682
+ .. seealso::
683
+
684
+ :ref:`session_expire` - introductory material
685
+
686
+ :meth:`.Session.expire`
687
+
688
+ :meth:`.Session.refresh`
689
+
690
+ :meth:`_orm.Query.populate_existing`
691
+
692
+
693
+
694
+ """ # noqa: E501
695
+
696
+ return self._proxied.expire_all()
697
+
698
+ def expunge(self, instance: object) -> None:
699
+ r"""Remove the `instance` from this ``Session``.
700
+
701
+ .. container:: class_bases
702
+
703
+ Proxied for the :class:`_asyncio.AsyncSession` class on
704
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
705
+
706
+ .. container:: class_bases
707
+
708
+ Proxied for the :class:`_orm.Session` class on
709
+ behalf of the :class:`_asyncio.AsyncSession` class.
710
+
711
+ This will free all internal references to the instance. Cascading
712
+ will be applied according to the *expunge* cascade rule.
713
+
714
+
715
+
716
+ """ # noqa: E501
717
+
718
+ return self._proxied.expunge(instance)
719
+
720
+ def expunge_all(self) -> None:
721
+ r"""Remove all object instances from this ``Session``.
722
+
723
+ .. container:: class_bases
724
+
725
+ Proxied for the :class:`_asyncio.AsyncSession` class on
726
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
727
+
728
+ .. container:: class_bases
729
+
730
+ Proxied for the :class:`_orm.Session` class on
731
+ behalf of the :class:`_asyncio.AsyncSession` class.
732
+
733
+ This is equivalent to calling ``expunge(obj)`` on all objects in this
734
+ ``Session``.
735
+
736
+
737
+
738
+ """ # noqa: E501
739
+
740
+ return self._proxied.expunge_all()
741
+
742
+ async def flush(self, objects: Optional[Sequence[Any]] = None) -> None:
743
+ r"""Flush all the object changes to the database.
744
+
745
+ .. container:: class_bases
746
+
747
+ Proxied for the :class:`_asyncio.AsyncSession` class on
748
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
749
+
750
+ .. seealso::
751
+
752
+ :meth:`_orm.Session.flush` - main documentation for flush
753
+
754
+
755
+ """ # noqa: E501
756
+
757
+ return await self._proxied.flush(objects=objects)
758
+
759
+ def get_bind(
760
+ self,
761
+ mapper: Optional[_EntityBindKey[_O]] = None,
762
+ clause: Optional[ClauseElement] = None,
763
+ bind: Optional[_SessionBind] = None,
764
+ **kw: Any,
765
+ ) -> Union[Engine, Connection]:
766
+ r"""Return a "bind" to which the synchronous proxied :class:`_orm.Session`
767
+ is bound.
768
+
769
+ .. container:: class_bases
770
+
771
+ Proxied for the :class:`_asyncio.AsyncSession` class on
772
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
773
+
774
+ Unlike the :meth:`_orm.Session.get_bind` method, this method is
775
+ currently **not** used by this :class:`.AsyncSession` in any way
776
+ in order to resolve engines for requests.
777
+
778
+ .. note::
779
+
780
+ This method proxies directly to the :meth:`_orm.Session.get_bind`
781
+ method, however is currently **not** useful as an override target,
782
+ in contrast to that of the :meth:`_orm.Session.get_bind` method.
783
+ The example below illustrates how to implement custom
784
+ :meth:`_orm.Session.get_bind` schemes that work with
785
+ :class:`.AsyncSession` and :class:`.AsyncEngine`.
786
+
787
+ The pattern introduced at :ref:`session_custom_partitioning`
788
+ illustrates how to apply a custom bind-lookup scheme to a
789
+ :class:`_orm.Session` given a set of :class:`_engine.Engine` objects.
790
+ To apply a corresponding :meth:`_orm.Session.get_bind` implementation
791
+ for use with a :class:`.AsyncSession` and :class:`.AsyncEngine`
792
+ objects, continue to subclass :class:`_orm.Session` and apply it to
793
+ :class:`.AsyncSession` using
794
+ :paramref:`.AsyncSession.sync_session_class`. The inner method must
795
+ continue to return :class:`_engine.Engine` instances, which can be
796
+ acquired from a :class:`_asyncio.AsyncEngine` using the
797
+ :attr:`_asyncio.AsyncEngine.sync_engine` attribute::
798
+
799
+ # using example from "Custom Vertical Partitioning"
800
+
801
+
802
+ import random
803
+
804
+ from sqlalchemy.ext.asyncio import AsyncSession
805
+ from sqlalchemy.ext.asyncio import create_async_engine
806
+ from sqlalchemy.ext.asyncio import async_sessionmaker
807
+ from sqlalchemy.orm import Session
808
+
809
+ # construct async engines w/ async drivers
810
+ engines = {
811
+ 'leader':create_async_engine("sqlite+aiosqlite:///leader.db"),
812
+ 'other':create_async_engine("sqlite+aiosqlite:///other.db"),
813
+ 'follower1':create_async_engine("sqlite+aiosqlite:///follower1.db"),
814
+ 'follower2':create_async_engine("sqlite+aiosqlite:///follower2.db"),
815
+ }
816
+
817
+ class RoutingSession(Session):
818
+ def get_bind(self, mapper=None, clause=None, **kw):
819
+ # within get_bind(), return sync engines
820
+ if mapper and issubclass(mapper.class_, MyOtherClass):
821
+ return engines['other'].sync_engine
822
+ elif self._flushing or isinstance(clause, (Update, Delete)):
823
+ return engines['leader'].sync_engine
824
+ else:
825
+ return engines[
826
+ random.choice(['follower1','follower2'])
827
+ ].sync_engine
828
+
829
+ # apply to AsyncSession using sync_session_class
830
+ AsyncSessionMaker = async_sessionmaker(
831
+ sync_session_class=RoutingSession
832
+ )
833
+
834
+ The :meth:`_orm.Session.get_bind` method is called in a non-asyncio,
835
+ implicitly non-blocking context in the same manner as ORM event hooks
836
+ and functions that are invoked via :meth:`.AsyncSession.run_sync`, so
837
+ routines that wish to run SQL commands inside of
838
+ :meth:`_orm.Session.get_bind` can continue to do so using
839
+ blocking-style code, which will be translated to implicitly async calls
840
+ at the point of invoking IO on the database drivers.
841
+
842
+
843
+ """ # noqa: E501
844
+
845
+ return self._proxied.get_bind(
846
+ mapper=mapper, clause=clause, bind=bind, **kw
847
+ )
848
+
849
+ def is_modified(
850
+ self, instance: object, include_collections: bool = True
851
+ ) -> bool:
852
+ r"""Return ``True`` if the given instance has locally
853
+ modified attributes.
854
+
855
+ .. container:: class_bases
856
+
857
+ Proxied for the :class:`_asyncio.AsyncSession` class on
858
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
859
+
860
+ .. container:: class_bases
861
+
862
+ Proxied for the :class:`_orm.Session` class on
863
+ behalf of the :class:`_asyncio.AsyncSession` class.
864
+
865
+ This method retrieves the history for each instrumented
866
+ attribute on the instance and performs a comparison of the current
867
+ value to its previously flushed or committed value, if any.
868
+
869
+ It is in effect a more expensive and accurate
870
+ version of checking for the given instance in the
871
+ :attr:`.Session.dirty` collection; a full test for
872
+ each attribute's net "dirty" status is performed.
873
+
874
+ E.g.::
875
+
876
+ return session.is_modified(someobject)
877
+
878
+ A few caveats to this method apply:
879
+
880
+ * Instances present in the :attr:`.Session.dirty` collection may
881
+ report ``False`` when tested with this method. This is because
882
+ the object may have received change events via attribute mutation,
883
+ thus placing it in :attr:`.Session.dirty`, but ultimately the state
884
+ is the same as that loaded from the database, resulting in no net
885
+ change here.
886
+ * Scalar attributes may not have recorded the previously set
887
+ value when a new value was applied, if the attribute was not loaded,
888
+ or was expired, at the time the new value was received - in these
889
+ cases, the attribute is assumed to have a change, even if there is
890
+ ultimately no net change against its database value. SQLAlchemy in
891
+ most cases does not need the "old" value when a set event occurs, so
892
+ it skips the expense of a SQL call if the old value isn't present,
893
+ based on the assumption that an UPDATE of the scalar value is
894
+ usually needed, and in those few cases where it isn't, is less
895
+ expensive on average than issuing a defensive SELECT.
896
+
897
+ The "old" value is fetched unconditionally upon set only if the
898
+ attribute container has the ``active_history`` flag set to ``True``.
899
+ This flag is set typically for primary key attributes and scalar
900
+ object references that are not a simple many-to-one. To set this
901
+ flag for any arbitrary mapped column, use the ``active_history``
902
+ argument with :func:`.column_property`.
903
+
904
+ :param instance: mapped instance to be tested for pending changes.
905
+ :param include_collections: Indicates if multivalued collections
906
+ should be included in the operation. Setting this to ``False`` is a
907
+ way to detect only local-column based properties (i.e. scalar columns
908
+ or many-to-one foreign keys) that would result in an UPDATE for this
909
+ instance upon flush.
910
+
911
+
912
+
913
+ """ # noqa: E501
914
+
915
+ return self._proxied.is_modified(
916
+ instance, include_collections=include_collections
917
+ )
918
+
919
+ async def invalidate(self) -> None:
920
+ r"""Close this Session, using connection invalidation.
921
+
922
+ .. container:: class_bases
923
+
924
+ Proxied for the :class:`_asyncio.AsyncSession` class on
925
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
926
+
927
+ For a complete description, see :meth:`_orm.Session.invalidate`.
928
+
929
+ """ # noqa: E501
930
+
931
+ return await self._proxied.invalidate()
932
+
933
+ async def merge(
934
+ self,
935
+ instance: _O,
936
+ *,
937
+ load: bool = True,
938
+ options: Optional[Sequence[ORMOption]] = None,
939
+ ) -> _O:
940
+ r"""Copy the state of a given instance into a corresponding instance
941
+ within this :class:`_asyncio.AsyncSession`.
942
+
943
+ .. container:: class_bases
944
+
945
+ Proxied for the :class:`_asyncio.AsyncSession` class on
946
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
947
+
948
+ .. seealso::
949
+
950
+ :meth:`_orm.Session.merge` - main documentation for merge
951
+
952
+
953
+ """ # noqa: E501
954
+
955
+ return await self._proxied.merge(instance, load=load, options=options)
956
+
957
+ async def refresh(
958
+ self,
959
+ instance: object,
960
+ attribute_names: Optional[Iterable[str]] = None,
961
+ with_for_update: ForUpdateParameter = None,
962
+ ) -> None:
963
+ r"""Expire and refresh the attributes on the given instance.
964
+
965
+ .. container:: class_bases
966
+
967
+ Proxied for the :class:`_asyncio.AsyncSession` class on
968
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
969
+
970
+ A query will be issued to the database and all attributes will be
971
+ refreshed with their current database value.
972
+
973
+ This is the async version of the :meth:`_orm.Session.refresh` method.
974
+ See that method for a complete description of all options.
975
+
976
+ .. seealso::
977
+
978
+ :meth:`_orm.Session.refresh` - main documentation for refresh
979
+
980
+
981
+ """ # noqa: E501
982
+
983
+ return await self._proxied.refresh(
984
+ instance,
985
+ attribute_names=attribute_names,
986
+ with_for_update=with_for_update,
987
+ )
988
+
989
+ async def rollback(self) -> None:
990
+ r"""Rollback the current transaction in progress.
991
+
992
+ .. container:: class_bases
993
+
994
+ Proxied for the :class:`_asyncio.AsyncSession` class on
995
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
996
+
997
+ .. seealso::
998
+
999
+ :meth:`_orm.Session.rollback` - main documentation for
1000
+ "rollback"
1001
+
1002
+ """ # noqa: E501
1003
+
1004
+ return await self._proxied.rollback()
1005
+
1006
+ @overload
1007
+ async def scalar(
1008
+ self,
1009
+ statement: TypedReturnsRows[Tuple[_T]],
1010
+ params: Optional[_CoreAnyExecuteParams] = None,
1011
+ *,
1012
+ execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
1013
+ bind_arguments: Optional[_BindArguments] = None,
1014
+ **kw: Any,
1015
+ ) -> Optional[_T]: ...
1016
+
1017
+ @overload
1018
+ async def scalar(
1019
+ self,
1020
+ statement: Executable,
1021
+ params: Optional[_CoreAnyExecuteParams] = None,
1022
+ *,
1023
+ execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
1024
+ bind_arguments: Optional[_BindArguments] = None,
1025
+ **kw: Any,
1026
+ ) -> Any: ...
1027
+
1028
+ async def scalar(
1029
+ self,
1030
+ statement: Executable,
1031
+ params: Optional[_CoreAnyExecuteParams] = None,
1032
+ *,
1033
+ execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
1034
+ bind_arguments: Optional[_BindArguments] = None,
1035
+ **kw: Any,
1036
+ ) -> Any:
1037
+ r"""Execute a statement and return a scalar result.
1038
+
1039
+ .. container:: class_bases
1040
+
1041
+ Proxied for the :class:`_asyncio.AsyncSession` class on
1042
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
1043
+
1044
+ .. seealso::
1045
+
1046
+ :meth:`_orm.Session.scalar` - main documentation for scalar
1047
+
1048
+
1049
+ """ # noqa: E501
1050
+
1051
+ return await self._proxied.scalar(
1052
+ statement,
1053
+ params=params,
1054
+ execution_options=execution_options,
1055
+ bind_arguments=bind_arguments,
1056
+ **kw,
1057
+ )
1058
+
1059
+ @overload
1060
+ async def scalars(
1061
+ self,
1062
+ statement: TypedReturnsRows[Tuple[_T]],
1063
+ params: Optional[_CoreAnyExecuteParams] = None,
1064
+ *,
1065
+ execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
1066
+ bind_arguments: Optional[_BindArguments] = None,
1067
+ **kw: Any,
1068
+ ) -> ScalarResult[_T]: ...
1069
+
1070
+ @overload
1071
+ async def scalars(
1072
+ self,
1073
+ statement: Executable,
1074
+ params: Optional[_CoreAnyExecuteParams] = None,
1075
+ *,
1076
+ execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
1077
+ bind_arguments: Optional[_BindArguments] = None,
1078
+ **kw: Any,
1079
+ ) -> ScalarResult[Any]: ...
1080
+
1081
+ async def scalars(
1082
+ self,
1083
+ statement: Executable,
1084
+ params: Optional[_CoreAnyExecuteParams] = None,
1085
+ *,
1086
+ execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
1087
+ bind_arguments: Optional[_BindArguments] = None,
1088
+ **kw: Any,
1089
+ ) -> ScalarResult[Any]:
1090
+ r"""Execute a statement and return scalar results.
1091
+
1092
+ .. container:: class_bases
1093
+
1094
+ Proxied for the :class:`_asyncio.AsyncSession` class on
1095
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
1096
+
1097
+ :return: a :class:`_result.ScalarResult` object
1098
+
1099
+ .. versionadded:: 1.4.24 Added :meth:`_asyncio.AsyncSession.scalars`
1100
+
1101
+ .. versionadded:: 1.4.26 Added
1102
+ :meth:`_asyncio.async_scoped_session.scalars`
1103
+
1104
+ .. seealso::
1105
+
1106
+ :meth:`_orm.Session.scalars` - main documentation for scalars
1107
+
1108
+ :meth:`_asyncio.AsyncSession.stream_scalars` - streaming version
1109
+
1110
+
1111
+ """ # noqa: E501
1112
+
1113
+ return await self._proxied.scalars(
1114
+ statement,
1115
+ params=params,
1116
+ execution_options=execution_options,
1117
+ bind_arguments=bind_arguments,
1118
+ **kw,
1119
+ )
1120
+
1121
+ async def get(
1122
+ self,
1123
+ entity: _EntityBindKey[_O],
1124
+ ident: _PKIdentityArgument,
1125
+ *,
1126
+ options: Optional[Sequence[ORMOption]] = None,
1127
+ populate_existing: bool = False,
1128
+ with_for_update: ForUpdateParameter = None,
1129
+ identity_token: Optional[Any] = None,
1130
+ execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
1131
+ ) -> Union[_O, None]:
1132
+ r"""Return an instance based on the given primary key identifier,
1133
+ or ``None`` if not found.
1134
+
1135
+ .. container:: class_bases
1136
+
1137
+ Proxied for the :class:`_asyncio.AsyncSession` class on
1138
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
1139
+
1140
+ .. seealso::
1141
+
1142
+ :meth:`_orm.Session.get` - main documentation for get
1143
+
1144
+
1145
+
1146
+ """ # noqa: E501
1147
+
1148
+ result = await self._proxied.get(
1149
+ entity,
1150
+ ident,
1151
+ options=options,
1152
+ populate_existing=populate_existing,
1153
+ with_for_update=with_for_update,
1154
+ identity_token=identity_token,
1155
+ execution_options=execution_options,
1156
+ )
1157
+ return result
1158
+
1159
+ async def get_one(
1160
+ self,
1161
+ entity: _EntityBindKey[_O],
1162
+ ident: _PKIdentityArgument,
1163
+ *,
1164
+ options: Optional[Sequence[ORMOption]] = None,
1165
+ populate_existing: bool = False,
1166
+ with_for_update: ForUpdateParameter = None,
1167
+ identity_token: Optional[Any] = None,
1168
+ execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
1169
+ ) -> _O:
1170
+ r"""Return an instance based on the given primary key identifier,
1171
+ or raise an exception if not found.
1172
+
1173
+ .. container:: class_bases
1174
+
1175
+ Proxied for the :class:`_asyncio.AsyncSession` class on
1176
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
1177
+
1178
+ Raises ``sqlalchemy.orm.exc.NoResultFound`` if the query selects
1179
+ no rows.
1180
+
1181
+ ..versionadded: 2.0.22
1182
+
1183
+ .. seealso::
1184
+
1185
+ :meth:`_orm.Session.get_one` - main documentation for get_one
1186
+
1187
+
1188
+ """ # noqa: E501
1189
+
1190
+ return await self._proxied.get_one(
1191
+ entity,
1192
+ ident,
1193
+ options=options,
1194
+ populate_existing=populate_existing,
1195
+ with_for_update=with_for_update,
1196
+ identity_token=identity_token,
1197
+ execution_options=execution_options,
1198
+ )
1199
+
1200
+ @overload
1201
+ async def stream(
1202
+ self,
1203
+ statement: TypedReturnsRows[_T],
1204
+ params: Optional[_CoreAnyExecuteParams] = None,
1205
+ *,
1206
+ execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
1207
+ bind_arguments: Optional[_BindArguments] = None,
1208
+ **kw: Any,
1209
+ ) -> AsyncResult[_T]: ...
1210
+
1211
+ @overload
1212
+ async def stream(
1213
+ self,
1214
+ statement: Executable,
1215
+ params: Optional[_CoreAnyExecuteParams] = None,
1216
+ *,
1217
+ execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
1218
+ bind_arguments: Optional[_BindArguments] = None,
1219
+ **kw: Any,
1220
+ ) -> AsyncResult[Any]: ...
1221
+
1222
+ async def stream(
1223
+ self,
1224
+ statement: Executable,
1225
+ params: Optional[_CoreAnyExecuteParams] = None,
1226
+ *,
1227
+ execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
1228
+ bind_arguments: Optional[_BindArguments] = None,
1229
+ **kw: Any,
1230
+ ) -> AsyncResult[Any]:
1231
+ r"""Execute a statement and return a streaming
1232
+ :class:`_asyncio.AsyncResult` object.
1233
+
1234
+ .. container:: class_bases
1235
+
1236
+ Proxied for the :class:`_asyncio.AsyncSession` class on
1237
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
1238
+
1239
+
1240
+ """ # noqa: E501
1241
+
1242
+ return await self._proxied.stream(
1243
+ statement,
1244
+ params=params,
1245
+ execution_options=execution_options,
1246
+ bind_arguments=bind_arguments,
1247
+ **kw,
1248
+ )
1249
+
1250
+ @overload
1251
+ async def stream_scalars(
1252
+ self,
1253
+ statement: TypedReturnsRows[Tuple[_T]],
1254
+ params: Optional[_CoreAnyExecuteParams] = None,
1255
+ *,
1256
+ execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
1257
+ bind_arguments: Optional[_BindArguments] = None,
1258
+ **kw: Any,
1259
+ ) -> AsyncScalarResult[_T]: ...
1260
+
1261
+ @overload
1262
+ async def stream_scalars(
1263
+ self,
1264
+ statement: Executable,
1265
+ params: Optional[_CoreAnyExecuteParams] = None,
1266
+ *,
1267
+ execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
1268
+ bind_arguments: Optional[_BindArguments] = None,
1269
+ **kw: Any,
1270
+ ) -> AsyncScalarResult[Any]: ...
1271
+
1272
+ async def stream_scalars(
1273
+ self,
1274
+ statement: Executable,
1275
+ params: Optional[_CoreAnyExecuteParams] = None,
1276
+ *,
1277
+ execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
1278
+ bind_arguments: Optional[_BindArguments] = None,
1279
+ **kw: Any,
1280
+ ) -> AsyncScalarResult[Any]:
1281
+ r"""Execute a statement and return a stream of scalar results.
1282
+
1283
+ .. container:: class_bases
1284
+
1285
+ Proxied for the :class:`_asyncio.AsyncSession` class on
1286
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
1287
+
1288
+ :return: an :class:`_asyncio.AsyncScalarResult` object
1289
+
1290
+ .. versionadded:: 1.4.24
1291
+
1292
+ .. seealso::
1293
+
1294
+ :meth:`_orm.Session.scalars` - main documentation for scalars
1295
+
1296
+ :meth:`_asyncio.AsyncSession.scalars` - non streaming version
1297
+
1298
+
1299
+ """ # noqa: E501
1300
+
1301
+ return await self._proxied.stream_scalars(
1302
+ statement,
1303
+ params=params,
1304
+ execution_options=execution_options,
1305
+ bind_arguments=bind_arguments,
1306
+ **kw,
1307
+ )
1308
+
1309
+ @property
1310
+ def bind(self) -> Any:
1311
+ r"""Proxy for the :attr:`_asyncio.AsyncSession.bind` attribute
1312
+ on behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
1313
+
1314
+ """ # noqa: E501
1315
+
1316
+ return self._proxied.bind
1317
+
1318
+ @bind.setter
1319
+ def bind(self, attr: Any) -> None:
1320
+ self._proxied.bind = attr
1321
+
1322
+ @property
1323
+ def dirty(self) -> Any:
1324
+ r"""The set of all persistent instances considered dirty.
1325
+
1326
+ .. container:: class_bases
1327
+
1328
+ Proxied for the :class:`_asyncio.AsyncSession` class
1329
+ on behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
1330
+
1331
+ .. container:: class_bases
1332
+
1333
+ Proxied for the :class:`_orm.Session` class
1334
+ on behalf of the :class:`_asyncio.AsyncSession` class.
1335
+
1336
+ E.g.::
1337
+
1338
+ some_mapped_object in session.dirty
1339
+
1340
+ Instances are considered dirty when they were modified but not
1341
+ deleted.
1342
+
1343
+ Note that this 'dirty' calculation is 'optimistic'; most
1344
+ attribute-setting or collection modification operations will
1345
+ mark an instance as 'dirty' and place it in this set, even if
1346
+ there is no net change to the attribute's value. At flush
1347
+ time, the value of each attribute is compared to its
1348
+ previously saved value, and if there's no net change, no SQL
1349
+ operation will occur (this is a more expensive operation so
1350
+ it's only done at flush time).
1351
+
1352
+ To check if an instance has actionable net changes to its
1353
+ attributes, use the :meth:`.Session.is_modified` method.
1354
+
1355
+
1356
+
1357
+ """ # noqa: E501
1358
+
1359
+ return self._proxied.dirty
1360
+
1361
+ @property
1362
+ def deleted(self) -> Any:
1363
+ r"""The set of all instances marked as 'deleted' within this ``Session``
1364
+
1365
+ .. container:: class_bases
1366
+
1367
+ Proxied for the :class:`_asyncio.AsyncSession` class
1368
+ on behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
1369
+
1370
+ .. container:: class_bases
1371
+
1372
+ Proxied for the :class:`_orm.Session` class
1373
+ on behalf of the :class:`_asyncio.AsyncSession` class.
1374
+
1375
+
1376
+ """ # noqa: E501
1377
+
1378
+ return self._proxied.deleted
1379
+
1380
+ @property
1381
+ def new(self) -> Any:
1382
+ r"""The set of all instances marked as 'new' within this ``Session``.
1383
+
1384
+ .. container:: class_bases
1385
+
1386
+ Proxied for the :class:`_asyncio.AsyncSession` class
1387
+ on behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
1388
+
1389
+ .. container:: class_bases
1390
+
1391
+ Proxied for the :class:`_orm.Session` class
1392
+ on behalf of the :class:`_asyncio.AsyncSession` class.
1393
+
1394
+
1395
+ """ # noqa: E501
1396
+
1397
+ return self._proxied.new
1398
+
1399
+ @property
1400
+ def identity_map(self) -> Any:
1401
+ r"""Proxy for the :attr:`_orm.Session.identity_map` attribute
1402
+ on behalf of the :class:`_asyncio.AsyncSession` class.
1403
+
1404
+ .. container:: class_bases
1405
+
1406
+ Proxied for the :class:`_asyncio.AsyncSession` class
1407
+ on behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
1408
+
1409
+
1410
+ """ # noqa: E501
1411
+
1412
+ return self._proxied.identity_map
1413
+
1414
+ @identity_map.setter
1415
+ def identity_map(self, attr: Any) -> None:
1416
+ self._proxied.identity_map = attr
1417
+
1418
+ @property
1419
+ def is_active(self) -> Any:
1420
+ r"""True if this :class:`.Session` not in "partial rollback" state.
1421
+
1422
+ .. container:: class_bases
1423
+
1424
+ Proxied for the :class:`_asyncio.AsyncSession` class
1425
+ on behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
1426
+
1427
+ .. container:: class_bases
1428
+
1429
+ Proxied for the :class:`_orm.Session` class
1430
+ on behalf of the :class:`_asyncio.AsyncSession` class.
1431
+
1432
+ .. versionchanged:: 1.4 The :class:`_orm.Session` no longer begins
1433
+ a new transaction immediately, so this attribute will be False
1434
+ when the :class:`_orm.Session` is first instantiated.
1435
+
1436
+ "partial rollback" state typically indicates that the flush process
1437
+ of the :class:`_orm.Session` has failed, and that the
1438
+ :meth:`_orm.Session.rollback` method must be emitted in order to
1439
+ fully roll back the transaction.
1440
+
1441
+ If this :class:`_orm.Session` is not in a transaction at all, the
1442
+ :class:`_orm.Session` will autobegin when it is first used, so in this
1443
+ case :attr:`_orm.Session.is_active` will return True.
1444
+
1445
+ Otherwise, if this :class:`_orm.Session` is within a transaction,
1446
+ and that transaction has not been rolled back internally, the
1447
+ :attr:`_orm.Session.is_active` will also return True.
1448
+
1449
+ .. seealso::
1450
+
1451
+ :ref:`faq_session_rollback`
1452
+
1453
+ :meth:`_orm.Session.in_transaction`
1454
+
1455
+
1456
+
1457
+ """ # noqa: E501
1458
+
1459
+ return self._proxied.is_active
1460
+
1461
+ @property
1462
+ def autoflush(self) -> Any:
1463
+ r"""Proxy for the :attr:`_orm.Session.autoflush` attribute
1464
+ on behalf of the :class:`_asyncio.AsyncSession` class.
1465
+
1466
+ .. container:: class_bases
1467
+
1468
+ Proxied for the :class:`_asyncio.AsyncSession` class
1469
+ on behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
1470
+
1471
+
1472
+ """ # noqa: E501
1473
+
1474
+ return self._proxied.autoflush
1475
+
1476
+ @autoflush.setter
1477
+ def autoflush(self, attr: Any) -> None:
1478
+ self._proxied.autoflush = attr
1479
+
1480
+ @property
1481
+ def no_autoflush(self) -> Any:
1482
+ r"""Return a context manager that disables autoflush.
1483
+
1484
+ .. container:: class_bases
1485
+
1486
+ Proxied for the :class:`_asyncio.AsyncSession` class
1487
+ on behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
1488
+
1489
+ .. container:: class_bases
1490
+
1491
+ Proxied for the :class:`_orm.Session` class
1492
+ on behalf of the :class:`_asyncio.AsyncSession` class.
1493
+
1494
+ e.g.::
1495
+
1496
+ with session.no_autoflush:
1497
+
1498
+ some_object = SomeClass()
1499
+ session.add(some_object)
1500
+ # won't autoflush
1501
+ some_object.related_thing = session.query(SomeRelated).first()
1502
+
1503
+ Operations that proceed within the ``with:`` block
1504
+ will not be subject to flushes occurring upon query
1505
+ access. This is useful when initializing a series
1506
+ of objects which involve existing database queries,
1507
+ where the uncompleted object should not yet be flushed.
1508
+
1509
+
1510
+
1511
+ """ # noqa: E501
1512
+
1513
+ return self._proxied.no_autoflush
1514
+
1515
+ @property
1516
+ def info(self) -> Any:
1517
+ r"""A user-modifiable dictionary.
1518
+
1519
+ .. container:: class_bases
1520
+
1521
+ Proxied for the :class:`_asyncio.AsyncSession` class
1522
+ on behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
1523
+
1524
+ .. container:: class_bases
1525
+
1526
+ Proxied for the :class:`_orm.Session` class
1527
+ on behalf of the :class:`_asyncio.AsyncSession` class.
1528
+
1529
+ The initial value of this dictionary can be populated using the
1530
+ ``info`` argument to the :class:`.Session` constructor or
1531
+ :class:`.sessionmaker` constructor or factory methods. The dictionary
1532
+ here is always local to this :class:`.Session` and can be modified
1533
+ independently of all other :class:`.Session` objects.
1534
+
1535
+
1536
+
1537
+ """ # noqa: E501
1538
+
1539
+ return self._proxied.info
1540
+
1541
+ @classmethod
1542
+ async def close_all(cls) -> None:
1543
+ r"""Close all :class:`_asyncio.AsyncSession` sessions.
1544
+
1545
+ .. container:: class_bases
1546
+
1547
+ Proxied for the :class:`_asyncio.AsyncSession` class on
1548
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
1549
+
1550
+ .. deprecated:: 2.0 The :meth:`.AsyncSession.close_all` method is deprecated and will be removed in a future release. Please refer to :func:`_asyncio.close_all_sessions`.
1551
+
1552
+ """ # noqa: E501
1553
+
1554
+ return await AsyncSession.close_all()
1555
+
1556
+ @classmethod
1557
+ def object_session(cls, instance: object) -> Optional[Session]:
1558
+ r"""Return the :class:`.Session` to which an object belongs.
1559
+
1560
+ .. container:: class_bases
1561
+
1562
+ Proxied for the :class:`_asyncio.AsyncSession` class on
1563
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
1564
+
1565
+ .. container:: class_bases
1566
+
1567
+ Proxied for the :class:`_orm.Session` class on
1568
+ behalf of the :class:`_asyncio.AsyncSession` class.
1569
+
1570
+ This is an alias of :func:`.object_session`.
1571
+
1572
+
1573
+
1574
+ """ # noqa: E501
1575
+
1576
+ return AsyncSession.object_session(instance)
1577
+
1578
+ @classmethod
1579
+ def identity_key(
1580
+ cls,
1581
+ class_: Optional[Type[Any]] = None,
1582
+ ident: Union[Any, Tuple[Any, ...]] = None,
1583
+ *,
1584
+ instance: Optional[Any] = None,
1585
+ row: Optional[Union[Row[Any], RowMapping]] = None,
1586
+ identity_token: Optional[Any] = None,
1587
+ ) -> _IdentityKeyType[Any]:
1588
+ r"""Return an identity key.
1589
+
1590
+ .. container:: class_bases
1591
+
1592
+ Proxied for the :class:`_asyncio.AsyncSession` class on
1593
+ behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
1594
+
1595
+ .. container:: class_bases
1596
+
1597
+ Proxied for the :class:`_orm.Session` class on
1598
+ behalf of the :class:`_asyncio.AsyncSession` class.
1599
+
1600
+ This is an alias of :func:`.util.identity_key`.
1601
+
1602
+
1603
+
1604
+ """ # noqa: E501
1605
+
1606
+ return AsyncSession.identity_key(
1607
+ class_=class_,
1608
+ ident=ident,
1609
+ instance=instance,
1610
+ row=row,
1611
+ identity_token=identity_token,
1612
+ )
1613
+
1614
+ # END PROXY METHODS async_scoped_session