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