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,145 @@
1
+ Rules for Migrating TypeEngine classes to 0.6
2
+ ---------------------------------------------
3
+
4
+ 1. the TypeEngine classes are used for:
5
+
6
+ a. Specifying behavior which needs to occur for bind parameters
7
+ or result row columns.
8
+
9
+ b. Specifying types that are entirely specific to the database
10
+ in use and have no analogue in the sqlalchemy.types package.
11
+
12
+ c. Specifying types where there is an analogue in sqlalchemy.types,
13
+ but the database in use takes vendor-specific flags for those
14
+ types.
15
+
16
+ d. If a TypeEngine class doesn't provide any of this, it should be
17
+ *removed* from the dialect.
18
+
19
+ 2. the TypeEngine classes are *no longer* used for generating DDL. Dialects
20
+ now have a TypeCompiler subclass which uses the same visit_XXX model as
21
+ other compilers.
22
+
23
+ 3. the "ischema_names" and "colspecs" dictionaries are now required members on
24
+ the Dialect class.
25
+
26
+ 4. The names of types within dialects are now important. If a dialect-specific type
27
+ is a subclass of an existing generic type and is only provided for bind/result behavior,
28
+ the current mixed case naming can remain, i.e. _PGNumeric for Numeric - in this case,
29
+ end users would never need to use _PGNumeric directly. However, if a dialect-specific
30
+ type is specifying a type *or* arguments that are not present generically, it should
31
+ match the real name of the type on that backend, in uppercase. E.g. postgresql.INET,
32
+ mysql.ENUM, postgresql.ARRAY.
33
+
34
+ Or follow this handy flowchart:
35
+
36
+ is the type meant to provide bind/result is the type the same name as an
37
+ behavior to a generic type (i.e. MixedCase) ---- no ---> UPPERCASE type in types.py ?
38
+ type in types.py ? | |
39
+ | no yes
40
+ yes | |
41
+ | | does your type need special
42
+ | +<--- yes --- behavior or arguments ?
43
+ | | |
44
+ | | no
45
+ name the type using | |
46
+ _MixedCase, i.e. v V
47
+ _OracleBoolean. it name the type don't make a
48
+ stays private to the dialect identically as that type, make sure the dialect's
49
+ and is invoked *only* via within the DB, base.py imports the types.py
50
+ the colspecs dict. using UPPERCASE UPPERCASE name into its namespace
51
+ | (i.e. BIT, NCHAR, INTERVAL).
52
+ | Users can import it.
53
+ | |
54
+ v v
55
+ subclass the closest is the name of this type
56
+ MixedCase type types.py, identical to an UPPERCASE
57
+ i.e. <--- no ------- name in types.py ?
58
+ class _DateTime(types.DateTime),
59
+ class DATETIME2(types.DateTime), |
60
+ class BIT(types.TypeEngine). yes
61
+ |
62
+ v
63
+ the type should
64
+ subclass the
65
+ UPPERCASE
66
+ type in types.py
67
+ (i.e. class BLOB(types.BLOB))
68
+
69
+
70
+ Example 1. pysqlite needs bind/result processing for the DateTime type in types.py,
71
+ which applies to all DateTimes and subclasses. It's named _SLDateTime and
72
+ subclasses types.DateTime.
73
+
74
+ Example 2. MS-SQL has a TIME type which takes a non-standard "precision" argument
75
+ that is rendered within DDL. So it's named TIME in the MS-SQL dialect's base.py,
76
+ and subclasses types.TIME. Users can then say mssql.TIME(precision=10).
77
+
78
+ Example 3. MS-SQL dialects also need special bind/result processing for date
79
+ But its DATE type doesn't render DDL differently than that of a plain
80
+ DATE, i.e. it takes no special arguments. Therefore we are just adding behavior
81
+ to types.Date, so it's named _MSDate in the MS-SQL dialect's base.py, and subclasses
82
+ types.Date.
83
+
84
+ Example 4. MySQL has a SET type, there's no analogue for this in types.py. So
85
+ MySQL names it SET in the dialect's base.py, and it subclasses types.String, since
86
+ it ultimately deals with strings.
87
+
88
+ Example 5. PostgreSQL has a DATETIME type. The DBAPIs handle dates correctly,
89
+ and no special arguments are used in PG's DDL beyond what types.py provides.
90
+ PostgreSQL dialect therefore imports types.DATETIME into its base.py.
91
+
92
+ Ideally one should be able to specify a schema using names imported completely from a
93
+ dialect, all matching the real name on that backend:
94
+
95
+ from sqlalchemy.dialects.postgresql import base as pg
96
+
97
+ t = Table('mytable', metadata,
98
+ Column('id', pg.INTEGER, primary_key=True),
99
+ Column('name', pg.VARCHAR(300)),
100
+ Column('inetaddr', pg.INET)
101
+ )
102
+
103
+ where above, the INTEGER and VARCHAR types are ultimately from sqlalchemy.types,
104
+ but the PG dialect makes them available in its own namespace.
105
+
106
+ 5. "colspecs" now is a dictionary of generic or uppercased types from sqlalchemy.types
107
+ linked to types specified in the dialect. Again, if a type in the dialect does not
108
+ specify any special behavior for bind_processor() or result_processor() and does not
109
+ indicate a special type only available in this database, it must be *removed* from the
110
+ module and from this dictionary.
111
+
112
+ 6. "ischema_names" indicates string descriptions of types as returned from the database
113
+ linked to TypeEngine classes.
114
+
115
+ a. The string name should be matched to the most specific type possible within
116
+ sqlalchemy.types, unless there is no matching type within sqlalchemy.types in which
117
+ case it points to a dialect type. *It doesn't matter* if the dialect has its
118
+ own subclass of that type with special bind/result behavior - reflect to the types.py
119
+ UPPERCASE type as much as possible. With very few exceptions, all types
120
+ should reflect to an UPPERCASE type.
121
+
122
+ b. If the dialect contains a matching dialect-specific type that takes extra arguments
123
+ which the generic one does not, then point to the dialect-specific type. E.g.
124
+ mssql.VARCHAR takes a "collation" parameter which should be preserved.
125
+
126
+ 5. DDL, or what was formerly issued by "get_col_spec()", is now handled exclusively by
127
+ a subclass of compiler.GenericTypeCompiler.
128
+
129
+ a. your TypeCompiler class will receive generic and uppercase types from
130
+ sqlalchemy.types. Do not assume the presence of dialect-specific attributes on
131
+ these types.
132
+
133
+ b. the visit_UPPERCASE methods on GenericTypeCompiler should *not* be overridden with
134
+ methods that produce a different DDL name. Uppercase types don't do any kind of
135
+ "guessing" - if visit_TIMESTAMP is called, the DDL should render as TIMESTAMP in
136
+ all cases, regardless of whether or not that type is legal on the backend database.
137
+
138
+ c. the visit_UPPERCASE methods *should* be overridden with methods that add additional
139
+ arguments and flags to those types.
140
+
141
+ d. the visit_lowercase methods are overridden to provide an interpretation of a generic
142
+ type. E.g. visit_large_binary() might be overridden to say "return self.visit_BIT(type_)".
143
+
144
+ e. visit_lowercase methods should *never* render strings directly - it should always
145
+ be via calling a visit_UPPERCASE() method.
@@ -0,0 +1,62 @@
1
+ # engine/__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
+
8
+ """SQL connections, SQL execution and high-level DB-API interface.
9
+
10
+ The engine package defines the basic components used to interface
11
+ DB-API modules with higher-level statement construction,
12
+ connection-management, execution and result contexts. The primary
13
+ "entry point" class into this package is the Engine and its public
14
+ constructor ``create_engine()``.
15
+
16
+ """
17
+
18
+ from . import events as events
19
+ from . import util as util
20
+ from .base import Connection as Connection
21
+ from .base import Engine as Engine
22
+ from .base import NestedTransaction as NestedTransaction
23
+ from .base import RootTransaction as RootTransaction
24
+ from .base import Transaction as Transaction
25
+ from .base import TwoPhaseTransaction as TwoPhaseTransaction
26
+ from .create import create_engine as create_engine
27
+ from .create import create_pool_from_url as create_pool_from_url
28
+ from .create import engine_from_config as engine_from_config
29
+ from .cursor import CursorResult as CursorResult
30
+ from .cursor import ResultProxy as ResultProxy
31
+ from .interfaces import AdaptedConnection as AdaptedConnection
32
+ from .interfaces import BindTyping as BindTyping
33
+ from .interfaces import Compiled as Compiled
34
+ from .interfaces import Connectable as Connectable
35
+ from .interfaces import ConnectArgsType as ConnectArgsType
36
+ from .interfaces import ConnectionEventsTarget as ConnectionEventsTarget
37
+ from .interfaces import CreateEnginePlugin as CreateEnginePlugin
38
+ from .interfaces import Dialect as Dialect
39
+ from .interfaces import ExceptionContext as ExceptionContext
40
+ from .interfaces import ExecutionContext as ExecutionContext
41
+ from .interfaces import TypeCompiler as TypeCompiler
42
+ from .mock import create_mock_engine as create_mock_engine
43
+ from .reflection import Inspector as Inspector
44
+ from .reflection import ObjectKind as ObjectKind
45
+ from .reflection import ObjectScope as ObjectScope
46
+ from .result import ChunkedIteratorResult as ChunkedIteratorResult
47
+ from .result import FilterResult as FilterResult
48
+ from .result import FrozenResult as FrozenResult
49
+ from .result import IteratorResult as IteratorResult
50
+ from .result import MappingResult as MappingResult
51
+ from .result import MergedResult as MergedResult
52
+ from .result import Result as Result
53
+ from .result import result_tuple as result_tuple
54
+ from .result import ScalarResult as ScalarResult
55
+ from .result import TupleResult as TupleResult
56
+ from .row import BaseRow as BaseRow
57
+ from .row import Row as Row
58
+ from .row import RowMapping as RowMapping
59
+ from .url import make_url as make_url
60
+ from .url import URL as URL
61
+ from .util import connection_memoize as connection_memoize
62
+ from ..sql import ddl as ddl
@@ -0,0 +1,136 @@
1
+ # engine/_py_processors.py
2
+ # Copyright (C) 2010-2026 the SQLAlchemy authors and contributors
3
+ # <see AUTHORS file>
4
+ # Copyright (C) 2010 Gaetan de Menten gdementen@gmail.com
5
+ #
6
+ # This module is part of SQLAlchemy and is released under
7
+ # the MIT License: https://www.opensource.org/licenses/mit-license.php
8
+
9
+ """defines generic type conversion functions, as used in bind and result
10
+ processors.
11
+
12
+ They all share one common characteristic: None is passed through unchanged.
13
+
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import datetime
19
+ from datetime import date as date_cls
20
+ from datetime import datetime as datetime_cls
21
+ from datetime import time as time_cls
22
+ from decimal import Decimal
23
+ import typing
24
+ from typing import Any
25
+ from typing import Callable
26
+ from typing import Optional
27
+ from typing import Type
28
+ from typing import TypeVar
29
+ from typing import Union
30
+
31
+
32
+ _DT = TypeVar(
33
+ "_DT", bound=Union[datetime.datetime, datetime.time, datetime.date]
34
+ )
35
+
36
+
37
+ def str_to_datetime_processor_factory(
38
+ regexp: typing.Pattern[str], type_: Callable[..., _DT]
39
+ ) -> Callable[[Optional[str]], Optional[_DT]]:
40
+ rmatch = regexp.match
41
+ # Even on python2.6 datetime.strptime is both slower than this code
42
+ # and it does not support microseconds.
43
+ has_named_groups = bool(regexp.groupindex)
44
+
45
+ def process(value: Optional[str]) -> Optional[_DT]:
46
+ if value is None:
47
+ return None
48
+ else:
49
+ try:
50
+ m = rmatch(value)
51
+ except TypeError as err:
52
+ raise ValueError(
53
+ "Couldn't parse %s string '%r' "
54
+ "- value is not a string." % (type_.__name__, value)
55
+ ) from err
56
+
57
+ if m is None:
58
+ raise ValueError(
59
+ "Couldn't parse %s string: "
60
+ "'%s'" % (type_.__name__, value)
61
+ )
62
+ if has_named_groups:
63
+ groups = m.groupdict(0)
64
+ return type_(
65
+ **dict(
66
+ list(
67
+ zip(
68
+ iter(groups.keys()),
69
+ list(map(int, iter(groups.values()))),
70
+ )
71
+ )
72
+ )
73
+ )
74
+ else:
75
+ return type_(*list(map(int, m.groups(0))))
76
+
77
+ return process
78
+
79
+
80
+ def to_decimal_processor_factory(
81
+ target_class: Type[Decimal], scale: int
82
+ ) -> Callable[[Optional[float]], Optional[Decimal]]:
83
+ fstring = "%%.%df" % scale
84
+
85
+ def process(value: Optional[float]) -> Optional[Decimal]:
86
+ if value is None:
87
+ return None
88
+ else:
89
+ return target_class(fstring % value)
90
+
91
+ return process
92
+
93
+
94
+ def to_float(value: Optional[Union[int, float]]) -> Optional[float]:
95
+ if value is None:
96
+ return None
97
+ else:
98
+ return float(value)
99
+
100
+
101
+ def to_str(value: Optional[Any]) -> Optional[str]:
102
+ if value is None:
103
+ return None
104
+ else:
105
+ return str(value)
106
+
107
+
108
+ def int_to_boolean(value: Optional[int]) -> Optional[bool]:
109
+ if value is None:
110
+ return None
111
+ else:
112
+ return bool(value)
113
+
114
+
115
+ def str_to_datetime(value: Optional[str]) -> Optional[datetime.datetime]:
116
+ if value is not None:
117
+ dt_value = datetime_cls.fromisoformat(value)
118
+ else:
119
+ dt_value = None
120
+ return dt_value
121
+
122
+
123
+ def str_to_time(value: Optional[str]) -> Optional[datetime.time]:
124
+ if value is not None:
125
+ dt_value = time_cls.fromisoformat(value)
126
+ else:
127
+ dt_value = None
128
+ return dt_value
129
+
130
+
131
+ def str_to_date(value: Optional[str]) -> Optional[datetime.date]:
132
+ if value is not None:
133
+ dt_value = date_cls.fromisoformat(value)
134
+ else:
135
+ dt_value = None
136
+ return dt_value
@@ -0,0 +1,128 @@
1
+ # engine/_py_row.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
+ from __future__ import annotations
8
+
9
+ import operator
10
+ import typing
11
+ from typing import Any
12
+ from typing import Callable
13
+ from typing import Dict
14
+ from typing import Iterator
15
+ from typing import List
16
+ from typing import Mapping
17
+ from typing import Optional
18
+ from typing import Tuple
19
+ from typing import Type
20
+
21
+ if typing.TYPE_CHECKING:
22
+ from .result import _KeyType
23
+ from .result import _ProcessorsType
24
+ from .result import _RawRowType
25
+ from .result import _TupleGetterType
26
+ from .result import ResultMetaData
27
+
28
+ MD_INDEX = 0 # integer index in cursor.description
29
+
30
+
31
+ class BaseRow:
32
+ __slots__ = ("_parent", "_data", "_key_to_index")
33
+
34
+ _parent: ResultMetaData
35
+ _key_to_index: Mapping[_KeyType, int]
36
+ _data: _RawRowType
37
+
38
+ def __init__(
39
+ self,
40
+ parent: ResultMetaData,
41
+ processors: Optional[_ProcessorsType],
42
+ key_to_index: Mapping[_KeyType, int],
43
+ data: _RawRowType,
44
+ ):
45
+ """Row objects are constructed by CursorResult objects."""
46
+ object.__setattr__(self, "_parent", parent)
47
+
48
+ object.__setattr__(self, "_key_to_index", key_to_index)
49
+
50
+ if processors:
51
+ object.__setattr__(
52
+ self,
53
+ "_data",
54
+ tuple(
55
+ [
56
+ proc(value) if proc else value
57
+ for proc, value in zip(processors, data)
58
+ ]
59
+ ),
60
+ )
61
+ else:
62
+ object.__setattr__(self, "_data", tuple(data))
63
+
64
+ def __reduce__(self) -> Tuple[Callable[..., BaseRow], Tuple[Any, ...]]:
65
+ return (
66
+ rowproxy_reconstructor,
67
+ (self.__class__, self.__getstate__()),
68
+ )
69
+
70
+ def __getstate__(self) -> Dict[str, Any]:
71
+ return {"_parent": self._parent, "_data": self._data}
72
+
73
+ def __setstate__(self, state: Dict[str, Any]) -> None:
74
+ parent = state["_parent"]
75
+ object.__setattr__(self, "_parent", parent)
76
+ object.__setattr__(self, "_data", state["_data"])
77
+ object.__setattr__(self, "_key_to_index", parent._key_to_index)
78
+
79
+ def _values_impl(self) -> List[Any]:
80
+ return list(self)
81
+
82
+ def __iter__(self) -> Iterator[Any]:
83
+ return iter(self._data)
84
+
85
+ def __len__(self) -> int:
86
+ return len(self._data)
87
+
88
+ def __hash__(self) -> int:
89
+ return hash(self._data)
90
+
91
+ def __getitem__(self, key: Any) -> Any:
92
+ return self._data[key]
93
+
94
+ def _get_by_key_impl_mapping(self, key: str) -> Any:
95
+ try:
96
+ return self._data[self._key_to_index[key]]
97
+ except KeyError:
98
+ pass
99
+ self._parent._key_not_found(key, False)
100
+
101
+ def __getattr__(self, name: str) -> Any:
102
+ try:
103
+ return self._data[self._key_to_index[name]]
104
+ except KeyError:
105
+ pass
106
+ self._parent._key_not_found(name, True)
107
+
108
+ def _to_tuple_instance(self) -> Tuple[Any, ...]:
109
+ return self._data
110
+
111
+
112
+ # This reconstructor is necessary so that pickles with the Cy extension or
113
+ # without use the same Binary format.
114
+ def rowproxy_reconstructor(
115
+ cls: Type[BaseRow], state: Dict[str, Any]
116
+ ) -> BaseRow:
117
+ obj = cls.__new__(cls)
118
+ obj.__setstate__(state)
119
+ return obj
120
+
121
+
122
+ def tuplegetter(*indexes: int) -> _TupleGetterType:
123
+ if len(indexes) != 1:
124
+ for i in range(1, len(indexes)):
125
+ if indexes[i - 1] != indexes[i] - 1:
126
+ return operator.itemgetter(*indexes)
127
+ # slice form is faster but returns a list if input is list
128
+ return operator.itemgetter(slice(indexes[0], indexes[-1] + 1))
@@ -0,0 +1,74 @@
1
+ # engine/_py_util.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
+ from __future__ import annotations
8
+
9
+ import typing
10
+ from typing import Any
11
+ from typing import Mapping
12
+ from typing import Optional
13
+ from typing import Tuple
14
+
15
+ from .. import exc
16
+
17
+ if typing.TYPE_CHECKING:
18
+ from .interfaces import _CoreAnyExecuteParams
19
+ from .interfaces import _CoreMultiExecuteParams
20
+ from .interfaces import _DBAPIAnyExecuteParams
21
+ from .interfaces import _DBAPIMultiExecuteParams
22
+
23
+
24
+ _no_tuple: Tuple[Any, ...] = ()
25
+
26
+
27
+ def _distill_params_20(
28
+ params: Optional[_CoreAnyExecuteParams],
29
+ ) -> _CoreMultiExecuteParams:
30
+ if params is None:
31
+ return _no_tuple
32
+ # Assume list is more likely than tuple
33
+ elif isinstance(params, list) or isinstance(params, tuple):
34
+ # collections_abc.MutableSequence): # avoid abc.__instancecheck__
35
+ if params and not isinstance(params[0], Mapping):
36
+ raise exc.ArgumentError(
37
+ "List argument must consist only of dictionaries"
38
+ )
39
+
40
+ return params
41
+ elif isinstance(params, dict) or isinstance(
42
+ # only do immutabledict or abc.__instancecheck__ for Mapping after
43
+ # we've checked for plain dictionaries and would otherwise raise
44
+ params,
45
+ Mapping,
46
+ ):
47
+ return [params]
48
+ else:
49
+ raise exc.ArgumentError("mapping or list expected for parameters")
50
+
51
+
52
+ def _distill_raw_params(
53
+ params: Optional[_DBAPIAnyExecuteParams],
54
+ ) -> _DBAPIMultiExecuteParams:
55
+ if params is None:
56
+ return _no_tuple
57
+ elif isinstance(params, list):
58
+ # collections_abc.MutableSequence): # avoid abc.__instancecheck__
59
+ if params and not isinstance(params[0], (tuple, Mapping)):
60
+ raise exc.ArgumentError(
61
+ "List argument must consist only of tuples or dictionaries"
62
+ )
63
+
64
+ return params
65
+ elif isinstance(params, (tuple, dict)) or isinstance(
66
+ # only do abc.__instancecheck__ for Mapping after we've checked
67
+ # for plain dictionaries and would otherwise raise
68
+ params,
69
+ Mapping,
70
+ ):
71
+ # cast("Union[List[Mapping[str, Any]], Tuple[Any, ...]]", [params])
72
+ return [params] # type: ignore
73
+ else:
74
+ raise exc.ArgumentError("mapping or sequence expected for parameters")