SQLAlchemy 2.0.47__cp313-cp313t-win32.whl

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