SQLAlchemy 2.1.0b2__cp313-cp313t-win_arm64.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 (270) hide show
  1. sqlalchemy/__init__.py +298 -0
  2. sqlalchemy/connectors/__init__.py +18 -0
  3. sqlalchemy/connectors/aioodbc.py +171 -0
  4. sqlalchemy/connectors/asyncio.py +476 -0
  5. sqlalchemy/connectors/pyodbc.py +250 -0
  6. sqlalchemy/dialects/__init__.py +62 -0
  7. sqlalchemy/dialects/_typing.py +30 -0
  8. sqlalchemy/dialects/mssql/__init__.py +89 -0
  9. sqlalchemy/dialects/mssql/aioodbc.py +63 -0
  10. sqlalchemy/dialects/mssql/base.py +4166 -0
  11. sqlalchemy/dialects/mssql/information_schema.py +285 -0
  12. sqlalchemy/dialects/mssql/json.py +140 -0
  13. sqlalchemy/dialects/mssql/mssqlpython.py +220 -0
  14. sqlalchemy/dialects/mssql/provision.py +196 -0
  15. sqlalchemy/dialects/mssql/pymssql.py +126 -0
  16. sqlalchemy/dialects/mssql/pyodbc.py +698 -0
  17. sqlalchemy/dialects/mysql/__init__.py +106 -0
  18. sqlalchemy/dialects/mysql/_mariadb_shim.py +312 -0
  19. sqlalchemy/dialects/mysql/aiomysql.py +226 -0
  20. sqlalchemy/dialects/mysql/asyncmy.py +214 -0
  21. sqlalchemy/dialects/mysql/base.py +3877 -0
  22. sqlalchemy/dialects/mysql/cymysql.py +106 -0
  23. sqlalchemy/dialects/mysql/dml.py +279 -0
  24. sqlalchemy/dialects/mysql/enumerated.py +277 -0
  25. sqlalchemy/dialects/mysql/expression.py +146 -0
  26. sqlalchemy/dialects/mysql/json.py +92 -0
  27. sqlalchemy/dialects/mysql/mariadb.py +67 -0
  28. sqlalchemy/dialects/mysql/mariadbconnector.py +330 -0
  29. sqlalchemy/dialects/mysql/mysqlconnector.py +296 -0
  30. sqlalchemy/dialects/mysql/mysqldb.py +312 -0
  31. sqlalchemy/dialects/mysql/provision.py +153 -0
  32. sqlalchemy/dialects/mysql/pymysql.py +157 -0
  33. sqlalchemy/dialects/mysql/pyodbc.py +156 -0
  34. sqlalchemy/dialects/mysql/reflection.py +724 -0
  35. sqlalchemy/dialects/mysql/reserved_words.py +570 -0
  36. sqlalchemy/dialects/mysql/types.py +845 -0
  37. sqlalchemy/dialects/oracle/__init__.py +85 -0
  38. sqlalchemy/dialects/oracle/base.py +3977 -0
  39. sqlalchemy/dialects/oracle/cx_oracle.py +1601 -0
  40. sqlalchemy/dialects/oracle/dictionary.py +507 -0
  41. sqlalchemy/dialects/oracle/json.py +158 -0
  42. sqlalchemy/dialects/oracle/oracledb.py +909 -0
  43. sqlalchemy/dialects/oracle/provision.py +288 -0
  44. sqlalchemy/dialects/oracle/types.py +367 -0
  45. sqlalchemy/dialects/oracle/vector.py +368 -0
  46. sqlalchemy/dialects/postgresql/__init__.py +171 -0
  47. sqlalchemy/dialects/postgresql/_psycopg_common.py +229 -0
  48. sqlalchemy/dialects/postgresql/array.py +534 -0
  49. sqlalchemy/dialects/postgresql/asyncpg.py +1323 -0
  50. sqlalchemy/dialects/postgresql/base.py +5789 -0
  51. sqlalchemy/dialects/postgresql/bitstring.py +327 -0
  52. sqlalchemy/dialects/postgresql/dml.py +360 -0
  53. sqlalchemy/dialects/postgresql/ext.py +593 -0
  54. sqlalchemy/dialects/postgresql/hstore.py +423 -0
  55. sqlalchemy/dialects/postgresql/json.py +408 -0
  56. sqlalchemy/dialects/postgresql/named_types.py +521 -0
  57. sqlalchemy/dialects/postgresql/operators.py +130 -0
  58. sqlalchemy/dialects/postgresql/pg8000.py +670 -0
  59. sqlalchemy/dialects/postgresql/pg_catalog.py +344 -0
  60. sqlalchemy/dialects/postgresql/provision.py +184 -0
  61. sqlalchemy/dialects/postgresql/psycopg.py +799 -0
  62. sqlalchemy/dialects/postgresql/psycopg2.py +860 -0
  63. sqlalchemy/dialects/postgresql/psycopg2cffi.py +61 -0
  64. sqlalchemy/dialects/postgresql/ranges.py +1002 -0
  65. sqlalchemy/dialects/postgresql/types.py +388 -0
  66. sqlalchemy/dialects/sqlite/__init__.py +57 -0
  67. sqlalchemy/dialects/sqlite/aiosqlite.py +321 -0
  68. sqlalchemy/dialects/sqlite/base.py +3063 -0
  69. sqlalchemy/dialects/sqlite/dml.py +279 -0
  70. sqlalchemy/dialects/sqlite/json.py +100 -0
  71. sqlalchemy/dialects/sqlite/provision.py +229 -0
  72. sqlalchemy/dialects/sqlite/pysqlcipher.py +161 -0
  73. sqlalchemy/dialects/sqlite/pysqlite.py +754 -0
  74. sqlalchemy/dialects/type_migration_guidelines.txt +145 -0
  75. sqlalchemy/engine/__init__.py +62 -0
  76. sqlalchemy/engine/_processors_cy.cp313t-win_arm64.pyd +0 -0
  77. sqlalchemy/engine/_processors_cy.py +92 -0
  78. sqlalchemy/engine/_result_cy.cp313t-win_arm64.pyd +0 -0
  79. sqlalchemy/engine/_result_cy.py +633 -0
  80. sqlalchemy/engine/_row_cy.cp313t-win_arm64.pyd +0 -0
  81. sqlalchemy/engine/_row_cy.py +232 -0
  82. sqlalchemy/engine/_util_cy.cp313t-win_arm64.pyd +0 -0
  83. sqlalchemy/engine/_util_cy.py +136 -0
  84. sqlalchemy/engine/base.py +3354 -0
  85. sqlalchemy/engine/characteristics.py +155 -0
  86. sqlalchemy/engine/create.py +877 -0
  87. sqlalchemy/engine/cursor.py +2421 -0
  88. sqlalchemy/engine/default.py +2402 -0
  89. sqlalchemy/engine/events.py +965 -0
  90. sqlalchemy/engine/interfaces.py +3495 -0
  91. sqlalchemy/engine/mock.py +134 -0
  92. sqlalchemy/engine/processors.py +82 -0
  93. sqlalchemy/engine/reflection.py +2100 -0
  94. sqlalchemy/engine/result.py +1966 -0
  95. sqlalchemy/engine/row.py +397 -0
  96. sqlalchemy/engine/strategies.py +16 -0
  97. sqlalchemy/engine/url.py +922 -0
  98. sqlalchemy/engine/util.py +156 -0
  99. sqlalchemy/event/__init__.py +26 -0
  100. sqlalchemy/event/api.py +220 -0
  101. sqlalchemy/event/attr.py +674 -0
  102. sqlalchemy/event/base.py +472 -0
  103. sqlalchemy/event/legacy.py +258 -0
  104. sqlalchemy/event/registry.py +390 -0
  105. sqlalchemy/events.py +17 -0
  106. sqlalchemy/exc.py +922 -0
  107. sqlalchemy/ext/__init__.py +11 -0
  108. sqlalchemy/ext/associationproxy.py +2072 -0
  109. sqlalchemy/ext/asyncio/__init__.py +29 -0
  110. sqlalchemy/ext/asyncio/base.py +281 -0
  111. sqlalchemy/ext/asyncio/engine.py +1487 -0
  112. sqlalchemy/ext/asyncio/exc.py +21 -0
  113. sqlalchemy/ext/asyncio/result.py +994 -0
  114. sqlalchemy/ext/asyncio/scoping.py +1679 -0
  115. sqlalchemy/ext/asyncio/session.py +2007 -0
  116. sqlalchemy/ext/automap.py +1701 -0
  117. sqlalchemy/ext/baked.py +559 -0
  118. sqlalchemy/ext/compiler.py +600 -0
  119. sqlalchemy/ext/declarative/__init__.py +65 -0
  120. sqlalchemy/ext/declarative/extensions.py +560 -0
  121. sqlalchemy/ext/horizontal_shard.py +481 -0
  122. sqlalchemy/ext/hybrid.py +1877 -0
  123. sqlalchemy/ext/indexable.py +364 -0
  124. sqlalchemy/ext/instrumentation.py +450 -0
  125. sqlalchemy/ext/mutable.py +1081 -0
  126. sqlalchemy/ext/orderinglist.py +439 -0
  127. sqlalchemy/ext/serializer.py +185 -0
  128. sqlalchemy/future/__init__.py +16 -0
  129. sqlalchemy/future/engine.py +15 -0
  130. sqlalchemy/inspection.py +174 -0
  131. sqlalchemy/log.py +283 -0
  132. sqlalchemy/orm/__init__.py +176 -0
  133. sqlalchemy/orm/_orm_constructors.py +2694 -0
  134. sqlalchemy/orm/_typing.py +179 -0
  135. sqlalchemy/orm/attributes.py +2868 -0
  136. sqlalchemy/orm/base.py +976 -0
  137. sqlalchemy/orm/bulk_persistence.py +2152 -0
  138. sqlalchemy/orm/clsregistry.py +582 -0
  139. sqlalchemy/orm/collections.py +1568 -0
  140. sqlalchemy/orm/context.py +3471 -0
  141. sqlalchemy/orm/decl_api.py +2280 -0
  142. sqlalchemy/orm/decl_base.py +2309 -0
  143. sqlalchemy/orm/dependency.py +1306 -0
  144. sqlalchemy/orm/descriptor_props.py +1183 -0
  145. sqlalchemy/orm/dynamic.py +307 -0
  146. sqlalchemy/orm/evaluator.py +379 -0
  147. sqlalchemy/orm/events.py +3386 -0
  148. sqlalchemy/orm/exc.py +237 -0
  149. sqlalchemy/orm/identity.py +302 -0
  150. sqlalchemy/orm/instrumentation.py +746 -0
  151. sqlalchemy/orm/interfaces.py +1589 -0
  152. sqlalchemy/orm/loading.py +1684 -0
  153. sqlalchemy/orm/mapped_collection.py +557 -0
  154. sqlalchemy/orm/mapper.py +4411 -0
  155. sqlalchemy/orm/path_registry.py +829 -0
  156. sqlalchemy/orm/persistence.py +1789 -0
  157. sqlalchemy/orm/properties.py +973 -0
  158. sqlalchemy/orm/query.py +3528 -0
  159. sqlalchemy/orm/relationships.py +3570 -0
  160. sqlalchemy/orm/scoping.py +2232 -0
  161. sqlalchemy/orm/session.py +5403 -0
  162. sqlalchemy/orm/state.py +1175 -0
  163. sqlalchemy/orm/state_changes.py +196 -0
  164. sqlalchemy/orm/strategies.py +3492 -0
  165. sqlalchemy/orm/strategy_options.py +2562 -0
  166. sqlalchemy/orm/sync.py +164 -0
  167. sqlalchemy/orm/unitofwork.py +798 -0
  168. sqlalchemy/orm/util.py +2438 -0
  169. sqlalchemy/orm/writeonly.py +694 -0
  170. sqlalchemy/pool/__init__.py +41 -0
  171. sqlalchemy/pool/base.py +1522 -0
  172. sqlalchemy/pool/events.py +375 -0
  173. sqlalchemy/pool/impl.py +582 -0
  174. sqlalchemy/py.typed +0 -0
  175. sqlalchemy/schema.py +74 -0
  176. sqlalchemy/sql/__init__.py +156 -0
  177. sqlalchemy/sql/_annotated_cols.py +397 -0
  178. sqlalchemy/sql/_dml_constructors.py +132 -0
  179. sqlalchemy/sql/_elements_constructors.py +2164 -0
  180. sqlalchemy/sql/_orm_types.py +20 -0
  181. sqlalchemy/sql/_selectable_constructors.py +840 -0
  182. sqlalchemy/sql/_typing.py +487 -0
  183. sqlalchemy/sql/_util_cy.cp313t-win_arm64.pyd +0 -0
  184. sqlalchemy/sql/_util_cy.py +127 -0
  185. sqlalchemy/sql/annotation.py +590 -0
  186. sqlalchemy/sql/base.py +2699 -0
  187. sqlalchemy/sql/cache_key.py +1066 -0
  188. sqlalchemy/sql/coercions.py +1373 -0
  189. sqlalchemy/sql/compiler.py +8327 -0
  190. sqlalchemy/sql/crud.py +1815 -0
  191. sqlalchemy/sql/ddl.py +1928 -0
  192. sqlalchemy/sql/default_comparator.py +654 -0
  193. sqlalchemy/sql/dml.py +1977 -0
  194. sqlalchemy/sql/elements.py +6033 -0
  195. sqlalchemy/sql/events.py +458 -0
  196. sqlalchemy/sql/expression.py +172 -0
  197. sqlalchemy/sql/functions.py +2305 -0
  198. sqlalchemy/sql/lambdas.py +1443 -0
  199. sqlalchemy/sql/naming.py +209 -0
  200. sqlalchemy/sql/operators.py +2897 -0
  201. sqlalchemy/sql/roles.py +332 -0
  202. sqlalchemy/sql/schema.py +6703 -0
  203. sqlalchemy/sql/selectable.py +7553 -0
  204. sqlalchemy/sql/sqltypes.py +4093 -0
  205. sqlalchemy/sql/traversals.py +1042 -0
  206. sqlalchemy/sql/type_api.py +2446 -0
  207. sqlalchemy/sql/util.py +1495 -0
  208. sqlalchemy/sql/visitors.py +1157 -0
  209. sqlalchemy/testing/__init__.py +96 -0
  210. sqlalchemy/testing/assertions.py +1007 -0
  211. sqlalchemy/testing/assertsql.py +519 -0
  212. sqlalchemy/testing/asyncio.py +128 -0
  213. sqlalchemy/testing/config.py +440 -0
  214. sqlalchemy/testing/engines.py +483 -0
  215. sqlalchemy/testing/entities.py +117 -0
  216. sqlalchemy/testing/exclusions.py +476 -0
  217. sqlalchemy/testing/fixtures/__init__.py +30 -0
  218. sqlalchemy/testing/fixtures/base.py +384 -0
  219. sqlalchemy/testing/fixtures/mypy.py +247 -0
  220. sqlalchemy/testing/fixtures/orm.py +227 -0
  221. sqlalchemy/testing/fixtures/sql.py +538 -0
  222. sqlalchemy/testing/pickleable.py +155 -0
  223. sqlalchemy/testing/plugin/__init__.py +6 -0
  224. sqlalchemy/testing/plugin/bootstrap.py +51 -0
  225. sqlalchemy/testing/plugin/plugin_base.py +828 -0
  226. sqlalchemy/testing/plugin/pytestplugin.py +892 -0
  227. sqlalchemy/testing/profiling.py +329 -0
  228. sqlalchemy/testing/provision.py +613 -0
  229. sqlalchemy/testing/requirements.py +1978 -0
  230. sqlalchemy/testing/schema.py +198 -0
  231. sqlalchemy/testing/suite/__init__.py +19 -0
  232. sqlalchemy/testing/suite/test_cte.py +237 -0
  233. sqlalchemy/testing/suite/test_ddl.py +420 -0
  234. sqlalchemy/testing/suite/test_dialect.py +776 -0
  235. sqlalchemy/testing/suite/test_insert.py +630 -0
  236. sqlalchemy/testing/suite/test_reflection.py +3557 -0
  237. sqlalchemy/testing/suite/test_results.py +660 -0
  238. sqlalchemy/testing/suite/test_rowcount.py +258 -0
  239. sqlalchemy/testing/suite/test_select.py +2112 -0
  240. sqlalchemy/testing/suite/test_sequence.py +317 -0
  241. sqlalchemy/testing/suite/test_table_via_select.py +686 -0
  242. sqlalchemy/testing/suite/test_types.py +2271 -0
  243. sqlalchemy/testing/suite/test_unicode_ddl.py +189 -0
  244. sqlalchemy/testing/suite/test_update_delete.py +139 -0
  245. sqlalchemy/testing/util.py +535 -0
  246. sqlalchemy/testing/warnings.py +52 -0
  247. sqlalchemy/types.py +76 -0
  248. sqlalchemy/util/__init__.py +158 -0
  249. sqlalchemy/util/_collections.py +688 -0
  250. sqlalchemy/util/_collections_cy.cp313t-win_arm64.pyd +0 -0
  251. sqlalchemy/util/_collections_cy.pxd +8 -0
  252. sqlalchemy/util/_collections_cy.py +516 -0
  253. sqlalchemy/util/_has_cython.py +46 -0
  254. sqlalchemy/util/_immutabledict_cy.cp313t-win_arm64.pyd +0 -0
  255. sqlalchemy/util/_immutabledict_cy.py +240 -0
  256. sqlalchemy/util/compat.py +299 -0
  257. sqlalchemy/util/concurrency.py +322 -0
  258. sqlalchemy/util/cython.py +79 -0
  259. sqlalchemy/util/deprecations.py +401 -0
  260. sqlalchemy/util/langhelpers.py +2320 -0
  261. sqlalchemy/util/preloaded.py +152 -0
  262. sqlalchemy/util/queue.py +304 -0
  263. sqlalchemy/util/tool_support.py +201 -0
  264. sqlalchemy/util/topological.py +120 -0
  265. sqlalchemy/util/typing.py +711 -0
  266. sqlalchemy-2.1.0b2.dist-info/METADATA +269 -0
  267. sqlalchemy-2.1.0b2.dist-info/RECORD +270 -0
  268. sqlalchemy-2.1.0b2.dist-info/WHEEL +5 -0
  269. sqlalchemy-2.1.0b2.dist-info/licenses/LICENSE +19 -0
  270. sqlalchemy-2.1.0b2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,670 @@
