SQLAlchemy 2.0.47__cp313-cp313t-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 (274) hide show
  1. sqlalchemy/__init__.py +283 -0
  2. sqlalchemy/connectors/__init__.py +18 -0
  3. sqlalchemy/connectors/aioodbc.py +184 -0
  4. sqlalchemy/connectors/asyncio.py +429 -0
  5. sqlalchemy/connectors/pyodbc.py +250 -0
  6. sqlalchemy/cyextension/__init__.py +6 -0
  7. sqlalchemy/cyextension/collections.cp313t-win32.pyd +0 -0
  8. sqlalchemy/cyextension/collections.pyx +409 -0
  9. sqlalchemy/cyextension/immutabledict.cp313t-win32.pyd +0 -0
  10. sqlalchemy/cyextension/immutabledict.pxd +8 -0
  11. sqlalchemy/cyextension/immutabledict.pyx +133 -0
  12. sqlalchemy/cyextension/processors.cp313t-win32.pyd +0 -0
  13. sqlalchemy/cyextension/processors.pyx +68 -0
  14. sqlalchemy/cyextension/resultproxy.cp313t-win32.pyd +0 -0
  15. sqlalchemy/cyextension/resultproxy.pyx +102 -0
  16. sqlalchemy/cyextension/util.cp313t-win32.pyd +0 -0
  17. sqlalchemy/cyextension/util.pyx +90 -0
  18. sqlalchemy/dialects/__init__.py +62 -0
  19. sqlalchemy/dialects/_typing.py +30 -0
  20. sqlalchemy/dialects/mssql/__init__.py +88 -0
  21. sqlalchemy/dialects/mssql/aioodbc.py +63 -0
  22. sqlalchemy/dialects/mssql/base.py +4093 -0
  23. sqlalchemy/dialects/mssql/information_schema.py +285 -0
  24. sqlalchemy/dialects/mssql/json.py +129 -0
  25. sqlalchemy/dialects/mssql/provision.py +185 -0
  26. sqlalchemy/dialects/mssql/pymssql.py +126 -0
  27. sqlalchemy/dialects/mssql/pyodbc.py +760 -0
  28. sqlalchemy/dialects/mysql/__init__.py +104 -0
  29. sqlalchemy/dialects/mysql/aiomysql.py +250 -0
  30. sqlalchemy/dialects/mysql/asyncmy.py +231 -0
  31. sqlalchemy/dialects/mysql/base.py +3949 -0
  32. sqlalchemy/dialects/mysql/cymysql.py +106 -0
  33. sqlalchemy/dialects/mysql/dml.py +225 -0
  34. sqlalchemy/dialects/mysql/enumerated.py +282 -0
  35. sqlalchemy/dialects/mysql/expression.py +146 -0
  36. sqlalchemy/dialects/mysql/json.py +91 -0
  37. sqlalchemy/dialects/mysql/mariadb.py +72 -0
  38. sqlalchemy/dialects/mysql/mariadbconnector.py +322 -0
  39. sqlalchemy/dialects/mysql/mysqlconnector.py +302 -0
  40. sqlalchemy/dialects/mysql/mysqldb.py +314 -0
  41. sqlalchemy/dialects/mysql/provision.py +153 -0
  42. sqlalchemy/dialects/mysql/pymysql.py +158 -0
  43. sqlalchemy/dialects/mysql/pyodbc.py +157 -0
  44. sqlalchemy/dialects/mysql/reflection.py +727 -0
  45. sqlalchemy/dialects/mysql/reserved_words.py +570 -0
  46. sqlalchemy/dialects/mysql/types.py +835 -0
  47. sqlalchemy/dialects/oracle/__init__.py +81 -0
  48. sqlalchemy/dialects/oracle/base.py +3802 -0
  49. sqlalchemy/dialects/oracle/cx_oracle.py +1555 -0
  50. sqlalchemy/dialects/oracle/dictionary.py +507 -0
  51. sqlalchemy/dialects/oracle/oracledb.py +941 -0
  52. sqlalchemy/dialects/oracle/provision.py +297 -0
  53. sqlalchemy/dialects/oracle/types.py +316 -0
  54. sqlalchemy/dialects/oracle/vector.py +365 -0
  55. sqlalchemy/dialects/postgresql/__init__.py +167 -0
  56. sqlalchemy/dialects/postgresql/_psycopg_common.py +189 -0
  57. sqlalchemy/dialects/postgresql/array.py +519 -0
  58. sqlalchemy/dialects/postgresql/asyncpg.py +1284 -0
  59. sqlalchemy/dialects/postgresql/base.py +5378 -0
  60. sqlalchemy/dialects/postgresql/dml.py +339 -0
  61. sqlalchemy/dialects/postgresql/ext.py +540 -0
  62. sqlalchemy/dialects/postgresql/hstore.py +406 -0
  63. sqlalchemy/dialects/postgresql/json.py +404 -0
  64. sqlalchemy/dialects/postgresql/named_types.py +524 -0
  65. sqlalchemy/dialects/postgresql/operators.py +129 -0
  66. sqlalchemy/dialects/postgresql/pg8000.py +669 -0
  67. sqlalchemy/dialects/postgresql/pg_catalog.py +326 -0
  68. sqlalchemy/dialects/postgresql/provision.py +183 -0
  69. sqlalchemy/dialects/postgresql/psycopg.py +862 -0
  70. sqlalchemy/dialects/postgresql/psycopg2.py +892 -0
  71. sqlalchemy/dialects/postgresql/psycopg2cffi.py +61 -0
  72. sqlalchemy/dialects/postgresql/ranges.py +1031 -0
  73. sqlalchemy/dialects/postgresql/types.py +313 -0
  74. sqlalchemy/dialects/sqlite/__init__.py +57 -0
  75. sqlalchemy/dialects/sqlite/aiosqlite.py +482 -0
  76. sqlalchemy/dialects/sqlite/base.py +3056 -0
  77. sqlalchemy/dialects/sqlite/dml.py +263 -0
  78. sqlalchemy/dialects/sqlite/json.py +92 -0
  79. sqlalchemy/dialects/sqlite/provision.py +229 -0
  80. sqlalchemy/dialects/sqlite/pysqlcipher.py +157 -0
  81. sqlalchemy/dialects/sqlite/pysqlite.py +756 -0
  82. sqlalchemy/dialects/type_migration_guidelines.txt +145 -0
  83. sqlalchemy/engine/__init__.py +62 -0
  84. sqlalchemy/engine/_py_processors.py +136 -0
  85. sqlalchemy/engine/_py_row.py +128 -0
  86. sqlalchemy/engine/_py_util.py +74 -0
  87. sqlalchemy/engine/base.py +3390 -0
  88. sqlalchemy/engine/characteristics.py +155 -0
  89. sqlalchemy/engine/create.py +893 -0
  90. sqlalchemy/engine/cursor.py +2298 -0
  91. sqlalchemy/engine/default.py +2394 -0
  92. sqlalchemy/engine/events.py +965 -0
  93. sqlalchemy/engine/interfaces.py +3471 -0
  94. sqlalchemy/engine/mock.py +134 -0
  95. sqlalchemy/engine/processors.py +61 -0
  96. sqlalchemy/engine/reflection.py +2102 -0
  97. sqlalchemy/engine/result.py +2399 -0
  98. sqlalchemy/engine/row.py +400 -0
  99. sqlalchemy/engine/strategies.py +16 -0
  100. sqlalchemy/engine/url.py +924 -0
  101. sqlalchemy/engine/util.py +167 -0
  102. sqlalchemy/event/__init__.py +26 -0
  103. sqlalchemy/event/api.py +220 -0
  104. sqlalchemy/event/attr.py +676 -0
  105. sqlalchemy/event/base.py +472 -0
  106. sqlalchemy/event/legacy.py +258 -0
  107. sqlalchemy/event/registry.py +390 -0
  108. sqlalchemy/events.py +17 -0
  109. sqlalchemy/exc.py +832 -0
  110. sqlalchemy/ext/__init__.py +11 -0
  111. sqlalchemy/ext/associationproxy.py +2027 -0
  112. sqlalchemy/ext/asyncio/__init__.py +25 -0
  113. sqlalchemy/ext/asyncio/base.py +281 -0
  114. sqlalchemy/ext/asyncio/engine.py +1471 -0
  115. sqlalchemy/ext/asyncio/exc.py +21 -0
  116. sqlalchemy/ext/asyncio/result.py +965 -0
  117. sqlalchemy/ext/asyncio/scoping.py +1599 -0
  118. sqlalchemy/ext/asyncio/session.py +1947 -0
  119. sqlalchemy/ext/automap.py +1701 -0
  120. sqlalchemy/ext/baked.py +570 -0
  121. sqlalchemy/ext/compiler.py +600 -0
  122. sqlalchemy/ext/declarative/__init__.py +65 -0
  123. sqlalchemy/ext/declarative/extensions.py +564 -0
  124. sqlalchemy/ext/horizontal_shard.py +478 -0
  125. sqlalchemy/ext/hybrid.py +1535 -0
  126. sqlalchemy/ext/indexable.py +364 -0
  127. sqlalchemy/ext/instrumentation.py +450 -0
  128. sqlalchemy/ext/mutable.py +1085 -0
  129. sqlalchemy/ext/mypy/__init__.py +6 -0
  130. sqlalchemy/ext/mypy/apply.py +324 -0
  131. sqlalchemy/ext/mypy/decl_class.py +515 -0
  132. sqlalchemy/ext/mypy/infer.py +590 -0
  133. sqlalchemy/ext/mypy/names.py +335 -0
  134. sqlalchemy/ext/mypy/plugin.py +303 -0
  135. sqlalchemy/ext/mypy/util.py +357 -0
  136. sqlalchemy/ext/orderinglist.py +439 -0
  137. sqlalchemy/ext/serializer.py +185 -0
  138. sqlalchemy/future/__init__.py +16 -0
  139. sqlalchemy/future/engine.py +15 -0
  140. sqlalchemy/inspection.py +174 -0
  141. sqlalchemy/log.py +288 -0
  142. sqlalchemy/orm/__init__.py +171 -0
  143. sqlalchemy/orm/_orm_constructors.py +2661 -0
  144. sqlalchemy/orm/_typing.py +179 -0
  145. sqlalchemy/orm/attributes.py +2845 -0
  146. sqlalchemy/orm/base.py +971 -0
  147. sqlalchemy/orm/bulk_persistence.py +2135 -0
  148. sqlalchemy/orm/clsregistry.py +571 -0
  149. sqlalchemy/orm/collections.py +1627 -0
  150. sqlalchemy/orm/context.py +3334 -0
  151. sqlalchemy/orm/decl_api.py +2004 -0
  152. sqlalchemy/orm/decl_base.py +2192 -0
  153. sqlalchemy/orm/dependency.py +1302 -0
  154. sqlalchemy/orm/descriptor_props.py +1092 -0
  155. sqlalchemy/orm/dynamic.py +300 -0
  156. sqlalchemy/orm/evaluator.py +379 -0
  157. sqlalchemy/orm/events.py +3252 -0
  158. sqlalchemy/orm/exc.py +237 -0
  159. sqlalchemy/orm/identity.py +302 -0
  160. sqlalchemy/orm/instrumentation.py +754 -0
  161. sqlalchemy/orm/interfaces.py +1496 -0
  162. sqlalchemy/orm/loading.py +1686 -0
  163. sqlalchemy/orm/mapped_collection.py +557 -0
  164. sqlalchemy/orm/mapper.py +4444 -0
  165. sqlalchemy/orm/path_registry.py +809 -0
  166. sqlalchemy/orm/persistence.py +1788 -0
  167. sqlalchemy/orm/properties.py +935 -0
  168. sqlalchemy/orm/query.py +3459 -0
  169. sqlalchemy/orm/relationships.py +3508 -0
  170. sqlalchemy/orm/scoping.py +2148 -0
  171. sqlalchemy/orm/session.py +5280 -0
  172. sqlalchemy/orm/state.py +1168 -0
  173. sqlalchemy/orm/state_changes.py +196 -0
  174. sqlalchemy/orm/strategies.py +3470 -0
  175. sqlalchemy/orm/strategy_options.py +2568 -0
  176. sqlalchemy/orm/sync.py +164 -0
  177. sqlalchemy/orm/unitofwork.py +796 -0
  178. sqlalchemy/orm/util.py +2403 -0
  179. sqlalchemy/orm/writeonly.py +674 -0
  180. sqlalchemy/pool/__init__.py +44 -0
  181. sqlalchemy/pool/base.py +1524 -0
  182. sqlalchemy/pool/events.py +375 -0
  183. sqlalchemy/pool/impl.py +588 -0
  184. sqlalchemy/py.typed +0 -0
  185. sqlalchemy/schema.py +69 -0
  186. sqlalchemy/sql/__init__.py +145 -0
  187. sqlalchemy/sql/_dml_constructors.py +132 -0
  188. sqlalchemy/sql/_elements_constructors.py +1872 -0
  189. sqlalchemy/sql/_orm_types.py +20 -0
  190. sqlalchemy/sql/_py_util.py +75 -0
  191. sqlalchemy/sql/_selectable_constructors.py +763 -0
  192. sqlalchemy/sql/_typing.py +482 -0
  193. sqlalchemy/sql/annotation.py +587 -0
  194. sqlalchemy/sql/base.py +2293 -0
  195. sqlalchemy/sql/cache_key.py +1057 -0
  196. sqlalchemy/sql/coercions.py +1404 -0
  197. sqlalchemy/sql/compiler.py +8081 -0
  198. sqlalchemy/sql/crud.py +1752 -0
  199. sqlalchemy/sql/ddl.py +1444 -0
  200. sqlalchemy/sql/default_comparator.py +551 -0
  201. sqlalchemy/sql/dml.py +1850 -0
  202. sqlalchemy/sql/elements.py +5589 -0
  203. sqlalchemy/sql/events.py +458 -0
  204. sqlalchemy/sql/expression.py +159 -0
  205. sqlalchemy/sql/functions.py +2158 -0
  206. sqlalchemy/sql/lambdas.py +1442 -0
  207. sqlalchemy/sql/naming.py +209 -0
  208. sqlalchemy/sql/operators.py +2623 -0
  209. sqlalchemy/sql/roles.py +323 -0
  210. sqlalchemy/sql/schema.py +6222 -0
  211. sqlalchemy/sql/selectable.py +7265 -0
  212. sqlalchemy/sql/sqltypes.py +3930 -0
  213. sqlalchemy/sql/traversals.py +1024 -0
  214. sqlalchemy/sql/type_api.py +2368 -0
  215. sqlalchemy/sql/util.py +1485 -0
  216. sqlalchemy/sql/visitors.py +1164 -0
  217. sqlalchemy/testing/__init__.py +96 -0
  218. sqlalchemy/testing/assertions.py +994 -0
  219. sqlalchemy/testing/assertsql.py +520 -0
  220. sqlalchemy/testing/asyncio.py +135 -0
  221. sqlalchemy/testing/config.py +434 -0
  222. sqlalchemy/testing/engines.py +483 -0
  223. sqlalchemy/testing/entities.py +117 -0
  224. sqlalchemy/testing/exclusions.py +476 -0
  225. sqlalchemy/testing/fixtures/__init__.py +28 -0
  226. sqlalchemy/testing/fixtures/base.py +384 -0
  227. sqlalchemy/testing/fixtures/mypy.py +332 -0
  228. sqlalchemy/testing/fixtures/orm.py +227 -0
  229. sqlalchemy/testing/fixtures/sql.py +482 -0
  230. sqlalchemy/testing/pickleable.py +155 -0
  231. sqlalchemy/testing/plugin/__init__.py +6 -0
  232. sqlalchemy/testing/plugin/bootstrap.py +51 -0
  233. sqlalchemy/testing/plugin/plugin_base.py +828 -0
  234. sqlalchemy/testing/plugin/pytestplugin.py +892 -0
  235. sqlalchemy/testing/profiling.py +329 -0
  236. sqlalchemy/testing/provision.py +603 -0
  237. sqlalchemy/testing/requirements.py +1945 -0
  238. sqlalchemy/testing/schema.py +198 -0
  239. sqlalchemy/testing/suite/__init__.py +19 -0
  240. sqlalchemy/testing/suite/test_cte.py +237 -0
  241. sqlalchemy/testing/suite/test_ddl.py +389 -0
  242. sqlalchemy/testing/suite/test_deprecations.py +153 -0
  243. sqlalchemy/testing/suite/test_dialect.py +776 -0
  244. sqlalchemy/testing/suite/test_insert.py +630 -0
  245. sqlalchemy/testing/suite/test_reflection.py +3557 -0
  246. sqlalchemy/testing/suite/test_results.py +504 -0
  247. sqlalchemy/testing/suite/test_rowcount.py +258 -0
  248. sqlalchemy/testing/suite/test_select.py +2010 -0
  249. sqlalchemy/testing/suite/test_sequence.py +317 -0
  250. sqlalchemy/testing/suite/test_types.py +2147 -0
  251. sqlalchemy/testing/suite/test_unicode_ddl.py +189 -0
  252. sqlalchemy/testing/suite/test_update_delete.py +139 -0
  253. sqlalchemy/testing/util.py +535 -0
  254. sqlalchemy/testing/warnings.py +52 -0
  255. sqlalchemy/types.py +74 -0
  256. sqlalchemy/util/__init__.py +162 -0
  257. sqlalchemy/util/_collections.py +712 -0
  258. sqlalchemy/util/_concurrency_py3k.py +288 -0
  259. sqlalchemy/util/_has_cy.py +40 -0
  260. sqlalchemy/util/_py_collections.py +541 -0
  261. sqlalchemy/util/compat.py +421 -0
  262. sqlalchemy/util/concurrency.py +110 -0
  263. sqlalchemy/util/deprecations.py +401 -0
  264. sqlalchemy/util/langhelpers.py +2203 -0
  265. sqlalchemy/util/preloaded.py +150 -0
  266. sqlalchemy/util/queue.py +322 -0
  267. sqlalchemy/util/tool_support.py +201 -0
  268. sqlalchemy/util/topological.py +120 -0
  269. sqlalchemy/util/typing.py +734 -0
  270. sqlalchemy-2.0.47.dist-info/METADATA +243 -0
  271. sqlalchemy-2.0.47.dist-info/RECORD +274 -0
  272. sqlalchemy-2.0.47.dist-info/WHEEL +5 -0
  273. sqlalchemy-2.0.47.dist-info/licenses/LICENSE +19 -0
  274. sqlalchemy-2.0.47.dist-info/top_level.txt +1 -0
