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,133 @@
1
+ # cyextension/immutabledict.pyx
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
+ from cpython.dict cimport PyDict_New, PyDict_Update, PyDict_Size
8
+
9
+
10
+ def _readonly_fn(obj):
11
+ raise TypeError(
12
+ "%s object is immutable and/or readonly" % obj.__class__.__name__)
13
+
14
+
15
+ def _immutable_fn(obj):
16
+ raise TypeError(
17
+ "%s object is immutable" % obj.__class__.__name__)
18
+
19
+
20
+ class ReadOnlyContainer:
21
+
22
+ __slots__ = ()
23
+
24
+ def _readonly(self, *a,**kw):
25
+ _readonly_fn(self)
26
+
27
+ __delitem__ = __setitem__ = __setattr__ = _readonly
28
+
29
+
30
+ class ImmutableDictBase(dict):
31
+ def _immutable(self, *a,**kw):
32
+ _immutable_fn(self)
33
+
34
+ @classmethod
35
+ def __class_getitem__(cls, key):
36
+ return cls
37
+
38
+ __delitem__ = __setitem__ = __setattr__ = _immutable
39
+ clear = pop = popitem = setdefault = update = _immutable
40
+
41
+
42
+ cdef class immutabledict(dict):
43
+ def __repr__(self):
44
+ return f"immutabledict({dict.__repr__(self)})"
45
+
46
+ @classmethod
47
+ def __class_getitem__(cls, key):
48
+ return cls
49
+
50
+ def union(self, *args, **kw):
51
+ cdef dict to_merge = None
52
+ cdef immutabledict result
53
+ cdef Py_ssize_t args_len = len(args)
54
+ if args_len > 1:
55
+ raise TypeError(
56
+ f'union expected at most 1 argument, got {args_len}'
57
+ )
58
+ if args_len == 1:
59
+ attribute = args[0]
60
+ if isinstance(attribute, dict):
61
+ to_merge = <dict> attribute
62
+ if to_merge is None:
63
+ to_merge = dict(*args, **kw)
64
+
65
+ if PyDict_Size(to_merge) == 0:
66
+ return self
67
+
68
+ # new + update is faster than immutabledict(self)
69
+ result = immutabledict()
70
+ PyDict_Update(result, self)
71
+ PyDict_Update(result, to_merge)
72
+ return result
73
+
74
+ def merge_with(self, *other):
75
+ cdef immutabledict result = None
76
+ cdef object d
77
+ cdef bint update = False
78
+ if not other:
79
+ return self
80
+ for d in other:
81
+ if d:
82
+ if update == False:
83
+ update = True
84
+ # new + update is faster than immutabledict(self)
85
+ result = immutabledict()
86
+ PyDict_Update(result, self)
87
+ PyDict_Update(
88
+ result, <dict>(d if isinstance(d, dict) else dict(d))
89
+ )
90
+
91
+ return self if update == False else result
92
+
93
+ def copy(self):
94
+ return self
95
+
96
+ def __reduce__(self):
97
+ return immutabledict, (dict(self), )
98
+
99
+ def __delitem__(self, k):
100
+ _immutable_fn(self)
101
+
102
+ def __setitem__(self, k, v):
103
+ _immutable_fn(self)
104
+
105
+ def __setattr__(self, k, v):
106
+ _immutable_fn(self)
107
+
108
+ def clear(self, *args, **kw):
109
+ _immutable_fn(self)
110
+
111
+ def pop(self, *args, **kw):
112
+ _immutable_fn(self)
113
+
114
+ def popitem(self, *args, **kw):
115
+ _immutable_fn(self)
116
+
117
+ def setdefault(self, *args, **kw):
118
+ _immutable_fn(self)
119
+
120
+ def update(self, *args, **kw):
121
+ _immutable_fn(self)
122
+
123
+ # PEP 584
124
+ def __ior__(self, other):
125
+ _immutable_fn(self)
126
+
127
+ def __or__(self, other):
128
+ return immutabledict(dict.__or__(self, other))
129
+
130
+ def __ror__(self, other):
131
+ # NOTE: this is used only in cython 3.x;
132
+ # version 0.x will call __or__ with args inversed
133
+ return immutabledict(dict.__ror__(self, other))
@@ -0,0 +1,68 @@
1
+ # cyextension/processors.pyx
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
+ import datetime
8
+ from datetime import datetime as datetime_cls
9
+ from datetime import time as time_cls
10
+ from datetime import date as date_cls
11
+ import re
12
+
13
+ from cpython.object cimport PyObject_Str
14
+ from cpython.unicode cimport PyUnicode_AsASCIIString, PyUnicode_Check, PyUnicode_Decode
15
+ from libc.stdio cimport sscanf
16
+
17
+
18
+ def int_to_boolean(value):
19
+ if value is None:
20
+ return None
21
+ return True if value else False
22
+
23
+ def to_str(value):
24
+ return PyObject_Str(value) if value is not None else None
25
+
26
+ def to_float(value):
27
+ return float(value) if value is not None else None
28
+
29
+ cdef inline bytes to_bytes(object value, str type_name):
30
+ try:
31
+ return PyUnicode_AsASCIIString(value)
32
+ except Exception as e:
33
+ raise ValueError(
34
+ f"Couldn't parse {type_name} string '{value!r}' "
35
+ "- value is not a string."
36
+ ) from e
37
+
38
+ def str_to_datetime(value):
39
+ if value is not None:
40
+ value = datetime_cls.fromisoformat(value)
41
+ return value
42
+
43
+ def str_to_time(value):
44
+ if value is not None:
45
+ value = time_cls.fromisoformat(value)
46
+ return value
47
+
48
+
49
+ def str_to_date(value):
50
+ if value is not None:
51
+ value = date_cls.fromisoformat(value)
52
+ return value
53
+
54
+
55
+
56
+ cdef class DecimalResultProcessor:
57
+ cdef object type_
58
+ cdef str format_
59
+
60
+ def __cinit__(self, type_, format_):
61
+ self.type_ = type_
62
+ self.format_ = format_
63
+
64
+ def process(self, object value):
65
+ if value is None:
66
+ return None
67
+ else:
68
+ return self.type_(self.format_ % value)
@@ -0,0 +1,102 @@
1
+ # cyextension/resultproxy.pyx
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
+ import operator
8
+
9
+ cdef class BaseRow:
10
+ cdef readonly object _parent
11
+ cdef readonly dict _key_to_index
12
+ cdef readonly tuple _data
13
+
14
+ def __init__(self, object parent, object processors, dict key_to_index, object data):
15
+ """Row objects are constructed by CursorResult objects."""
16
+
17
+ self._parent = parent
18
+
19
+ self._key_to_index = key_to_index
20
+
21
+ if processors:
22
+ self._data = _apply_processors(processors, data)
23
+ else:
24
+ self._data = tuple(data)
25
+
26
+ def __reduce__(self):
27
+ return (
28
+ rowproxy_reconstructor,
29
+ (self.__class__, self.__getstate__()),
30
+ )
31
+
32
+ def __getstate__(self):
33
+ return {"_parent": self._parent, "_data": self._data}
34
+
35
+ def __setstate__(self, dict state):
36
+ parent = state["_parent"]
37
+ self._parent = parent
38
+ self._data = state["_data"]
39
+ self._key_to_index = parent._key_to_index
40
+
41
+ def _values_impl(self):
42
+ return list(self)
43
+
44
+ def __iter__(self):
45
+ return iter(self._data)
46
+
47
+ def __len__(self):
48
+ return len(self._data)
49
+
50
+ def __hash__(self):
51
+ return hash(self._data)
52
+
53
+ def __getitem__(self, index):
54
+ return self._data[index]
55
+
56
+ def _get_by_key_impl_mapping(self, key):
57
+ return self._get_by_key_impl(key, 0)
58
+
59
+ cdef _get_by_key_impl(self, object key, int attr_err):
60
+ index = self._key_to_index.get(key)
61
+ if index is not None:
62
+ return self._data[<int>index]
63
+ self._parent._key_not_found(key, attr_err != 0)
64
+
65
+ def __getattr__(self, name):
66
+ return self._get_by_key_impl(name, 1)
67
+
68
+ def _to_tuple_instance(self):
69
+ return self._data
70
+
71
+
72
+ cdef tuple _apply_processors(proc, data):
73
+ res = []
74
+ for i in range(len(proc)):
75
+ p = proc[i]
76
+ if p is None:
77
+ res.append(data[i])
78
+ else:
79
+ res.append(p(data[i]))
80
+ return tuple(res)
81
+
82
+
83
+ def rowproxy_reconstructor(cls, state):
84
+ obj = cls.__new__(cls)
85
+ obj.__setstate__(state)
86
+ return obj
87
+
88
+
89
+ cdef int is_contiguous(tuple indexes):
90
+ cdef int i
91
+ for i in range(1, len(indexes)):
92
+ if indexes[i-1] != indexes[i] -1:
93
+ return 0
94
+ return 1
95
+
96
+
97
+ def tuplegetter(*indexes):
98
+ if len(indexes) == 1 or is_contiguous(indexes) != 0:
99
+ # slice form is faster but returns a list if input is list
100
+ return operator.itemgetter(slice(indexes[0], indexes[-1] + 1))
101
+ else:
102
+ return operator.itemgetter(*indexes)
@@ -0,0 +1,91 @@
1
+ # cyextension/util.pyx
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
+ from collections.abc import Mapping
8
+
9
+ from sqlalchemy import exc
10
+
11
+ cdef tuple _Empty_Tuple = ()
12
+
13
+ cdef inline bint _mapping_or_tuple(object value):
14
+ return isinstance(value, dict) or isinstance(value, tuple) or isinstance(value, Mapping)
15
+
16
+ cdef inline bint _check_item(object params) except 0:
17
+ cdef object item
18
+ cdef bint ret = 1
19
+ if params:
20
+ item = params[0]
21
+ if not _mapping_or_tuple(item):
22
+ ret = 0
23
+ raise exc.ArgumentError(
24
+ "List argument must consist only of tuples or dictionaries"
25
+ )
26
+ return ret
27
+
28
+ def _distill_params_20(object params):
29
+ if params is None:
30
+ return _Empty_Tuple
31
+ elif isinstance(params, list) or isinstance(params, tuple):
32
+ _check_item(params)
33
+ return params
34
+ elif isinstance(params, dict) or isinstance(params, Mapping):
35
+ return [params]
36
+ else:
37
+ raise exc.ArgumentError("mapping or list expected for parameters")
38
+
39
+
40
+ def _distill_raw_params(object params):
41
+ if params is None:
42
+ return _Empty_Tuple
43
+ elif isinstance(params, list):
44
+ _check_item(params)
45
+ return params
46
+ elif _mapping_or_tuple(params):
47
+ return [params]
48
+ else:
49
+ raise exc.ArgumentError("mapping or sequence expected for parameters")
50
+
51
+ cdef class prefix_anon_map(dict):
52
+ def __missing__(self, str key):
53
+ cdef str derived
54
+ cdef int anonymous_counter
55
+ cdef dict self_dict = self
56
+
57
+ derived = key.split(" ", 1)[1]
58
+
59
+ anonymous_counter = self_dict.get(derived, 1)
60
+ self_dict[derived] = anonymous_counter + 1
61
+ value = f"{derived}_{anonymous_counter}"
62
+ self_dict[key] = value
63
+ return value
64
+
65
+
66
+ cdef class cache_anon_map(dict):
67
+ cdef int _index
68
+
69
+ def __init__(self):
70
+ self._index = 0
71
+
72
+ def get_anon(self, obj):
73
+ cdef long long idself
74
+ cdef str id_
75
+ cdef dict self_dict = self
76
+
77
+ idself = id(obj)
78
+ if idself in self_dict:
79
+ return self_dict[idself], True
80
+ else:
81
+ id_ = self.__missing__(idself)
82
+ return id_, False
83
+
84
+ def __missing__(self, key):
85
+ cdef str val
86
+ cdef dict self_dict = self
87
+
88
+ self_dict[key] = val = str(self._index)
89
+ self._index += 1
90
+ return val
91
+
@@ -0,0 +1,61 @@
1
+ # dialects/__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
+
8
+ from __future__ import annotations
9
+
10
+ from typing import Callable
11
+ from typing import Optional
12
+ from typing import Type
13
+ from typing import TYPE_CHECKING
14
+
15
+ from .. import util
16
+
17
+ if TYPE_CHECKING:
18
+ from ..engine.interfaces import Dialect
19
+
20
+ __all__ = ("mssql", "mysql", "oracle", "postgresql", "sqlite")
21
+
22
+
23
+ def _auto_fn(name: str) -> Optional[Callable[[], Type[Dialect]]]:
24
+ """default dialect importer.
25
+
26
+ plugs into the :class:`.PluginLoader`
27
+ as a first-hit system.
28
+
29
+ """
30
+ if "." in name:
31
+ dialect, driver = name.split(".")
32
+ else:
33
+ dialect = name
34
+ driver = "base"
35
+
36
+ try:
37
+ if dialect == "mariadb":
38
+ # it's "OK" for us to hardcode here since _auto_fn is already
39
+ # hardcoded. if mysql / mariadb etc were third party dialects
40
+ # they would just publish all the entrypoints, which would actually
41
+ # look much nicer.
42
+ module = __import__(
43
+ "sqlalchemy.dialects.mysql.mariadb"
44
+ ).dialects.mysql.mariadb
45
+ return module.loader(driver) # type: ignore
46
+ else:
47
+ module = __import__("sqlalchemy.dialects.%s" % (dialect,)).dialects
48
+ module = getattr(module, dialect)
49
+ except ImportError:
50
+ return None
51
+
52
+ if hasattr(module, driver):
53
+ module = getattr(module, driver)
54
+ return lambda: module.dialect
55
+ else:
56
+ return None
57
+
58
+
59
+ registry = util.PluginLoader("sqlalchemy.dialects", auto_fn=_auto_fn)
60
+
61
+ plugins = util.PluginLoader("sqlalchemy.plugins")
@@ -0,0 +1,25 @@
1
+ # dialects/_typing.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
+ from __future__ import annotations
8
+
9
+ from typing import Any
10
+ from typing import Iterable
11
+ from typing import Mapping
12
+ from typing import Optional
13
+ from typing import Union
14
+
15
+ from ..sql._typing import _DDLColumnArgument
16
+ from ..sql.elements import DQLDMLClauseElement
17
+ from ..sql.schema import ColumnCollectionConstraint
18
+ from ..sql.schema import Index
19
+
20
+
21
+ _OnConflictConstraintT = Union[str, ColumnCollectionConstraint, Index, None]
22
+ _OnConflictIndexElementsT = Optional[Iterable[_DDLColumnArgument]]
23
+ _OnConflictIndexWhereT = Optional[DQLDMLClauseElement]
24
+ _OnConflictSetT = Optional[Mapping[Any, Any]]
25
+ _OnConflictWhereT = Union[DQLDMLClauseElement, str, None]
@@ -0,0 +1,88 @@
1
+ # dialects/mssql/__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
+ from . import aioodbc # noqa
10
+ from . import base # noqa
11
+ from . import pymssql # noqa
12
+ from . import pyodbc # noqa
13
+ from .base import BIGINT
14
+ from .base import BINARY
15
+ from .base import BIT
16
+ from .base import CHAR
17
+ from .base import DATE
18
+ from .base import DATETIME
19
+ from .base import DATETIME2
20
+ from .base import DATETIMEOFFSET
21
+ from .base import DECIMAL
22
+ from .base import DOUBLE_PRECISION
23
+ from .base import FLOAT
24
+ from .base import IMAGE
25
+ from .base import INTEGER
26
+ from .base import JSON
27
+ from .base import MONEY
28
+ from .base import NCHAR
29
+ from .base import NTEXT
30
+ from .base import NUMERIC
31
+ from .base import NVARCHAR
32
+ from .base import REAL
33
+ from .base import ROWVERSION
34
+ from .base import SMALLDATETIME
35
+ from .base import SMALLINT
36
+ from .base import SMALLMONEY
37
+ from .base import SQL_VARIANT
38
+ from .base import TEXT
39
+ from .base import TIME
40
+ from .base import TIMESTAMP
41
+ from .base import TINYINT
42
+ from .base import UNIQUEIDENTIFIER
43
+ from .base import VARBINARY
44
+ from .base import VARCHAR
45
+ from .base import XML
46
+ from ...sql import try_cast
47
+
48
+
49
+ base.dialect = dialect = pyodbc.dialect
50
+
51
+
52
+ __all__ = (
53
+ "JSON",
54
+ "INTEGER",
55
+ "BIGINT",
56
+ "SMALLINT",
57
+ "TINYINT",
58
+ "VARCHAR",
59
+ "NVARCHAR",
60
+ "CHAR",
61
+ "NCHAR",
62
+ "TEXT",
63
+ "NTEXT",
64
+ "DECIMAL",
65
+ "NUMERIC",
66
+ "FLOAT",
67
+ "DATETIME",
68
+ "DATETIME2",
69
+ "DATETIMEOFFSET",
70
+ "DATE",
71
+ "DOUBLE_PRECISION",
72
+ "TIME",
73
+ "SMALLDATETIME",
74
+ "BINARY",
75
+ "VARBINARY",
76
+ "BIT",
77
+ "REAL",
78
+ "IMAGE",
79
+ "TIMESTAMP",
80
+ "ROWVERSION",
81
+ "MONEY",
82
+ "SMALLMONEY",
83
+ "UNIQUEIDENTIFIER",
84
+ "SQL_VARIANT",
85
+ "XML",
86
+ "dialect",
87
+ "try_cast",
88
+ )
@@ -0,0 +1,64 @@
1
+ # dialects/mssql/aioodbc.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
+ r"""
9
+ .. dialect:: mssql+aioodbc
10
+ :name: aioodbc
11
+ :dbapi: aioodbc
12
+ :connectstring: mssql+aioodbc://<username>:<password>@<dsnname>
13
+ :url: https://pypi.org/project/aioodbc/
14
+
15
+
16
+ Support for the SQL Server database in asyncio style, using the aioodbc
17
+ driver which itself is a thread-wrapper around pyodbc.
18
+
19
+ .. versionadded:: 2.0.23 Added the mssql+aioodbc dialect which builds
20
+ on top of the pyodbc and general aio* dialect architecture.
21
+
22
+ Using a special asyncio mediation layer, the aioodbc dialect is usable
23
+ as the backend for the :ref:`SQLAlchemy asyncio <asyncio_toplevel>`
24
+ extension package.
25
+
26
+ Most behaviors and caveats for this driver are the same as that of the
27
+ pyodbc dialect used on SQL Server; see :ref:`mssql_pyodbc` for general
28
+ background.
29
+
30
+ This dialect should normally be used only with the
31
+ :func:`_asyncio.create_async_engine` engine creation function; connection
32
+ styles are otherwise equivalent to those documented in the pyodbc section::
33
+
34
+ from sqlalchemy.ext.asyncio import create_async_engine
35
+ engine = create_async_engine(
36
+ "mssql+aioodbc://scott:tiger@mssql2017:1433/test?"
37
+ "driver=ODBC+Driver+18+for+SQL+Server&TrustServerCertificate=yes"
38
+ )
39
+
40
+
41
+
42
+ """
43
+
44
+ from __future__ import annotations
45
+
46
+ from .pyodbc import MSDialect_pyodbc
47
+ from .pyodbc import MSExecutionContext_pyodbc
48
+ from ...connectors.aioodbc import aiodbcConnector
49
+
50
+
51
+ class MSExecutionContext_aioodbc(MSExecutionContext_pyodbc):
52
+ def create_server_side_cursor(self):
53
+ return self._dbapi_connection.cursor(server_side=True)
54
+
55
+
56
+ class MSDialectAsync_aioodbc(aiodbcConnector, MSDialect_pyodbc):
57
+ driver = "aioodbc"
58
+
59
+ supports_statement_cache = True
60
+
61
+ execution_ctx_cls = MSExecutionContext_aioodbc
62
+
63
+
64
+ dialect = MSDialectAsync_aioodbc