1
+ # dialects/postgresql/pg8000.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
+ # mypy: ignore-errors
8
+
9
+ r"""
10
+ .. dialect:: postgresql+pg8000
11
+ :name: pg8000
12
+ :dbapi: pg8000
13
+ :connectstring: postgresql+pg8000://user:password@host:port/dbname[?key=value&key=value...]
14
+ :url: https://pypi.org/project/pg8000/
15
+
16
+ .. versionchanged:: 1.4 The pg8000 dialect has been updated for version
17
+ 1.16.6 and higher, and is again part of SQLAlchemy's continuous integration
18
+ with full feature support.
19
+
20
+ .. _pg8000_unicode:
21
+
22
+ Unicode
23
+ -------
24
+
25
+ pg8000 will encode / decode string values between it and the server using the
26
+ PostgreSQL ``client_encoding`` parameter; by default this is the value in
27
+ the ``postgresql.conf`` file, which often defaults to ``SQL_ASCII``.
28
+ Typically, this can be changed to ``utf-8``, as a more useful default::
29
+
30
+ # client_encoding = sql_ascii # actually, defaults to database encoding
31
+ client_encoding = utf8
32
+
33
+ The ``client_encoding`` can be overridden for a session by executing the SQL:
34
+
35
+ .. sourcecode:: sql
36
+
37
+ SET CLIENT_ENCODING TO 'utf8';
38
+
39
+ SQLAlchemy will execute this SQL on all new connections based on the value
40
+ passed to :func:`_sa.create_engine` using the ``client_encoding`` parameter::
41
+
42
+ engine = create_engine(
43
+ "postgresql+pg8000://user:pass@host/dbname", client_encoding="utf8"
44
+ )
45
+
46
+ .. _pg8000_ssl:
47
+
48
+ SSL Connections
49
+ ---------------
50
+
51
+ pg8000 accepts a Python ``SSLContext`` object which may be specified using the
52
+ :paramref:`_sa.create_engine.connect_args` dictionary::
53
+
54
+ import ssl
55
+
56
+ ssl_context = ssl.create_default_context()
57
+ engine = sa.create_engine(
58
+ "postgresql+pg8000://scott:tiger@192.168.0.199/test",
59
+ connect_args={"ssl_context": ssl_context},
60
+ )
61
+
62
+ If the server uses an automatically-generated certificate that is self-signed
63
+ or does not match the host name (as seen from the client), it may also be
64
+ necessary to disable hostname checking::
65
+
66
+ import ssl
67
+
68
+ ssl_context = ssl.create_default_context()
69
+ ssl_context.check_hostname = False
70
+ ssl_context.verify_mode = ssl.CERT_NONE
71
+ engine = sa.create_engine(
72
+ "postgresql+pg8000://scott:tiger@192.168.0.199/test",
73
+ connect_args={"ssl_context": ssl_context},
74
+ )
75
+
76
+ .. _pg8000_isolation_level:
77
+
78
+ pg8000 Transaction Isolation Level
79
+ -------------------------------------
80
+
81
+ The pg8000 dialect offers the same isolation level settings as that
82
+ of the :ref:`psycopg2 <psycopg2_isolation_level>` dialect:
83
+
84
+ * ``READ COMMITTED``
85
+ * ``READ UNCOMMITTED``
86
+ * ``REPEATABLE READ``
87
+ * ``SERIALIZABLE``
88
+ * ``AUTOCOMMIT``
89
+
90
+ .. seealso::
91
+
92
+ :ref:`postgresql_isolation_level`
93
+
94
+ :ref:`psycopg2_isolation_level`
95
+
96
+
97
+ """ # noqa
98
+ import decimal
99
+ import re
100
+
101
+ from . import ranges
102
+ from .array import ARRAY as PGARRAY
103
+ from .base import _DECIMAL_TYPES
104
+ from .base import _FLOAT_TYPES
105
+ from .base import _INT_TYPES
106
+ from .base import ENUM
107
+ from .base import INTERVAL
108
+ from .base import PGCompiler
109
+ from .base import PGDialect
110
+ from .base import PGExecutionContext
111
+ from .base import PGIdentifierPreparer
112
+ from .json import JSON
113
+ from .json import JSONB
114
+ from .json import JSONPathType
115
+ from .pg_catalog import _SpaceVector
116
+ from .pg_catalog import OIDVECTOR
117
+ from .types import CITEXT
118
+ from ... import exc
119
+ from ... import util
120
+ from ...engine import processors
121
+ from ...sql import sqltypes
122
+ from ...sql.elements import quoted_name
123
+
124
+
125
+ class _PGString(sqltypes.String):
126
+ render_bind_cast = True
127
+
128
+
129
+ class _PGNumericCommon(sqltypes.NumericCommon):
130
+ render_bind_cast = True
131
+
132
+ def result_processor(self, dialect, coltype):
133
+ if self.asdecimal:
134
+ if coltype in _FLOAT_TYPES:
135
+ return processors.to_decimal_processor_factory(
136
+ decimal.Decimal, self._effective_decimal_return_scale
137
+ )
138
+ elif coltype in _DECIMAL_TYPES or coltype in _INT_TYPES:
139
+ # pg8000 returns Decimal natively for 1700
140
+ return None
141
+ else:
142
+ raise exc.InvalidRequestError(
143
+ "Unknown PG numeric type: %d" % coltype
144
+ )
145
+ else:
146
+ if coltype in _FLOAT_TYPES:
147
+ # pg8000 returns float natively for 701
148
+ return None
149
+ elif coltype in _DECIMAL_TYPES or coltype in _INT_TYPES:
150
+ return processors.to_float
151
+ else:
152
+ raise exc.InvalidRequestError(
153
+ "Unknown PG numeric type: %d" % coltype
154
+ )
155
+
156
+
157
+ class _PGNumeric(_PGNumericCommon, sqltypes.Numeric):
158
+ pass
159
+
160
+
161
+ class _PGFloat(_PGNumericCommon, sqltypes.Float):
162
+ pass
163
+
164
+
165
+ class _PGNumericNoBind(_PGNumeric):
166
+ def bind_processor(self, dialect):
167
+ return None
168
+
169
+
170
+ class _PGJSON(JSON):
171
+ render_bind_cast = True
172
+
173
+
174
+ class _PGJSONB(JSONB):
175
+ render_bind_cast = True
176
+
177
+
178
+ class _PGJSONIndexType(sqltypes.JSON.JSONIndexType):
179
+ def get_dbapi_type(self, dbapi):
180
+ raise NotImplementedError("should not be here")
181
+
182
+
183
+ class _PGJSONIntIndexType(sqltypes.JSON.JSONIntIndexType):
184
+ __visit_name__ = "json_int_index"
185
+
186
+ render_bind_cast = True
187
+
188
+
189
+ class _PGJSONStrIndexType(sqltypes.JSON.JSONStrIndexType):
190
+ __visit_name__ = "json_str_index"
191
+
192
+ render_bind_cast = True
193
+
194
+
195
+ class _PGJSONPathType(JSONPathType):
196
+ pass
197
+
198
+ # DBAPI type 1009
199
+
200
+
201
+ class _PGEnum(ENUM):
202
+ def get_dbapi_type(self, dbapi):
203
+ return dbapi.UNKNOWN
204
+
205
+
206
+ class _PGInterval(INTERVAL):
207
+ render_bind_cast = True
208
+
209
+ def get_dbapi_type(self, dbapi):
210
+ return dbapi.INTERVAL
211
+
212
+ @classmethod
213
+ def adapt_emulated_to_native(cls, interval, **kw):
214
+ return _PGInterval(precision=interval.second_precision)
215
+
216
+
217
+ class _PGTimeStamp(sqltypes.DateTime):
218
+ render_bind_cast = True
219
+
220
+
221
+ class _PGDate(sqltypes.Date):
222
+ render_bind_cast = True
223
+
224
+
225
+ class _PGTime(sqltypes.Time):
226
+ render_bind_cast = True
227
+
228
+
229
+ class _PGInteger(sqltypes.Integer):
230
+ render_bind_cast = True
231
+
232
+
233
+ class _PGSmallInteger(sqltypes.SmallInteger):
234
+ render_bind_cast = True
235
+
236
+
237
+ class _PGNullType(sqltypes.NullType):
238
+ pass
239
+
240
+
241
+ class _PGBigInteger(sqltypes.BigInteger):
242
+ render_bind_cast = True
243
+
244
+
245
+ class _PGBoolean(sqltypes.Boolean):
246
+ render_bind_cast = True
247
+
248
+
249
+ class _PGARRAY(PGARRAY):
250
+ render_bind_cast = True
251
+
252
+
253
+ class _PGOIDVECTOR(_SpaceVector, OIDVECTOR):
254
+ pass
255
+
256
+
257
+ class _Pg8000Range(ranges.AbstractSingleRangeImpl):
258
+ def bind_processor(self, dialect):
259
+ pg8000_Range = dialect.dbapi.Range
260
+
261
+ def to_range(value):
262
+ if isinstance(value, ranges.Range):
263
+ value = pg8000_Range(
264
+ value.lower, value.upper, value.bounds, value.empty
265
+ )
266
+ return value
267
+
268
+ return to_range
269
+
270
+ def result_processor(self, dialect, coltype):
271
+ def to_range(value):
272
+ if value is not None:
273
+ value = ranges.Range(
274
+ value.lower,
275
+ value.upper,
276
+ bounds=value.bounds,
277
+ empty=value.is_empty,
278
+ )
279
+ return value
280
+
281
+ return to_range
282
+
283
+
284
+ class _Pg8000MultiRange(ranges.AbstractMultiRangeImpl):
285
+ def bind_processor(self, dialect):
286
+ pg8000_Range = dialect.dbapi.Range
287
+
288
+ def to_multirange(value):
289
+ if isinstance(value, list):
290
+ mr = []
291
+ for v in value:
292
+ if isinstance(v, ranges.Range):
293
+ mr.append(
294
+ pg8000_Range(v.lower, v.upper, v.bounds, v.empty)
295
+ )
296
+ else:
297
+ mr.append(v)
298
+ return mr
299
+ else:
300
+ return value
301
+
302
+ return to_multirange
303
+
304
+ def result_processor(self, dialect, coltype):
305
+ def to_multirange(value):
306
+ if value is None:
307
+ return None
308
+ else:
309
+ return ranges.MultiRange(
310
+ ranges.Range(
311
+ v.lower, v.upper, bounds=v.bounds, empty=v.is_empty
312
+ )
313
+ for v in value
314
+ )
315
+
316
+ return to_multirange
317
+
318
+
319
+ _server_side_id = util.counter()
320
+
321
+
322
+ class PGExecutionContext_pg8000(PGExecutionContext):
323
+ def create_server_side_cursor(self):
324
+ ident = "c_%s_%s" % (hex(id(self))[2:], hex(_server_side_id())[2:])
325
+ return ServerSideCursor(self._dbapi_connection.cursor(), ident)
326
+
327
+ def pre_exec(self):
328
+ if not self.compiled:
329
+ return
330
+
331
+
332
+ class ServerSideCursor:
333
+ server_side = True
334
+
335
+ def __init__(self, cursor, ident):
336
+ self.ident = ident
337
+ self.cursor = cursor
338
+
339
+ @property
340
+ def connection(self):
341
+ return self.cursor.connection
342
+
343
+ @property
344
+ def rowcount(self):
345
+ return self.cursor.rowcount
346
+
347
+ @property
348
+ def description(self):
349
+ return self.cursor.description
350
+
351
+ def execute(self, operation, args=(), stream=None):
352
+ op = "DECLARE " + self.ident + " NO SCROLL CURSOR FOR " + operation
353
+ self.cursor.execute(op, args, stream=stream)
354
+ return self
355
+
356
+ def executemany(self, operation, param_sets):
357
+ self.cursor.executemany(operation, param_sets)
358
+ return self
359
+
360
+ def fetchone(self):
361
+ self.cursor.execute("FETCH FORWARD 1 FROM " + self.ident)
362
+ return self.cursor.fetchone()
363
+
364
+ def fetchmany(self, num=None):
365
+ if num is None:
366
+ return self.fetchall()
367
+ else:
368
+ self.cursor.execute(
369
+ "FETCH FORWARD " + str(int(num)) + " FROM " + self.ident
370
+ )
371
+ return self.cursor.fetchall()
372
+
373
+ def fetchall(self):
374
+ self.cursor.execute("FETCH FORWARD ALL FROM " + self.ident)
375
+ return self.cursor.fetchall()
376
+
377
+ def close(self):
378
+ self.cursor.execute("CLOSE " + self.ident)
379
+ self.cursor.close()
380
+
381
+ def setinputsizes(self, *sizes):
382
+ self.cursor.setinputsizes(*sizes)
383
+
384
+ def setoutputsize(self, size, column=None):
385
+ pass
386
+
387
+
388
+ class PGCompiler_pg8000(PGCompiler):
389
+ def visit_mod_binary(self, binary, operator, **kw):
390
+ return (
391
+ self.process(binary.left, **kw)
392
+ + " %% "
393
+ + self.process(binary.right, **kw)
394
+ )
395
+
396
+
397
+ class PGIdentifierPreparer_pg8000(PGIdentifierPreparer):
398
+ def __init__(self, *args, **kwargs):
399
+ PGIdentifierPreparer.__init__(self, *args, **kwargs)
400
+ self._double_percents = False
401
+
402
+
403
+ class PGDialect_pg8000(PGDialect):
404
+ driver = "pg8000"
405
+ supports_statement_cache = True
406
+
407
+ supports_unicode_statements = True
408
+
409
+ supports_unicode_binds = True
410
+
411
+ default_paramstyle = "format"
412
+ supports_sane_multi_rowcount = True
413
+ execution_ctx_cls = PGExecutionContext_pg8000
414
+ statement_compiler = PGCompiler_pg8000
415
+ preparer = PGIdentifierPreparer_pg8000
416
+ supports_server_side_cursors = True
417
+
418
+ supports_native_json_serialization = False
419
+ supports_native_json_deserialization = True
420
+ dialect_injects_custom_json_deserializer = True
421
+
422
+ render_bind_cast = True
423
+
424
+ # reversed as of pg8000 1.16.6. 1.16.5 and lower
425
+ # are no longer compatible
426
+ description_encoding = None
427
+ # description_encoding = "use_encoding"
428
+
429
+ colspecs = util.update_copy(
430
+ PGDialect.colspecs,
431
+ {
432
+ sqltypes.String: _PGString,
433
+ sqltypes.Numeric: _PGNumericNoBind,
434
+ sqltypes.Float: _PGFloat,
435
+ sqltypes.JSON: _PGJSON,
436
+ sqltypes.Boolean: _PGBoolean,
437
+ sqltypes.NullType: _PGNullType,
438
+ JSONB: _PGJSONB,
439
+ CITEXT: CITEXT,
440
+ sqltypes.JSON.JSONPathType: _PGJSONPathType,
441
+ sqltypes.JSON.JSONIndexType: _PGJSONIndexType,
442
+ sqltypes.JSON.JSONIntIndexType: _PGJSONIntIndexType,
443
+ sqltypes.JSON.JSONStrIndexType: _PGJSONStrIndexType,
444
+ sqltypes.Interval: _PGInterval,
445
+ INTERVAL: _PGInterval,
446
+ sqltypes.DateTime: _PGTimeStamp,
447
+ sqltypes.DateTime: _PGTimeStamp,
448
+ sqltypes.Date: _PGDate,
449
+ sqltypes.Time: _PGTime,
450
+ sqltypes.Integer: _PGInteger,
451
+ sqltypes.SmallInteger: _PGSmallInteger,
452
+ sqltypes.BigInteger: _PGBigInteger,
453
+ sqltypes.Enum: _PGEnum,
454
+ sqltypes.ARRAY: _PGARRAY,
455
+ OIDVECTOR: _PGOIDVECTOR,
456
+ ranges.INT4RANGE: _Pg8000Range,
457
+ ranges.INT8RANGE: _Pg8000Range,
458
+ ranges.NUMRANGE: _Pg8000Range,
459
+ ranges.DATERANGE: _Pg8000Range,
460
+ ranges.TSRANGE: _Pg8000Range,
461
+ ranges.TSTZRANGE: _Pg8000Range,
462
+ ranges.INT4MULTIRANGE: _Pg8000MultiRange,
463
+ ranges.INT8MULTIRANGE: _Pg8000MultiRange,
464
+ ranges.NUMMULTIRANGE: _Pg8000MultiRange,
465
+ ranges.DATEMULTIRANGE: _Pg8000MultiRange,
466
+ ranges.TSMULTIRANGE: _Pg8000MultiRange,
467
+ ranges.TSTZMULTIRANGE: _Pg8000MultiRange,
468
+ },
469
+ )
470
+
471
+ def __init__(self, client_encoding=None, **kwargs):
472
+ PGDialect.__init__(self, **kwargs)
473
+ self.client_encoding = client_encoding
474
+
475
+ if self._dbapi_version < (1, 16, 6):
476
+ raise NotImplementedError("pg8000 1.16.6 or greater is required")
477
+
478
+ if self._native_inet_types:
479
+ raise NotImplementedError(
480
+ "The pg8000 dialect does not fully implement "
481
+ "ipaddress type handling; INET is supported by default, "
482
+ "CIDR is not"
483
+ )
484
+
485
+ @util.memoized_property
486
+ def _dbapi_version(self):
487
+ if self.dbapi and hasattr(self.dbapi, "__version__"):
488
+ return tuple(
489
+ [
490
+ int(x)
491
+ for x in re.findall(
492
+ r"(\d+)(?:[-\.]?|$)", self.dbapi.__version__
493
+ )
494
+ ]
495
+ )
496
+ else:
497
+ return (99, 99, 99)
498
+
499
+ @classmethod
500
+ def import_dbapi(cls):
501
+ return __import__("pg8000")
502
+
503
+ def create_connect_args(self, url):
504
+ opts = url.translate_connect_args(username="user")
505
+ if "port" in opts:
506
+ opts["port"] = int(opts["port"])
507
+ opts.update(url.query)
508
+ return ([], opts)
509
+
510
+ def is_disconnect(self, e, connection, cursor):
511
+ if isinstance(e, self.dbapi.InterfaceError) and "network error" in str(
512
+ e
513
+ ):
514
+ # new as of pg8000 1.19.0 for broken connections
515
+ return True
516
+
517
+ # connection was closed normally
518
+ return "connection is closed" in str(e)
519
+
520
+ def get_isolation_level_values(self, dbapi_connection):
521
+ return (
522
+ "AUTOCOMMIT",
523
+ "READ COMMITTED",
524
+ "READ UNCOMMITTED",
525
+ "REPEATABLE READ",
526
+ "SERIALIZABLE",
527
+ )
528
+
529
+ def set_isolation_level(self, dbapi_connection, level):
530
+ level = level.replace("_", " ")
531
+
532
+ if level == "AUTOCOMMIT":
533
+ dbapi_connection.autocommit = True
534
+ else:
535
+ dbapi_connection.autocommit = False
536
+ cursor = dbapi_connection.cursor()
537
+ cursor.execute(
538
+ "SET SESSION CHARACTERISTICS AS TRANSACTION "
539
+ f"ISOLATION LEVEL {level}"
540
+ )
541
+ cursor.execute("COMMIT")
542
+ cursor.close()
543
+
544
+ def detect_autocommit_setting(self, dbapi_conn) -> bool:
545
+ return bool(dbapi_conn.autocommit)
546
+
547
+ def set_readonly(self, connection, value):
548
+ cursor = connection.cursor()
549
+ try:
550
+ cursor.execute(
551
+ "SET SESSION CHARACTERISTICS AS TRANSACTION %s"
552
+ % ("READ ONLY" if value else "READ WRITE")
553
+ )
554
+ cursor.execute("COMMIT")
555
+ finally:
556
+ cursor.close()
557
+
558
+ def get_readonly(self, connection):
559
+ cursor = connection.cursor()
560
+ try:
561
+ cursor.execute("show transaction_read_only")
562
+ val = cursor.fetchone()[0]
563
+ finally:
564
+ cursor.close()
565
+
566
+ return val == "on"
567
+
568
+ def set_deferrable(self, connection, value):
569
+ cursor = connection.cursor()
570
+ try:
571
+ cursor.execute(
572
+ "SET SESSION CHARACTERISTICS AS TRANSACTION %s"
573
+ % ("DEFERRABLE" if value else "NOT DEFERRABLE")
574
+ )
575
+ cursor.execute("COMMIT")
576
+ finally:
577
+ cursor.close()
578
+
579
+ def get_deferrable(self, connection):
580
+ cursor = connection.cursor()
581
+ try:
582
+ cursor.execute("show transaction_deferrable")
583
+ val = cursor.fetchone()[0]
584
+ finally:
585
+ cursor.close()
586
+
587
+ return val == "on"
588
+
589
+ def _set_client_encoding(self, dbapi_connection, client_encoding):
590
+ cursor = dbapi_connection.cursor()
591
+ cursor.execute(
592
+ f"""SET CLIENT_ENCODING TO '{
593
+ client_encoding.replace("'", "''")
594
+ }'"""
595
+ )
596
+ cursor.execute("COMMIT")
597
+ cursor.close()
598
+
599
+ def do_begin_twophase(self, connection, xid):
600
+ connection.connection.tpc_begin((0, xid, ""))
601
+
602
+ def do_prepare_twophase(self, connection, xid):
603
+ connection.connection.tpc_prepare()
604
+
605
+ def do_rollback_twophase(
606
+ self, connection, xid, is_prepared=True, recover=False
607
+ ):
608
+ connection.connection.tpc_rollback((0, xid, ""))
609
+
610
+ def do_commit_twophase(
611
+ self, connection, xid, is_prepared=True, recover=False
612
+ ):
613
+ connection.connection.tpc_commit((0, xid, ""))
614
+
615
+ def do_recover_twophase(self, connection):
616
+ return [row[1] for row in connection.connection.tpc_recover()]
617
+
618
+ def on_connect(self):
619
+ fns = []
620
+
621
+ def on_connect(conn):
622
+ conn.py_types[quoted_name] = conn.py_types[str]
623
+
624
+ fns.append(on_connect)
625
+
626
+ if self.client_encoding is not None:
627
+
628
+ def on_connect(conn):
629
+ self._set_client_encoding(conn, self.client_encoding)
630
+
631
+ fns.append(on_connect)
632
+
633
+ if self._native_inet_types is False:
634
+
635
+ def on_connect(conn):
636
+ # inet
637
+ conn.register_in_adapter(869, lambda s: s)
638
+
639
+ # cidr
640
+ conn.register_in_adapter(650, lambda s: s)
641
+
642
+ fns.append(on_connect)
643
+
644
+ if self._json_deserializer:
645
+
646
+ def on_connect(conn):
647
+ # json
648
+ conn.register_in_adapter(114, self._json_deserializer)
649
+
650
+ # jsonb
651
+ conn.register_in_adapter(3802, self._json_deserializer)
652
+
653
+ fns.append(on_connect)
654
+
655
+ if len(fns) > 0:
656
+
657
+ def on_connect(conn):
658
+ for fn in fns:
659
+ fn(conn)
660
+
661
+ return on_connect
662
+ else:
663
+ return None
664
+
665
+ @util.memoized_property
666
+ def _dialect_specific_select_one(self):
667
+ return ";"
668
+
669
+
670
+ dialect = PGDialect_pg8000