@@ -0,0 +1,104 @@
1
+ # dialects/mysql/__init__.py
2
+ # Copyright (C) 2005-2026 the SQLAlchemy authors and contributors
3
+ # <see AUTHORS file>
4
+ #
5
+ # This module is part of SQLAlchemy and is released under
6
+ # the MIT License: https://www.opensource.org/licenses/mit-license.php
7
+ # 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 .mariadb import INET4
57
+ from .mariadb import INET6
58
+
59
+ # default dialect
60
+ base.dialect = dialect = mysqldb.dialect
61
+
62
+ __all__ = (
63
+ "BIGINT",
64
+ "BINARY",
65
+ "BIT",
66
+ "BLOB",
67
+ "BOOLEAN",
68
+ "CHAR",
69
+ "DATE",
70
+ "DATETIME",
71
+ "DECIMAL",
72
+ "DOUBLE",
73
+ "ENUM",
74
+ "FLOAT",
75
+ "INET4",
76
+ "INET6",
77
+ "INTEGER",
78
+ "INTEGER",
79
+ "JSON",
80
+ "LONGBLOB",
81
+ "LONGTEXT",
82
+ "MEDIUMBLOB",
83
+ "MEDIUMINT",
84
+ "MEDIUMTEXT",
85
+ "NCHAR",
86
+ "NVARCHAR",
87
+ "NUMERIC",
88
+ "SET",
89
+ "SMALLINT",
90
+ "REAL",
91
+ "TEXT",
92
+ "TIME",
93
+ "TIMESTAMP",
94
+ "TINYBLOB",
95
+ "TINYINT",
96
+ "TINYTEXT",
97
+ "VARBINARY",
98
+ "VARCHAR",
99
+ "YEAR",
100
+ "dialect",
101
+ "insert",
102
+ "Insert",
103
+ "match",
104
+ )
@@ -0,0 +1,250 @@
1
+ # dialects/mysql/aiomysql.py
2
+ # Copyright (C) 2005-2026 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
+
8
+ r"""
9
+ .. dialect:: mysql+aiomysql
10
+ :name: aiomysql
11
+ :dbapi: aiomysql
12
+ :connectstring: mysql+aiomysql://user:password@host:port/dbname[?key=value&key=value...]
13
+ :url: https://github.com/aio-libs/aiomysql
14
+
15
+ The aiomysql dialect is SQLAlchemy's second Python asyncio dialect.
16
+
17
+ Using a special asyncio mediation layer, the aiomysql dialect is usable
18
+ as the backend for the :ref:`SQLAlchemy asyncio <asyncio_toplevel>`
19
+ extension package.
20
+
21
+ This dialect should normally be used only with the
22
+ :func:`_asyncio.create_async_engine` engine creation function::
23
+
24
+ from sqlalchemy.ext.asyncio import create_async_engine
25
+
26
+ engine = create_async_engine(
27
+ "mysql+aiomysql://user:pass@hostname/dbname?charset=utf8mb4"
28
+ )
29
+
30
+ """ # noqa
31
+ from __future__ import annotations
32
+
33
+ from types import ModuleType
34
+ from typing import Any
35
+ from typing import Dict
36
+ from typing import Optional
37
+ from typing import Tuple
38
+ from typing import TYPE_CHECKING
39
+ from typing import Union
40
+
41
+ from .pymysql import MySQLDialect_pymysql
42
+ from ... import pool
43
+ from ... import util
44
+ from ...connectors.asyncio import AsyncAdapt_dbapi_connection
45
+ from ...connectors.asyncio import AsyncAdapt_dbapi_cursor
46
+ from ...connectors.asyncio import AsyncAdapt_dbapi_module
47
+ from ...connectors.asyncio import AsyncAdapt_dbapi_ss_cursor
48
+ from ...connectors.asyncio import AsyncAdapt_terminate
49
+ from ...util.concurrency import await_fallback
50
+ from ...util.concurrency import await_only
51
+
52
+ if TYPE_CHECKING:
53
+
54
+ from ...connectors.asyncio import AsyncIODBAPIConnection
55
+ from ...connectors.asyncio import AsyncIODBAPICursor
56
+ from ...engine.interfaces import ConnectArgsType
57
+ from ...engine.interfaces import DBAPIConnection
58
+ from ...engine.interfaces import DBAPICursor
59
+ from ...engine.interfaces import DBAPIModule
60
+ from ...engine.interfaces import PoolProxiedConnection
61
+ from ...engine.url import URL
62
+
63
+
64
+ class AsyncAdapt_aiomysql_cursor(AsyncAdapt_dbapi_cursor):
65
+ __slots__ = ()
66
+
67
+ def _make_new_cursor(
68
+ self, connection: AsyncIODBAPIConnection
69
+ ) -> AsyncIODBAPICursor:
70
+ return connection.cursor(self._adapt_connection.dbapi.Cursor)
71
+
72
+
73
+ class AsyncAdapt_aiomysql_ss_cursor(
74
+ AsyncAdapt_dbapi_ss_cursor, AsyncAdapt_aiomysql_cursor
75
+ ):
76
+ __slots__ = ()
77
+
78
+ def _make_new_cursor(
79
+ self, connection: AsyncIODBAPIConnection
80
+ ) -> AsyncIODBAPICursor:
81
+ return connection.cursor(
82
+ self._adapt_connection.dbapi.aiomysql.cursors.SSCursor
83
+ )
84
+
85
+
86
+ class AsyncAdapt_aiomysql_connection(
87
+ AsyncAdapt_terminate, AsyncAdapt_dbapi_connection
88
+ ):
89
+ __slots__ = ()
90
+
91
+ _cursor_cls = AsyncAdapt_aiomysql_cursor
92
+ _ss_cursor_cls = AsyncAdapt_aiomysql_ss_cursor
93
+
94
+ def ping(self, reconnect: bool) -> None:
95
+ assert not reconnect
96
+ self.await_(self._connection.ping(reconnect))
97
+
98
+ def character_set_name(self) -> Optional[str]:
99
+ return self._connection.character_set_name() # type: ignore[no-any-return] # noqa: E501
100
+
101
+ def autocommit(self, value: Any) -> None:
102
+ self.await_(self._connection.autocommit(value))
103
+
104
+ def get_autocommit(self) -> bool:
105
+ return self._connection.get_autocommit() # type: ignore
106
+
107
+ def close(self) -> None:
108
+ self.await_(self._connection.ensure_closed())
109
+
110
+ async def _terminate_graceful_close(self) -> None:
111
+ await self._connection.ensure_closed()
112
+
113
+ def _terminate_force_close(self) -> None:
114
+ # it's not awaitable.
115
+ self._connection.close()
116
+
117
+
118
+ class AsyncAdaptFallback_aiomysql_connection(AsyncAdapt_aiomysql_connection):
119
+ __slots__ = ()
120
+
121
+ await_ = staticmethod(await_fallback)
122
+
123
+
124
+ class AsyncAdapt_aiomysql_dbapi(AsyncAdapt_dbapi_module):
125
+ def __init__(self, aiomysql: ModuleType, pymysql: ModuleType):
126
+ self.aiomysql = aiomysql
127
+ self.pymysql = pymysql
128
+ self.paramstyle = "format"
129
+ self._init_dbapi_attributes()
130
+ self.Cursor, self.SSCursor = self._init_cursors_subclasses()
131
+
132
+ def _init_dbapi_attributes(self) -> None:
133
+ for name in (
134
+ "Warning",
135
+ "Error",
136
+ "InterfaceError",
137
+ "DataError",
138
+ "DatabaseError",
139
+ "OperationalError",
140
+ "InterfaceError",
141
+ "IntegrityError",
142
+ "ProgrammingError",
143
+ "InternalError",
144
+ "NotSupportedError",
145
+ ):
146
+ setattr(self, name, getattr(self.aiomysql, name))
147
+
148
+ for name in (
149
+ "NUMBER",
150
+ "STRING",
151
+ "DATETIME",
152
+ "BINARY",
153
+ "TIMESTAMP",
154
+ "Binary",
155
+ ):
156
+ setattr(self, name, getattr(self.pymysql, name))
157
+
158
+ def connect(self, *arg: Any, **kw: Any) -> AsyncAdapt_aiomysql_connection:
159
+ async_fallback = kw.pop("async_fallback", False)
160
+ creator_fn = kw.pop("async_creator_fn", self.aiomysql.connect)
161
+
162
+ if util.asbool(async_fallback):
163
+ return AsyncAdaptFallback_aiomysql_connection(
164
+ self,
165
+ await_fallback(creator_fn(*arg, **kw)),
166
+ )
167
+ else:
168
+ return AsyncAdapt_aiomysql_connection(
169
+ self,
170
+ await_only(creator_fn(*arg, **kw)),
171
+ )
172
+
173
+ def _init_cursors_subclasses(
174
+ self,
175
+ ) -> Tuple[AsyncIODBAPICursor, AsyncIODBAPICursor]:
176
+ # suppress unconditional warning emitted by aiomysql
177
+ class Cursor(self.aiomysql.Cursor): # type: ignore[misc, name-defined]
178
+ async def _show_warnings(
179
+ self, conn: AsyncIODBAPIConnection
180
+ ) -> None:
181
+ pass
182
+
183
+ class SSCursor(self.aiomysql.SSCursor): # type: ignore[misc, name-defined] # noqa: E501
184
+ async def _show_warnings(
185
+ self, conn: AsyncIODBAPIConnection
186
+ ) -> None:
187
+ pass
188
+
189
+ return Cursor, SSCursor # type: ignore[return-value]
190
+
191
+
192
+ class MySQLDialect_aiomysql(MySQLDialect_pymysql):
193
+ driver = "aiomysql"
194
+ supports_statement_cache = True
195
+
196
+ supports_server_side_cursors = True
197
+ _sscursor = AsyncAdapt_aiomysql_ss_cursor
198
+
199
+ is_async = True
200
+ has_terminate = True
201
+
202
+ @classmethod
203
+ def import_dbapi(cls) -> AsyncAdapt_aiomysql_dbapi:
204
+ return AsyncAdapt_aiomysql_dbapi(
205
+ __import__("aiomysql"), __import__("pymysql")
206
+ )
207
+
208
+ @classmethod
209
+ def get_pool_class(cls, url: URL) -> type:
210
+ async_fallback = url.query.get("async_fallback", False)
211
+
212
+ if util.asbool(async_fallback):
213
+ return pool.FallbackAsyncAdaptedQueuePool
214
+ else:
215
+ return pool.AsyncAdaptedQueuePool
216
+
217
+ def do_terminate(self, dbapi_connection: DBAPIConnection) -> None:
218
+ dbapi_connection.terminate()
219
+
220
+ def create_connect_args(
221
+ self, url: URL, _translate_args: Optional[Dict[str, Any]] = None
222
+ ) -> ConnectArgsType:
223
+ return super().create_connect_args(
224
+ url, _translate_args=dict(username="user", database="db")
225
+ )
226
+
227
+ def is_disconnect(
228
+ self,
229
+ e: DBAPIModule.Error,
230
+ connection: Optional[Union[PoolProxiedConnection, DBAPIConnection]],
231
+ cursor: Optional[DBAPICursor],
232
+ ) -> bool:
233
+ if super().is_disconnect(e, connection, cursor):
234
+ return True
235
+ else:
236
+ str_e = str(e).lower()
237
+ return "not connected" in str_e
238
+
239
+ def _found_rows_client_flag(self) -> int:
240
+ from pymysql.constants import CLIENT # type: ignore
241
+
242
+ return CLIENT.FOUND_ROWS # type: ignore[no-any-return]
243
+
244
+ def get_driver_connection(
245
+ self, connection: DBAPIConnection
246
+ ) -> AsyncIODBAPIConnection:
247
+ return connection._connection # type: ignore[no-any-return]
248
+
249
+
250
+ dialect = MySQLDialect_aiomysql
@@ -0,0 +1,231 @@
1
+ # dialects/mysql/asyncmy.py
2
+ # Copyright (C) 2005-2026 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
+
8
+ r"""
9
+ .. dialect:: mysql+asyncmy
10
+ :name: asyncmy
11
+ :dbapi: asyncmy
12
+ :connectstring: mysql+asyncmy://user:password@host:port/dbname[?key=value&key=value...]
13
+ :url: https://github.com/long2ice/asyncmy
14
+
15
+ Using a special asyncio mediation layer, the asyncmy dialect is usable
16
+ as the backend for the :ref:`SQLAlchemy asyncio <asyncio_toplevel>`
17
+ extension package.
18
+
19
+ This dialect should normally be used only with the
20
+ :func:`_asyncio.create_async_engine` engine creation function::
21
+
22
+ from sqlalchemy.ext.asyncio import create_async_engine
23
+
24
+ engine = create_async_engine(
25
+ "mysql+asyncmy://user:pass@hostname/dbname?charset=utf8mb4"
26
+ )
27
+
28
+ """ # noqa
29
+ from __future__ import annotations
30
+
31
+ from types import ModuleType
32
+ from typing import Any
33
+ from typing import NoReturn
34
+ from typing import Optional
35
+ from typing import TYPE_CHECKING
36
+ from typing import Union
37
+
38
+ from .pymysql import MySQLDialect_pymysql
39
+ from ... import pool
40
+ from ... import util
41
+ from ...connectors.asyncio import AsyncAdapt_dbapi_connection
42
+ from ...connectors.asyncio import AsyncAdapt_dbapi_cursor
43
+ from ...connectors.asyncio import AsyncAdapt_dbapi_module
44
+ from ...connectors.asyncio import AsyncAdapt_dbapi_ss_cursor
45
+ from ...connectors.asyncio import AsyncAdapt_terminate
46
+ from ...util.concurrency import await_fallback
47
+ from ...util.concurrency import await_only
48
+
49
+ if TYPE_CHECKING:
50
+ from ...connectors.asyncio import AsyncIODBAPIConnection
51
+ from ...connectors.asyncio import AsyncIODBAPICursor
52
+ from ...engine.interfaces import ConnectArgsType
53
+ from ...engine.interfaces import DBAPIConnection
54
+ from ...engine.interfaces import DBAPICursor
55
+ from ...engine.interfaces import DBAPIModule
56
+ from ...engine.interfaces import PoolProxiedConnection
57
+ from ...engine.url import URL
58
+
59
+
60
+ class AsyncAdapt_asyncmy_cursor(AsyncAdapt_dbapi_cursor):
61
+ __slots__ = ()
62
+
63
+
64
+ class AsyncAdapt_asyncmy_ss_cursor(
65
+ AsyncAdapt_dbapi_ss_cursor, AsyncAdapt_asyncmy_cursor
66
+ ):
67
+ __slots__ = ()
68
+
69
+ def _make_new_cursor(
70
+ self, connection: AsyncIODBAPIConnection
71
+ ) -> AsyncIODBAPICursor:
72
+ return connection.cursor(
73
+ self._adapt_connection.dbapi.asyncmy.cursors.SSCursor
74
+ )
75
+
76
+
77
+ class AsyncAdapt_asyncmy_connection(
78
+ AsyncAdapt_terminate, AsyncAdapt_dbapi_connection
79
+ ):
80
+ __slots__ = ()
81
+
82
+ _cursor_cls = AsyncAdapt_asyncmy_cursor
83
+ _ss_cursor_cls = AsyncAdapt_asyncmy_ss_cursor
84
+
85
+ def _handle_exception(self, error: Exception) -> NoReturn:
86
+ if isinstance(error, AttributeError):
87
+ raise self.dbapi.InternalError(
88
+ "network operation failed due to asyncmy attribute error"
89
+ )
90
+
91
+ raise error
92
+
93
+ def ping(self, reconnect: bool) -> None:
94
+ assert not reconnect
95
+ return self.await_(self._do_ping())
96
+
97
+ async def _do_ping(self) -> None:
98
+ try:
99
+ async with self._execute_mutex:
100
+ await self._connection.ping(False)
101
+ except Exception as error:
102
+ self._handle_exception(error)
103
+
104
+ def character_set_name(self) -> Optional[str]:
105
+ return self._connection.character_set_name() # type: ignore[no-any-return] # noqa: E501
106
+
107
+ def autocommit(self, value: Any) -> None:
108
+ self.await_(self._connection.autocommit(value))
109
+
110
+ def get_autocommit(self) -> bool:
111
+ return self._connection.get_autocommit() # type: ignore
112
+
113
+ def close(self) -> None:
114
+ self.await_(self._connection.ensure_closed())
115
+
116
+ async def _terminate_graceful_close(self) -> None:
117
+ await self._connection.ensure_closed()
118
+
119
+ def _terminate_force_close(self) -> None:
120
+ # it's not awaitable.
121
+ self._connection.close()
122
+
123
+
124
+ class AsyncAdaptFallback_asyncmy_connection(AsyncAdapt_asyncmy_connection):
125
+ __slots__ = ()
126
+
127
+ await_ = staticmethod(await_fallback)
128
+
129
+
130
+ class AsyncAdapt_asyncmy_dbapi(AsyncAdapt_dbapi_module):
131
+ def __init__(self, asyncmy: ModuleType):
132
+ self.asyncmy = asyncmy
133
+ self.paramstyle = "format"
134
+ self._init_dbapi_attributes()
135
+
136
+ def _init_dbapi_attributes(self) -> None:
137
+ for name in (
138
+ "Warning",
139
+ "Error",
140
+ "InterfaceError",
141
+ "DataError",
142
+ "DatabaseError",
143
+ "OperationalError",
144
+ "InterfaceError",
145
+ "IntegrityError",
146
+ "ProgrammingError",
147
+ "InternalError",
148
+ "NotSupportedError",
149
+ ):
150
+ setattr(self, name, getattr(self.asyncmy.errors, name))
151
+
152
+ STRING = util.symbol("STRING")
153
+ NUMBER = util.symbol("NUMBER")
154
+ BINARY = util.symbol("BINARY")
155
+ DATETIME = util.symbol("DATETIME")
156
+ TIMESTAMP = util.symbol("TIMESTAMP")
157
+ Binary = staticmethod(bytes)
158
+
159
+ def connect(self, *arg: Any, **kw: Any) -> AsyncAdapt_asyncmy_connection:
160
+ async_fallback = kw.pop("async_fallback", False)
161
+ creator_fn = kw.pop("async_creator_fn", self.asyncmy.connect)
162
+
163
+ if util.asbool(async_fallback):
164
+ return AsyncAdaptFallback_asyncmy_connection(
165
+ self,
166
+ await_fallback(creator_fn(*arg, **kw)),
167
+ )
168
+ else:
169
+ return AsyncAdapt_asyncmy_connection(
170
+ self,
171
+ await_only(creator_fn(*arg, **kw)),
172
+ )
173
+
174
+
175
+ class MySQLDialect_asyncmy(MySQLDialect_pymysql):
176
+ driver = "asyncmy"
177
+ supports_statement_cache = True
178
+
179
+ supports_server_side_cursors = True
180
+ _sscursor = AsyncAdapt_asyncmy_ss_cursor
181
+
182
+ is_async = True
183
+ has_terminate = True
184
+
185
+ @classmethod
186
+ def import_dbapi(cls) -> DBAPIModule:
187
+ return AsyncAdapt_asyncmy_dbapi(__import__("asyncmy"))
188
+
189
+ @classmethod
190
+ def get_pool_class(cls, url: URL) -> type:
191
+ async_fallback = url.query.get("async_fallback", False)
192
+
193
+ if util.asbool(async_fallback):
194
+ return pool.FallbackAsyncAdaptedQueuePool
195
+ else:
196
+ return pool.AsyncAdaptedQueuePool
197
+
198
+ def do_terminate(self, dbapi_connection: DBAPIConnection) -> None:
199
+ dbapi_connection.terminate()
200
+
201
+ def create_connect_args(self, url: URL) -> ConnectArgsType: # type: ignore[override] # noqa: E501
202
+ return super().create_connect_args(
203
+ url, _translate_args=dict(username="user", database="db")
204
+ )
205
+
206
+ def is_disconnect(
207
+ self,
208
+ e: DBAPIModule.Error,
209
+ connection: Optional[Union[PoolProxiedConnection, DBAPIConnection]],
210
+ cursor: Optional[DBAPICursor],
211
+ ) -> bool:
212
+ if super().is_disconnect(e, connection, cursor):
213
+ return True
214
+ else:
215
+ str_e = str(e).lower()
216
+ return (
217
+ "not connected" in str_e or "network operation failed" in str_e
218
+ )
219
+
220
+ def _found_rows_client_flag(self) -> int:
221
+ from asyncmy.constants import CLIENT # type: ignore
222
+
223
+ return CLIENT.FOUND_ROWS # type: ignore[no-any-return]
224
+
225
+ def get_driver_connection(
226
+ self, connection: DBAPIConnection
227
+ ) -> AsyncIODBAPIConnection:
228
+ return connection._connection # type: ignore[no-any-return]
229
+
230
+
231
+ dialect = MySQLDialect_asyncmy