SQLAlchemy 2.0.36__cp313-cp313-win_amd64.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-win_amd64.pyd +0 -0
  13. sqlalchemy/cyextension/collections.pyx +409 -0
  14. sqlalchemy/cyextension/immutabledict.cp313-win_amd64.pyd +0 -0
  15. sqlalchemy/cyextension/immutabledict.pxd +8 -0
  16. sqlalchemy/cyextension/immutabledict.pyx +133 -0
  17. sqlalchemy/cyextension/processors.cp313-win_amd64.pyd +0 -0
  18. sqlalchemy/cyextension/processors.pyx +68 -0
  19. sqlalchemy/cyextension/resultproxy.cp313-win_amd64.pyd +0 -0
  20. sqlalchemy/cyextension/resultproxy.pyx +102 -0
  21. sqlalchemy/cyextension/util.cp313-win_amd64.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,101 @@
1
+ # dialects/mysql/__init__.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
+ from . import aiomysql # noqa
11
+ from . import asyncmy # noqa
12
+ from . import base # noqa
13
+ from . import cymysql # noqa
14
+ from . import mariadbconnector # noqa
15
+ from . import mysqlconnector # noqa
16
+ from . import mysqldb # noqa
17
+ from . import pymysql # noqa
18
+ from . import pyodbc # noqa
19
+ from .base import BIGINT
20
+ from .base import BINARY
21
+ from .base import BIT
22
+ from .base import BLOB
23
+ from .base import BOOLEAN
24
+ from .base import CHAR
25
+ from .base import DATE
26
+ from .base import DATETIME
27
+ from .base import DECIMAL
28
+ from .base import DOUBLE
29
+ from .base import ENUM
30
+ from .base import FLOAT
31
+ from .base import INTEGER
32
+ from .base import JSON
33
+ from .base import LONGBLOB
34
+ from .base import LONGTEXT
35
+ from .base import MEDIUMBLOB
36
+ from .base import MEDIUMINT
37
+ from .base import MEDIUMTEXT
38
+ from .base import NCHAR
39
+ from .base import NUMERIC
40
+ from .base import NVARCHAR
41
+ from .base import REAL
42
+ from .base import SET
43
+ from .base import SMALLINT
44
+ from .base import TEXT
45
+ from .base import TIME
46
+ from .base import TIMESTAMP
47
+ from .base import TINYBLOB
48
+ from .base import TINYINT
49
+ from .base import TINYTEXT
50
+ from .base import VARBINARY
51
+ from .base import VARCHAR
52
+ from .base import YEAR
53
+ from .dml import Insert
54
+ from .dml import insert
55
+ from .expression import match
56
+ from ...util import compat
57
+
58
+ # default dialect
59
+ base.dialect = dialect = mysqldb.dialect
60
+
61
+ __all__ = (
62
+ "BIGINT",
63
+ "BINARY",
64
+ "BIT",
65
+ "BLOB",
66
+ "BOOLEAN",
67
+ "CHAR",
68
+ "DATE",
69
+ "DATETIME",
70
+ "DECIMAL",
71
+ "DOUBLE",
72
+ "ENUM",
73
+ "FLOAT",
74
+ "INTEGER",
75
+ "INTEGER",
76
+ "JSON",
77
+ "LONGBLOB",
78
+ "LONGTEXT",
79
+ "MEDIUMBLOB",
80
+ "MEDIUMINT",
81
+ "MEDIUMTEXT",
82
+ "NCHAR",
83
+ "NVARCHAR",
84
+ "NUMERIC",
85
+ "SET",
86
+ "SMALLINT",
87
+ "REAL",
88
+ "TEXT",
89
+ "TIME",
90
+ "TIMESTAMP",
91
+ "TINYBLOB",
92
+ "TINYINT",
93
+ "TINYTEXT",
94
+ "VARBINARY",
95
+ "VARCHAR",
96
+ "YEAR",
97
+ "dialect",
98
+ "insert",
99
+ "Insert",
100
+ "match",
101
+ )
@@ -0,0 +1,333 @@
1
+ # dialects/mysql/aiomysql.py
2
+ # Copyright (C) 2005-2024 the SQLAlchemy authors and contributors <see AUTHORS
3
+ # 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
+ r"""
10
+ .. dialect:: mysql+aiomysql
11
+ :name: aiomysql
12
+ :dbapi: aiomysql
13
+ :connectstring: mysql+aiomysql://user:password@host:port/dbname[?key=value&key=value...]
14
+ :url: https://github.com/aio-libs/aiomysql
15
+
16
+ The aiomysql dialect is SQLAlchemy's second Python asyncio dialect.
17
+
18
+ Using a special asyncio mediation layer, the aiomysql dialect is usable
19
+ as the backend for the :ref:`SQLAlchemy asyncio <asyncio_toplevel>`
20
+ extension package.
21
+
22
+ This dialect should normally be used only with the
23
+ :func:`_asyncio.create_async_engine` engine creation function::
24
+
25
+ from sqlalchemy.ext.asyncio import create_async_engine
26
+ engine = create_async_engine("mysql+aiomysql://user:pass@hostname/dbname?charset=utf8mb4")
27
+
28
+
29
+ """ # noqa
30
+ from collections import deque
31
+
32
+ from .pymysql import MySQLDialect_pymysql
33
+ from ... import pool
34
+ from ... import util
35
+ from ...engine import AdaptedConnection
36
+ from ...util.concurrency import asyncio
37
+ from ...util.concurrency import await_fallback
38
+ from ...util.concurrency import await_only
39
+
40
+
41
+ class AsyncAdapt_aiomysql_cursor:
42
+ # TODO: base on connectors/asyncio.py
43
+ # see #10415
44
+ server_side = False
45
+ __slots__ = (
46
+ "_adapt_connection",
47
+ "_connection",
48
+ "await_",
49
+ "_cursor",
50
+ "_rows",
51
+ )
52
+
53
+ def __init__(self, adapt_connection):
54
+ self._adapt_connection = adapt_connection
55
+ self._connection = adapt_connection._connection
56
+ self.await_ = adapt_connection.await_
57
+
58
+ cursor = self._connection.cursor(adapt_connection.dbapi.Cursor)
59
+
60
+ # see https://github.com/aio-libs/aiomysql/issues/543
61
+ self._cursor = self.await_(cursor.__aenter__())
62
+ self._rows = deque()
63
+
64
+ @property
65
+ def description(self):
66
+ return self._cursor.description
67
+
68
+ @property
69
+ def rowcount(self):
70
+ return self._cursor.rowcount
71
+
72
+ @property
73
+ def arraysize(self):
74
+ return self._cursor.arraysize
75
+
76
+ @arraysize.setter
77
+ def arraysize(self, value):
78
+ self._cursor.arraysize = value
79
+
80
+ @property
81
+ def lastrowid(self):
82
+ return self._cursor.lastrowid
83
+
84
+ def close(self):
85
+ # note we aren't actually closing the cursor here,
86
+ # we are just letting GC do it. to allow this to be async
87
+ # we would need the Result to change how it does "Safe close cursor".
88
+ # MySQL "cursors" don't actually have state to be "closed" besides
89
+ # exhausting rows, which we already have done for sync cursor.
90
+ # another option would be to emulate aiosqlite dialect and assign
91
+ # cursor only if we are doing server side cursor operation.
92
+ self._rows.clear()
93
+
94
+ def execute(self, operation, parameters=None):
95
+ return self.await_(self._execute_async(operation, parameters))
96
+
97
+ def executemany(self, operation, seq_of_parameters):
98
+ return self.await_(
99
+ self._executemany_async(operation, seq_of_parameters)
100
+ )
101
+
102
+ async def _execute_async(self, operation, parameters):
103
+ async with self._adapt_connection._execute_mutex:
104
+ result = await self._cursor.execute(operation, parameters)
105
+
106
+ if not self.server_side:
107
+ # aiomysql has a "fake" async result, so we have to pull it out
108
+ # of that here since our default result is not async.
109
+ # we could just as easily grab "_rows" here and be done with it
110
+ # but this is safer.
111
+ self._rows = deque(await self._cursor.fetchall())
112
+ return result
113
+
114
+ async def _executemany_async(self, operation, seq_of_parameters):
115
+ async with self._adapt_connection._execute_mutex:
116
+ return await self._cursor.executemany(operation, seq_of_parameters)
117
+
118
+ def setinputsizes(self, *inputsizes):
119
+ pass
120
+
121
+ def __iter__(self):
122
+ while self._rows:
123
+ yield self._rows.popleft()
124
+
125
+ def fetchone(self):
126
+ if self._rows:
127
+ return self._rows.popleft()
128
+ else:
129
+ return None
130
+
131
+ def fetchmany(self, size=None):
132
+ if size is None:
133
+ size = self.arraysize
134
+
135
+ rr = self._rows
136
+ return [rr.popleft() for _ in range(min(size, len(rr)))]
137
+
138
+ def fetchall(self):
139
+ retval = list(self._rows)
140
+ self._rows.clear()
141
+ return retval
142
+
143
+
144
+ class AsyncAdapt_aiomysql_ss_cursor(AsyncAdapt_aiomysql_cursor):
145
+ # TODO: base on connectors/asyncio.py
146
+ # see #10415
147
+ __slots__ = ()
148
+ server_side = True
149
+
150
+ def __init__(self, adapt_connection):
151
+ self._adapt_connection = adapt_connection
152
+ self._connection = adapt_connection._connection
153
+ self.await_ = adapt_connection.await_
154
+
155
+ cursor = self._connection.cursor(adapt_connection.dbapi.SSCursor)
156
+
157
+ self._cursor = self.await_(cursor.__aenter__())
158
+
159
+ def close(self):
160
+ if self._cursor is not None:
161
+ self.await_(self._cursor.close())
162
+ self._cursor = None
163
+
164
+ def fetchone(self):
165
+ return self.await_(self._cursor.fetchone())
166
+
167
+ def fetchmany(self, size=None):
168
+ return self.await_(self._cursor.fetchmany(size=size))
169
+
170
+ def fetchall(self):
171
+ return self.await_(self._cursor.fetchall())
172
+
173
+
174
+ class AsyncAdapt_aiomysql_connection(AdaptedConnection):
175
+ # TODO: base on connectors/asyncio.py
176
+ # see #10415
177
+ await_ = staticmethod(await_only)
178
+ __slots__ = ("dbapi", "_execute_mutex")
179
+
180
+ def __init__(self, dbapi, connection):
181
+ self.dbapi = dbapi
182
+ self._connection = connection
183
+ self._execute_mutex = asyncio.Lock()
184
+
185
+ def ping(self, reconnect):
186
+ return self.await_(self._connection.ping(reconnect))
187
+
188
+ def character_set_name(self):
189
+ return self._connection.character_set_name()
190
+
191
+ def autocommit(self, value):
192
+ self.await_(self._connection.autocommit(value))
193
+
194
+ def cursor(self, server_side=False):
195
+ if server_side:
196
+ return AsyncAdapt_aiomysql_ss_cursor(self)
197
+ else:
198
+ return AsyncAdapt_aiomysql_cursor(self)
199
+
200
+ def rollback(self):
201
+ self.await_(self._connection.rollback())
202
+
203
+ def commit(self):
204
+ self.await_(self._connection.commit())
205
+
206
+ def terminate(self):
207
+ # it's not awaitable.
208
+ self._connection.close()
209
+
210
+ def close(self) -> None:
211
+ self.await_(self._connection.ensure_closed())
212
+
213
+
214
+ class AsyncAdaptFallback_aiomysql_connection(AsyncAdapt_aiomysql_connection):
215
+ # TODO: base on connectors/asyncio.py
216
+ # see #10415
217
+ __slots__ = ()
218
+
219
+ await_ = staticmethod(await_fallback)
220
+
221
+
222
+ class AsyncAdapt_aiomysql_dbapi:
223
+ def __init__(self, aiomysql, pymysql):
224
+ self.aiomysql = aiomysql
225
+ self.pymysql = pymysql
226
+ self.paramstyle = "format"
227
+ self._init_dbapi_attributes()
228
+ self.Cursor, self.SSCursor = self._init_cursors_subclasses()
229
+
230
+ def _init_dbapi_attributes(self):
231
+ for name in (
232
+ "Warning",
233
+ "Error",
234
+ "InterfaceError",
235
+ "DataError",
236
+ "DatabaseError",
237
+ "OperationalError",
238
+ "InterfaceError",
239
+ "IntegrityError",
240
+ "ProgrammingError",
241
+ "InternalError",
242
+ "NotSupportedError",
243
+ ):
244
+ setattr(self, name, getattr(self.aiomysql, name))
245
+
246
+ for name in (
247
+ "NUMBER",
248
+ "STRING",
249
+ "DATETIME",
250
+ "BINARY",
251
+ "TIMESTAMP",
252
+ "Binary",
253
+ ):
254
+ setattr(self, name, getattr(self.pymysql, name))
255
+
256
+ def connect(self, *arg, **kw):
257
+ async_fallback = kw.pop("async_fallback", False)
258
+ creator_fn = kw.pop("async_creator_fn", self.aiomysql.connect)
259
+
260
+ if util.asbool(async_fallback):
261
+ return AsyncAdaptFallback_aiomysql_connection(
262
+ self,
263
+ await_fallback(creator_fn(*arg, **kw)),
264
+ )
265
+ else:
266
+ return AsyncAdapt_aiomysql_connection(
267
+ self,
268
+ await_only(creator_fn(*arg, **kw)),
269
+ )
270
+
271
+ def _init_cursors_subclasses(self):
272
+ # suppress unconditional warning emitted by aiomysql
273
+ class Cursor(self.aiomysql.Cursor):
274
+ async def _show_warnings(self, conn):
275
+ pass
276
+
277
+ class SSCursor(self.aiomysql.SSCursor):
278
+ async def _show_warnings(self, conn):
279
+ pass
280
+
281
+ return Cursor, SSCursor
282
+
283
+
284
+ class MySQLDialect_aiomysql(MySQLDialect_pymysql):
285
+ driver = "aiomysql"
286
+ supports_statement_cache = True
287
+
288
+ supports_server_side_cursors = True
289
+ _sscursor = AsyncAdapt_aiomysql_ss_cursor
290
+
291
+ is_async = True
292
+ has_terminate = True
293
+
294
+ @classmethod
295
+ def import_dbapi(cls):
296
+ return AsyncAdapt_aiomysql_dbapi(
297
+ __import__("aiomysql"), __import__("pymysql")
298
+ )
299
+
300
+ @classmethod
301
+ def get_pool_class(cls, url):
302
+ async_fallback = url.query.get("async_fallback", False)
303
+
304
+ if util.asbool(async_fallback):
305
+ return pool.FallbackAsyncAdaptedQueuePool
306
+ else:
307
+ return pool.AsyncAdaptedQueuePool
308
+
309
+ def do_terminate(self, dbapi_connection) -> None:
310
+ dbapi_connection.terminate()
311
+
312
+ def create_connect_args(self, url):
313
+ return super().create_connect_args(
314
+ url, _translate_args=dict(username="user", database="db")
315
+ )
316
+
317
+ def is_disconnect(self, e, connection, cursor):
318
+ if super().is_disconnect(e, connection, cursor):
319
+ return True
320
+ else:
321
+ str_e = str(e).lower()
322
+ return "not connected" in str_e
323
+
324
+ def _found_rows_client_flag(self):
325
+ from pymysql.constants import CLIENT
326
+
327
+ return CLIENT.FOUND_ROWS
328
+
329
+ def get_driver_connection(self, connection):
330
+ return connection._connection
331
+
332
+
333
+ dialect = MySQLDialect_aiomysql