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,496 @@
1
+ # dialects/postgresql/ext.py
2
+ # Copyright (C) 2005-2024 the SQLAlchemy authors and contributors
3
+ # <see AUTHORS file>
4
+ #
5
+ # This module is part of SQLAlchemy and is released under
6
+ # the MIT License: https://www.opensource.org/licenses/mit-license.php
7
+ # mypy: ignore-errors
8
+ from __future__ import annotations
9
+
10
+ from typing import Any
11
+ from typing import TYPE_CHECKING
12
+ from typing import TypeVar
13
+
14
+ from . import types
15
+ from .array import ARRAY
16
+ from ...sql import coercions
17
+ from ...sql import elements
18
+ from ...sql import expression
19
+ from ...sql import functions
20
+ from ...sql import roles
21
+ from ...sql import schema
22
+ from ...sql.schema import ColumnCollectionConstraint
23
+ from ...sql.sqltypes import TEXT
24
+ from ...sql.visitors import InternalTraversal
25
+
26
+ _T = TypeVar("_T", bound=Any)
27
+
28
+ if TYPE_CHECKING:
29
+ from ...sql.visitors import _TraverseInternalsType
30
+
31
+
32
+ class aggregate_order_by(expression.ColumnElement):
33
+ """Represent a PostgreSQL aggregate order by expression.
34
+
35
+ E.g.::
36
+
37
+ from sqlalchemy.dialects.postgresql import aggregate_order_by
38
+ expr = func.array_agg(aggregate_order_by(table.c.a, table.c.b.desc()))
39
+ stmt = select(expr)
40
+
41
+ would represent the expression::
42
+
43
+ SELECT array_agg(a ORDER BY b DESC) FROM table;
44
+
45
+ Similarly::
46
+
47
+ expr = func.string_agg(
48
+ table.c.a,
49
+ aggregate_order_by(literal_column("','"), table.c.a)
50
+ )
51
+ stmt = select(expr)
52
+
53
+ Would represent::
54
+
55
+ SELECT string_agg(a, ',' ORDER BY a) FROM table;
56
+
57
+ .. versionchanged:: 1.2.13 - the ORDER BY argument may be multiple terms
58
+
59
+ .. seealso::
60
+
61
+ :class:`_functions.array_agg`
62
+
63
+ """
64
+
65
+ __visit_name__ = "aggregate_order_by"
66
+
67
+ stringify_dialect = "postgresql"
68
+ _traverse_internals: _TraverseInternalsType = [
69
+ ("target", InternalTraversal.dp_clauseelement),
70
+ ("type", InternalTraversal.dp_type),
71
+ ("order_by", InternalTraversal.dp_clauseelement),
72
+ ]
73
+
74
+ def __init__(self, target, *order_by):
75
+ self.target = coercions.expect(roles.ExpressionElementRole, target)
76
+ self.type = self.target.type
77
+
78
+ _lob = len(order_by)
79
+ if _lob == 0:
80
+ raise TypeError("at least one ORDER BY element is required")
81
+ elif _lob == 1:
82
+ self.order_by = coercions.expect(
83
+ roles.ExpressionElementRole, order_by[0]
84
+ )
85
+ else:
86
+ self.order_by = elements.ClauseList(
87
+ *order_by, _literal_as_text_role=roles.ExpressionElementRole
88
+ )
89
+
90
+ def self_group(self, against=None):
91
+ return self
92
+
93
+ def get_children(self, **kwargs):
94
+ return self.target, self.order_by
95
+
96
+ def _copy_internals(self, clone=elements._clone, **kw):
97
+ self.target = clone(self.target, **kw)
98
+ self.order_by = clone(self.order_by, **kw)
99
+
100
+ @property
101
+ def _from_objects(self):
102
+ return self.target._from_objects + self.order_by._from_objects
103
+
104
+
105
+ class ExcludeConstraint(ColumnCollectionConstraint):
106
+ """A table-level EXCLUDE constraint.
107
+
108
+ Defines an EXCLUDE constraint as described in the `PostgreSQL
109
+ documentation`__.
110
+
111
+ __ https://www.postgresql.org/docs/current/static/sql-createtable.html#SQL-CREATETABLE-EXCLUDE
112
+
113
+ """ # noqa
114
+
115
+ __visit_name__ = "exclude_constraint"
116
+
117
+ where = None
118
+ inherit_cache = False
119
+
120
+ create_drop_stringify_dialect = "postgresql"
121
+
122
+ @elements._document_text_coercion(
123
+ "where",
124
+ ":class:`.ExcludeConstraint`",
125
+ ":paramref:`.ExcludeConstraint.where`",
126
+ )
127
+ def __init__(self, *elements, **kw):
128
+ r"""
129
+ Create an :class:`.ExcludeConstraint` object.
130
+
131
+ E.g.::
132
+
133
+ const = ExcludeConstraint(
134
+ (Column('period'), '&&'),
135
+ (Column('group'), '='),
136
+ where=(Column('group') != 'some group'),
137
+ ops={'group': 'my_operator_class'}
138
+ )
139
+
140
+ The constraint is normally embedded into the :class:`_schema.Table`
141
+ construct
142
+ directly, or added later using :meth:`.append_constraint`::
143
+
144
+ some_table = Table(
145
+ 'some_table', metadata,
146
+ Column('id', Integer, primary_key=True),
147
+ Column('period', TSRANGE()),
148
+ Column('group', String)
149
+ )
150
+
151
+ some_table.append_constraint(
152
+ ExcludeConstraint(
153
+ (some_table.c.period, '&&'),
154
+ (some_table.c.group, '='),
155
+ where=some_table.c.group != 'some group',
156
+ name='some_table_excl_const',
157
+ ops={'group': 'my_operator_class'}
158
+ )
159
+ )
160
+
161
+ The exclude constraint defined in this example requires the
162
+ ``btree_gist`` extension, that can be created using the
163
+ command ``CREATE EXTENSION btree_gist;``.
164
+
165
+ :param \*elements:
166
+
167
+ A sequence of two tuples of the form ``(column, operator)`` where
168
+ "column" is either a :class:`_schema.Column` object, or a SQL
169
+ expression element (e.g. ``func.int8range(table.from, table.to)``)
170
+ or the name of a column as string, and "operator" is a string
171
+ containing the operator to use (e.g. `"&&"` or `"="`).
172
+
173
+ In order to specify a column name when a :class:`_schema.Column`
174
+ object is not available, while ensuring
175
+ that any necessary quoting rules take effect, an ad-hoc
176
+ :class:`_schema.Column` or :func:`_expression.column`
177
+ object should be used.
178
+ The ``column`` may also be a string SQL expression when
179
+ passed as :func:`_expression.literal_column` or
180
+ :func:`_expression.text`
181
+
182
+ :param name:
183
+ Optional, the in-database name of this constraint.
184
+
185
+ :param deferrable:
186
+ Optional bool. If set, emit DEFERRABLE or NOT DEFERRABLE when
187
+ issuing DDL for this constraint.
188
+
189
+ :param initially:
190
+ Optional string. If set, emit INITIALLY <value> when issuing DDL
191
+ for this constraint.
192
+
193
+ :param using:
194
+ Optional string. If set, emit USING <index_method> when issuing DDL
195
+ for this constraint. Defaults to 'gist'.
196
+
197
+ :param where:
198
+ Optional SQL expression construct or literal SQL string.
199
+ If set, emit WHERE <predicate> when issuing DDL
200
+ for this constraint.
201
+
202
+ :param ops:
203
+ Optional dictionary. Used to define operator classes for the
204
+ elements; works the same way as that of the
205
+ :ref:`postgresql_ops <postgresql_operator_classes>`
206
+ parameter specified to the :class:`_schema.Index` construct.
207
+
208
+ .. versionadded:: 1.3.21
209
+
210
+ .. seealso::
211
+
212
+ :ref:`postgresql_operator_classes` - general description of how
213
+ PostgreSQL operator classes are specified.
214
+
215
+ """
216
+ columns = []
217
+ render_exprs = []
218
+ self.operators = {}
219
+
220
+ expressions, operators = zip(*elements)
221
+
222
+ for (expr, column, strname, add_element), operator in zip(
223
+ coercions.expect_col_expression_collection(
224
+ roles.DDLConstraintColumnRole, expressions
225
+ ),
226
+ operators,
227
+ ):
228
+ if add_element is not None:
229
+ columns.append(add_element)
230
+
231
+ name = column.name if column is not None else strname
232
+
233
+ if name is not None:
234
+ # backwards compat
235
+ self.operators[name] = operator
236
+
237
+ render_exprs.append((expr, name, operator))
238
+
239
+ self._render_exprs = render_exprs
240
+
241
+ ColumnCollectionConstraint.__init__(
242
+ self,
243
+ *columns,
244
+ name=kw.get("name"),
245
+ deferrable=kw.get("deferrable"),
246
+ initially=kw.get("initially"),
247
+ )
248
+ self.using = kw.get("using", "gist")
249
+ where = kw.get("where")
250
+ if where is not None:
251
+ self.where = coercions.expect(roles.StatementOptionRole, where)
252
+
253
+ self.ops = kw.get("ops", {})
254
+
255
+ def _set_parent(self, table, **kw):
256
+ super()._set_parent(table)
257
+
258
+ self._render_exprs = [
259
+ (
260
+ expr if not isinstance(expr, str) else table.c[expr],
261
+ name,
262
+ operator,
263
+ )
264
+ for expr, name, operator in (self._render_exprs)
265
+ ]
266
+
267
+ def _copy(self, target_table=None, **kw):
268
+ elements = [
269
+ (
270
+ schema._copy_expression(expr, self.parent, target_table),
271
+ operator,
272
+ )
273
+ for expr, _, operator in self._render_exprs
274
+ ]
275
+ c = self.__class__(
276
+ *elements,
277
+ name=self.name,
278
+ deferrable=self.deferrable,
279
+ initially=self.initially,
280
+ where=self.where,
281
+ using=self.using,
282
+ )
283
+ c.dispatch._update(self.dispatch)
284
+ return c
285
+
286
+
287
+ def array_agg(*arg, **kw):
288
+ """PostgreSQL-specific form of :class:`_functions.array_agg`, ensures
289
+ return type is :class:`_postgresql.ARRAY` and not
290
+ the plain :class:`_types.ARRAY`, unless an explicit ``type_``
291
+ is passed.
292
+
293
+ """
294
+ kw["_default_array_type"] = ARRAY
295
+ return functions.func.array_agg(*arg, **kw)
296
+
297
+
298
+ class _regconfig_fn(functions.GenericFunction[_T]):
299
+ inherit_cache = True
300
+
301
+ def __init__(self, *args, **kwargs):
302
+ args = list(args)
303
+ if len(args) > 1:
304
+ initial_arg = coercions.expect(
305
+ roles.ExpressionElementRole,
306
+ args.pop(0),
307
+ name=getattr(self, "name", None),
308
+ apply_propagate_attrs=self,
309
+ type_=types.REGCONFIG,
310
+ )
311
+ initial_arg = [initial_arg]
312
+ else:
313
+ initial_arg = []
314
+
315
+ addtl_args = [
316
+ coercions.expect(
317
+ roles.ExpressionElementRole,
318
+ c,
319
+ name=getattr(self, "name", None),
320
+ apply_propagate_attrs=self,
321
+ )
322
+ for c in args
323
+ ]
324
+ super().__init__(*(initial_arg + addtl_args), **kwargs)
325
+
326
+
327
+ class to_tsvector(_regconfig_fn):
328
+ """The PostgreSQL ``to_tsvector`` SQL function.
329
+
330
+ This function applies automatic casting of the REGCONFIG argument
331
+ to use the :class:`_postgresql.REGCONFIG` datatype automatically,
332
+ and applies a return type of :class:`_postgresql.TSVECTOR`.
333
+
334
+ Assuming the PostgreSQL dialect has been imported, either by invoking
335
+ ``from sqlalchemy.dialects import postgresql``, or by creating a PostgreSQL
336
+ engine using ``create_engine("postgresql...")``,
337
+ :class:`_postgresql.to_tsvector` will be used automatically when invoking
338
+ ``sqlalchemy.func.to_tsvector()``, ensuring the correct argument and return
339
+ type handlers are used at compile and execution time.
340
+
341
+ .. versionadded:: 2.0.0rc1
342
+
343
+ """
344
+
345
+ inherit_cache = True
346
+ type = types.TSVECTOR
347
+
348
+
349
+ class to_tsquery(_regconfig_fn):
350
+ """The PostgreSQL ``to_tsquery`` SQL function.
351
+
352
+ This function applies automatic casting of the REGCONFIG argument
353
+ to use the :class:`_postgresql.REGCONFIG` datatype automatically,
354
+ and applies a return type of :class:`_postgresql.TSQUERY`.
355
+
356
+ Assuming the PostgreSQL dialect has been imported, either by invoking
357
+ ``from sqlalchemy.dialects import postgresql``, or by creating a PostgreSQL
358
+ engine using ``create_engine("postgresql...")``,
359
+ :class:`_postgresql.to_tsquery` will be used automatically when invoking
360
+ ``sqlalchemy.func.to_tsquery()``, ensuring the correct argument and return
361
+ type handlers are used at compile and execution time.
362
+
363
+ .. versionadded:: 2.0.0rc1
364
+
365
+ """
366
+
367
+ inherit_cache = True
368
+ type = types.TSQUERY
369
+
370
+
371
+ class plainto_tsquery(_regconfig_fn):
372
+ """The PostgreSQL ``plainto_tsquery`` SQL function.
373
+
374
+ This function applies automatic casting of the REGCONFIG argument
375
+ to use the :class:`_postgresql.REGCONFIG` datatype automatically,
376
+ and applies a return type of :class:`_postgresql.TSQUERY`.
377
+
378
+ Assuming the PostgreSQL dialect has been imported, either by invoking
379
+ ``from sqlalchemy.dialects import postgresql``, or by creating a PostgreSQL
380
+ engine using ``create_engine("postgresql...")``,
381
+ :class:`_postgresql.plainto_tsquery` will be used automatically when
382
+ invoking ``sqlalchemy.func.plainto_tsquery()``, ensuring the correct
383
+ argument and return type handlers are used at compile and execution time.
384
+
385
+ .. versionadded:: 2.0.0rc1
386
+
387
+ """
388
+
389
+ inherit_cache = True
390
+ type = types.TSQUERY
391
+
392
+
393
+ class phraseto_tsquery(_regconfig_fn):
394
+ """The PostgreSQL ``phraseto_tsquery`` SQL function.
395
+
396
+ This function applies automatic casting of the REGCONFIG argument
397
+ to use the :class:`_postgresql.REGCONFIG` datatype automatically,
398
+ and applies a return type of :class:`_postgresql.TSQUERY`.
399
+
400
+ Assuming the PostgreSQL dialect has been imported, either by invoking
401
+ ``from sqlalchemy.dialects import postgresql``, or by creating a PostgreSQL
402
+ engine using ``create_engine("postgresql...")``,
403
+ :class:`_postgresql.phraseto_tsquery` will be used automatically when
404
+ invoking ``sqlalchemy.func.phraseto_tsquery()``, ensuring the correct
405
+ argument and return type handlers are used at compile and execution time.
406
+
407
+ .. versionadded:: 2.0.0rc1
408
+
409
+ """
410
+
411
+ inherit_cache = True
412
+ type = types.TSQUERY
413
+
414
+
415
+ class websearch_to_tsquery(_regconfig_fn):
416
+ """The PostgreSQL ``websearch_to_tsquery`` SQL function.
417
+
418
+ This function applies automatic casting of the REGCONFIG argument
419
+ to use the :class:`_postgresql.REGCONFIG` datatype automatically,
420
+ and applies a return type of :class:`_postgresql.TSQUERY`.
421
+
422
+ Assuming the PostgreSQL dialect has been imported, either by invoking
423
+ ``from sqlalchemy.dialects import postgresql``, or by creating a PostgreSQL
424
+ engine using ``create_engine("postgresql...")``,
425
+ :class:`_postgresql.websearch_to_tsquery` will be used automatically when
426
+ invoking ``sqlalchemy.func.websearch_to_tsquery()``, ensuring the correct
427
+ argument and return type handlers are used at compile and execution time.
428
+
429
+ .. versionadded:: 2.0.0rc1
430
+
431
+ """
432
+
433
+ inherit_cache = True
434
+ type = types.TSQUERY
435
+
436
+
437
+ class ts_headline(_regconfig_fn):
438
+ """The PostgreSQL ``ts_headline`` SQL function.
439
+
440
+ This function applies automatic casting of the REGCONFIG argument
441
+ to use the :class:`_postgresql.REGCONFIG` datatype automatically,
442
+ and applies a return type of :class:`_types.TEXT`.
443
+
444
+ Assuming the PostgreSQL dialect has been imported, either by invoking
445
+ ``from sqlalchemy.dialects import postgresql``, or by creating a PostgreSQL
446
+ engine using ``create_engine("postgresql...")``,
447
+ :class:`_postgresql.ts_headline` will be used automatically when invoking
448
+ ``sqlalchemy.func.ts_headline()``, ensuring the correct argument and return
449
+ type handlers are used at compile and execution time.
450
+
451
+ .. versionadded:: 2.0.0rc1
452
+
453
+ """
454
+
455
+ inherit_cache = True
456
+ type = TEXT
457
+
458
+ def __init__(self, *args, **kwargs):
459
+ args = list(args)
460
+
461
+ # parse types according to
462
+ # https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-HEADLINE
463
+ if len(args) < 2:
464
+ # invalid args; don't do anything
465
+ has_regconfig = False
466
+ elif (
467
+ isinstance(args[1], elements.ColumnElement)
468
+ and args[1].type._type_affinity is types.TSQUERY
469
+ ):
470
+ # tsquery is second argument, no regconfig argument
471
+ has_regconfig = False
472
+ else:
473
+ has_regconfig = True
474
+
475
+ if has_regconfig:
476
+ initial_arg = coercions.expect(
477
+ roles.ExpressionElementRole,
478
+ args.pop(0),
479
+ apply_propagate_attrs=self,
480
+ name=getattr(self, "name", None),
481
+ type_=types.REGCONFIG,
482
+ )
483
+ initial_arg = [initial_arg]
484
+ else:
485
+ initial_arg = []
486
+
487
+ addtl_args = [
488
+ coercions.expect(
489
+ roles.ExpressionElementRole,
490
+ c,
491
+ name=getattr(self, "name", None),
492
+ apply_propagate_attrs=self,
493
+ )
494
+ for c in args
495
+ ]
496
+ super().__init__(*(initial_arg + addtl_args), **kwargs)