SQLAlchemy 2.0.36__cp313-cp313-win32.whl

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