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,396 @@
1
+ # dialects/sqlite/aiosqlite.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
+ # mypy: ignore-errors
8
+
9
+
10
+ r"""
11
+
12
+ .. dialect:: sqlite+aiosqlite
13
+ :name: aiosqlite
14
+ :dbapi: aiosqlite
15
+ :connectstring: sqlite+aiosqlite:///file_path
16
+ :url: https://pypi.org/project/aiosqlite/
17
+
18
+ The aiosqlite dialect provides support for the SQLAlchemy asyncio interface
19
+ running on top of pysqlite.
20
+
21
+ aiosqlite is a wrapper around pysqlite that uses a background thread for
22
+ each connection. It does not actually use non-blocking IO, as SQLite
23
+ databases are not socket-based. However it does provide a working asyncio
24
+ interface that's useful for testing and prototyping purposes.
25
+
26
+ Using a special asyncio mediation layer, the aiosqlite dialect is usable
27
+ as the backend for the :ref:`SQLAlchemy asyncio <asyncio_toplevel>`
28
+ extension package.
29
+
30
+ This dialect should normally be used only with the
31
+ :func:`_asyncio.create_async_engine` engine creation function::
32
+
33
+ from sqlalchemy.ext.asyncio import create_async_engine
34
+ engine = create_async_engine("sqlite+aiosqlite:///filename")
35
+
36
+ The URL passes through all arguments to the ``pysqlite`` driver, so all
37
+ connection arguments are the same as they are for that of :ref:`pysqlite`.
38
+
39
+ .. _aiosqlite_udfs:
40
+
41
+ User-Defined Functions
42
+ ----------------------
43
+
44
+ aiosqlite extends pysqlite to support async, so we can create our own user-defined functions (UDFs)
45
+ in Python and use them directly in SQLite queries as described here: :ref:`pysqlite_udfs`.
46
+
47
+ .. _aiosqlite_serializable:
48
+
49
+ Serializable isolation / Savepoints / Transactional DDL (asyncio version)
50
+ -------------------------------------------------------------------------
51
+
52
+ Similarly to pysqlite, aiosqlite does not support SAVEPOINT feature.
53
+
54
+ The solution is similar to :ref:`pysqlite_serializable`. This is achieved by the event listeners in async::
55
+
56
+ from sqlalchemy import create_engine, event
57
+ from sqlalchemy.ext.asyncio import create_async_engine
58
+
59
+ engine = create_async_engine("sqlite+aiosqlite:///myfile.db")
60
+
61
+ @event.listens_for(engine.sync_engine, "connect")
62
+ def do_connect(dbapi_connection, connection_record):
63
+ # disable aiosqlite's emitting of the BEGIN statement entirely.
64
+ # also stops it from emitting COMMIT before any DDL.
65
+ dbapi_connection.isolation_level = None
66
+
67
+ @event.listens_for(engine.sync_engine, "begin")
68
+ def do_begin(conn):
69
+ # emit our own BEGIN
70
+ conn.exec_driver_sql("BEGIN")
71
+
72
+ .. warning:: When using the above recipe, it is advised to not use the
73
+ :paramref:`.Connection.execution_options.isolation_level` setting on
74
+ :class:`_engine.Connection` and :func:`_sa.create_engine`
75
+ with the SQLite driver,
76
+ as this function necessarily will also alter the ".isolation_level" setting.
77
+
78
+ """ # noqa
79
+
80
+ import asyncio
81
+ from collections import deque
82
+ from functools import partial
83
+
84
+ from .base import SQLiteExecutionContext
85
+ from .pysqlite import SQLiteDialect_pysqlite
86
+ from ... import pool
87
+ from ... import util
88
+ from ...engine import AdaptedConnection
89
+ from ...util.concurrency import await_fallback
90
+ from ...util.concurrency import await_only
91
+
92
+
93
+ class AsyncAdapt_aiosqlite_cursor:
94
+ # TODO: base on connectors/asyncio.py
95
+ # see #10415
96
+
97
+ __slots__ = (
98
+ "_adapt_connection",
99
+ "_connection",
100
+ "description",
101
+ "await_",
102
+ "_rows",
103
+ "arraysize",
104
+ "rowcount",
105
+ "lastrowid",
106
+ )
107
+
108
+ server_side = False
109
+
110
+ def __init__(self, adapt_connection):
111
+ self._adapt_connection = adapt_connection
112
+ self._connection = adapt_connection._connection
113
+ self.await_ = adapt_connection.await_
114
+ self.arraysize = 1
115
+ self.rowcount = -1
116
+ self.description = None
117
+ self._rows = deque()
118
+
119
+ def close(self):
120
+ self._rows.clear()
121
+
122
+ def execute(self, operation, parameters=None):
123
+ try:
124
+ _cursor = self.await_(self._connection.cursor())
125
+
126
+ if parameters is None:
127
+ self.await_(_cursor.execute(operation))
128
+ else:
129
+ self.await_(_cursor.execute(operation, parameters))
130
+
131
+ if _cursor.description:
132
+ self.description = _cursor.description
133
+ self.lastrowid = self.rowcount = -1
134
+
135
+ if not self.server_side:
136
+ self._rows = deque(self.await_(_cursor.fetchall()))
137
+ else:
138
+ self.description = None
139
+ self.lastrowid = _cursor.lastrowid
140
+ self.rowcount = _cursor.rowcount
141
+
142
+ if not self.server_side:
143
+ self.await_(_cursor.close())
144
+ else:
145
+ self._cursor = _cursor
146
+ except Exception as error:
147
+ self._adapt_connection._handle_exception(error)
148
+
149
+ def executemany(self, operation, seq_of_parameters):
150
+ try:
151
+ _cursor = self.await_(self._connection.cursor())
152
+ self.await_(_cursor.executemany(operation, seq_of_parameters))
153
+ self.description = None
154
+ self.lastrowid = _cursor.lastrowid
155
+ self.rowcount = _cursor.rowcount
156
+ self.await_(_cursor.close())
157
+ except Exception as error:
158
+ self._adapt_connection._handle_exception(error)
159
+
160
+ def setinputsizes(self, *inputsizes):
161
+ pass
162
+
163
+ def __iter__(self):
164
+ while self._rows:
165
+ yield self._rows.popleft()
166
+
167
+ def fetchone(self):
168
+ if self._rows:
169
+ return self._rows.popleft()
170
+ else:
171
+ return None
172
+
173
+ def fetchmany(self, size=None):
174
+ if size is None:
175
+ size = self.arraysize
176
+
177
+ rr = self._rows
178
+ return [rr.popleft() for _ in range(min(size, len(rr)))]
179
+
180
+ def fetchall(self):
181
+ retval = list(self._rows)
182
+ self._rows.clear()
183
+ return retval
184
+
185
+
186
+ class AsyncAdapt_aiosqlite_ss_cursor(AsyncAdapt_aiosqlite_cursor):
187
+ # TODO: base on connectors/asyncio.py
188
+ # see #10415
189
+ __slots__ = "_cursor"
190
+
191
+ server_side = True
192
+
193
+ def __init__(self, *arg, **kw):
194
+ super().__init__(*arg, **kw)
195
+ self._cursor = None
196
+
197
+ def close(self):
198
+ if self._cursor is not None:
199
+ self.await_(self._cursor.close())
200
+ self._cursor = None
201
+
202
+ def fetchone(self):
203
+ return self.await_(self._cursor.fetchone())
204
+
205
+ def fetchmany(self, size=None):
206
+ if size is None:
207
+ size = self.arraysize
208
+ return self.await_(self._cursor.fetchmany(size=size))
209
+
210
+ def fetchall(self):
211
+ return self.await_(self._cursor.fetchall())
212
+
213
+
214
+ class AsyncAdapt_aiosqlite_connection(AdaptedConnection):
215
+ await_ = staticmethod(await_only)
216
+ __slots__ = ("dbapi",)
217
+
218
+ def __init__(self, dbapi, connection):
219
+ self.dbapi = dbapi
220
+ self._connection = connection
221
+
222
+ @property
223
+ def isolation_level(self):
224
+ return self._connection.isolation_level
225
+
226
+ @isolation_level.setter
227
+ def isolation_level(self, value):
228
+ # aiosqlite's isolation_level setter works outside the Thread
229
+ # that it's supposed to, necessitating setting check_same_thread=False.
230
+ # for improved stability, we instead invent our own awaitable version
231
+ # using aiosqlite's async queue directly.
232
+
233
+ def set_iso(connection, value):
234
+ connection.isolation_level = value
235
+
236
+ function = partial(set_iso, self._connection._conn, value)
237
+ future = asyncio.get_event_loop().create_future()
238
+
239
+ self._connection._tx.put_nowait((future, function))
240
+
241
+ try:
242
+ return self.await_(future)
243
+ except Exception as error:
244
+ self._handle_exception(error)
245
+
246
+ def create_function(self, *args, **kw):
247
+ try:
248
+ self.await_(self._connection.create_function(*args, **kw))
249
+ except Exception as error:
250
+ self._handle_exception(error)
251
+
252
+ def cursor(self, server_side=False):
253
+ if server_side:
254
+ return AsyncAdapt_aiosqlite_ss_cursor(self)
255
+ else:
256
+ return AsyncAdapt_aiosqlite_cursor(self)
257
+
258
+ def execute(self, *args, **kw):
259
+ return self.await_(self._connection.execute(*args, **kw))
260
+
261
+ def rollback(self):
262
+ try:
263
+ self.await_(self._connection.rollback())
264
+ except Exception as error:
265
+ self._handle_exception(error)
266
+
267
+ def commit(self):
268
+ try:
269
+ self.await_(self._connection.commit())
270
+ except Exception as error:
271
+ self._handle_exception(error)
272
+
273
+ def close(self):
274
+ try:
275
+ self.await_(self._connection.close())
276
+ except ValueError:
277
+ # this is undocumented for aiosqlite, that ValueError
278
+ # was raised if .close() was called more than once, which is
279
+ # both not customary for DBAPI and is also not a DBAPI.Error
280
+ # exception. This is now fixed in aiosqlite via my PR
281
+ # https://github.com/omnilib/aiosqlite/pull/238, so we can be
282
+ # assured this will not become some other kind of exception,
283
+ # since it doesn't raise anymore.
284
+
285
+ pass
286
+ except Exception as error:
287
+ self._handle_exception(error)
288
+
289
+ def _handle_exception(self, error):
290
+ if (
291
+ isinstance(error, ValueError)
292
+ and error.args[0] == "no active connection"
293
+ ):
294
+ raise self.dbapi.sqlite.OperationalError(
295
+ "no active connection"
296
+ ) from error
297
+ else:
298
+ raise error
299
+
300
+
301
+ class AsyncAdaptFallback_aiosqlite_connection(AsyncAdapt_aiosqlite_connection):
302
+ __slots__ = ()
303
+
304
+ await_ = staticmethod(await_fallback)
305
+
306
+
307
+ class AsyncAdapt_aiosqlite_dbapi:
308
+ def __init__(self, aiosqlite, sqlite):
309
+ self.aiosqlite = aiosqlite
310
+ self.sqlite = sqlite
311
+ self.paramstyle = "qmark"
312
+ self._init_dbapi_attributes()
313
+
314
+ def _init_dbapi_attributes(self):
315
+ for name in (
316
+ "DatabaseError",
317
+ "Error",
318
+ "IntegrityError",
319
+ "NotSupportedError",
320
+ "OperationalError",
321
+ "ProgrammingError",
322
+ "sqlite_version",
323
+ "sqlite_version_info",
324
+ ):
325
+ setattr(self, name, getattr(self.aiosqlite, name))
326
+
327
+ for name in ("PARSE_COLNAMES", "PARSE_DECLTYPES"):
328
+ setattr(self, name, getattr(self.sqlite, name))
329
+
330
+ for name in ("Binary",):
331
+ setattr(self, name, getattr(self.sqlite, name))
332
+
333
+ def connect(self, *arg, **kw):
334
+ async_fallback = kw.pop("async_fallback", False)
335
+
336
+ creator_fn = kw.pop("async_creator_fn", None)
337
+ if creator_fn:
338
+ connection = creator_fn(*arg, **kw)
339
+ else:
340
+ connection = self.aiosqlite.connect(*arg, **kw)
341
+ # it's a Thread. you'll thank us later
342
+ connection.daemon = True
343
+
344
+ if util.asbool(async_fallback):
345
+ return AsyncAdaptFallback_aiosqlite_connection(
346
+ self,
347
+ await_fallback(connection),
348
+ )
349
+ else:
350
+ return AsyncAdapt_aiosqlite_connection(
351
+ self,
352
+ await_only(connection),
353
+ )
354
+
355
+
356
+ class SQLiteExecutionContext_aiosqlite(SQLiteExecutionContext):
357
+ def create_server_side_cursor(self):
358
+ return self._dbapi_connection.cursor(server_side=True)
359
+
360
+
361
+ class SQLiteDialect_aiosqlite(SQLiteDialect_pysqlite):
362
+ driver = "aiosqlite"
363
+ supports_statement_cache = True
364
+
365
+ is_async = True
366
+
367
+ supports_server_side_cursors = True
368
+
369
+ execution_ctx_cls = SQLiteExecutionContext_aiosqlite
370
+
371
+ @classmethod
372
+ def import_dbapi(cls):
373
+ return AsyncAdapt_aiosqlite_dbapi(
374
+ __import__("aiosqlite"), __import__("sqlite3")
375
+ )
376
+
377
+ @classmethod
378
+ def get_pool_class(cls, url):
379
+ if cls._is_url_file_db(url):
380
+ return pool.NullPool
381
+ else:
382
+ return pool.StaticPool
383
+
384
+ def is_disconnect(self, e, connection, cursor):
385
+ if isinstance(
386
+ e, self.dbapi.OperationalError
387
+ ) and "no active connection" in str(e):
388
+ return True
389
+
390
+ return super().is_disconnect(e, connection, cursor)
391
+
392
+ def get_driver_connection(self, connection):
393
+ return connection._connection
394
+
395
+
396
+ dialect = SQLiteDialect_aiosqlite