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,300 @@
1
+ # dialects/postgresql/pg_catalog.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
+
9
+ from .array import ARRAY
10
+ from .types import OID
11
+ from .types import REGCLASS
12
+ from ... import Column
13
+ from ... import func
14
+ from ... import MetaData
15
+ from ... import Table
16
+ from ...types import BigInteger
17
+ from ...types import Boolean
18
+ from ...types import CHAR
19
+ from ...types import Float
20
+ from ...types import Integer
21
+ from ...types import SmallInteger
22
+ from ...types import String
23
+ from ...types import Text
24
+ from ...types import TypeDecorator
25
+
26
+
27
+ # types
28
+ class NAME(TypeDecorator):
29
+ impl = String(64, collation="C")
30
+ cache_ok = True
31
+
32
+
33
+ class PG_NODE_TREE(TypeDecorator):
34
+ impl = Text(collation="C")
35
+ cache_ok = True
36
+
37
+
38
+ class INT2VECTOR(TypeDecorator):
39
+ impl = ARRAY(SmallInteger)
40
+ cache_ok = True
41
+
42
+
43
+ class OIDVECTOR(TypeDecorator):
44
+ impl = ARRAY(OID)
45
+ cache_ok = True
46
+
47
+
48
+ class _SpaceVector:
49
+ def result_processor(self, dialect, coltype):
50
+ def process(value):
51
+ if value is None:
52
+ return value
53
+ return [int(p) for p in value.split(" ")]
54
+
55
+ return process
56
+
57
+
58
+ REGPROC = REGCLASS # seems an alias
59
+
60
+ # functions
61
+ _pg_cat = func.pg_catalog
62
+ quote_ident = _pg_cat.quote_ident
63
+ pg_table_is_visible = _pg_cat.pg_table_is_visible
64
+ pg_type_is_visible = _pg_cat.pg_type_is_visible
65
+ pg_get_viewdef = _pg_cat.pg_get_viewdef
66
+ pg_get_serial_sequence = _pg_cat.pg_get_serial_sequence
67
+ format_type = _pg_cat.format_type
68
+ pg_get_expr = _pg_cat.pg_get_expr
69
+ pg_get_constraintdef = _pg_cat.pg_get_constraintdef
70
+ pg_get_indexdef = _pg_cat.pg_get_indexdef
71
+
72
+ # constants
73
+ RELKINDS_TABLE_NO_FOREIGN = ("r", "p")
74
+ RELKINDS_TABLE = RELKINDS_TABLE_NO_FOREIGN + ("f",)
75
+ RELKINDS_VIEW = ("v",)
76
+ RELKINDS_MAT_VIEW = ("m",)
77
+ RELKINDS_ALL_TABLE_LIKE = RELKINDS_TABLE + RELKINDS_VIEW + RELKINDS_MAT_VIEW
78
+
79
+ # tables
80
+ pg_catalog_meta = MetaData(schema="pg_catalog")
81
+
82
+ pg_namespace = Table(
83
+ "pg_namespace",
84
+ pg_catalog_meta,
85
+ Column("oid", OID),
86
+ Column("nspname", NAME),
87
+ Column("nspowner", OID),
88
+ )
89
+
90
+ pg_class = Table(
91
+ "pg_class",
92
+ pg_catalog_meta,
93
+ Column("oid", OID, info={"server_version": (9, 3)}),
94
+ Column("relname", NAME),
95
+ Column("relnamespace", OID),
96
+ Column("reltype", OID),
97
+ Column("reloftype", OID),
98
+ Column("relowner", OID),
99
+ Column("relam", OID),
100
+ Column("relfilenode", OID),
101
+ Column("reltablespace", OID),
102
+ Column("relpages", Integer),
103
+ Column("reltuples", Float),
104
+ Column("relallvisible", Integer, info={"server_version": (9, 2)}),
105
+ Column("reltoastrelid", OID),
106
+ Column("relhasindex", Boolean),
107
+ Column("relisshared", Boolean),
108
+ Column("relpersistence", CHAR, info={"server_version": (9, 1)}),
109
+ Column("relkind", CHAR),
110
+ Column("relnatts", SmallInteger),
111
+ Column("relchecks", SmallInteger),
112
+ Column("relhasrules", Boolean),
113
+ Column("relhastriggers", Boolean),
114
+ Column("relhassubclass", Boolean),
115
+ Column("relrowsecurity", Boolean),
116
+ Column("relforcerowsecurity", Boolean, info={"server_version": (9, 5)}),
117
+ Column("relispopulated", Boolean, info={"server_version": (9, 3)}),
118
+ Column("relreplident", CHAR, info={"server_version": (9, 4)}),
119
+ Column("relispartition", Boolean, info={"server_version": (10,)}),
120
+ Column("relrewrite", OID, info={"server_version": (11,)}),
121
+ Column("reloptions", ARRAY(Text)),
122
+ )
123
+
124
+ pg_type = Table(
125
+ "pg_type",
126
+ pg_catalog_meta,
127
+ Column("oid", OID, info={"server_version": (9, 3)}),
128
+ Column("typname", NAME),
129
+ Column("typnamespace", OID),
130
+ Column("typowner", OID),
131
+ Column("typlen", SmallInteger),
132
+ Column("typbyval", Boolean),
133
+ Column("typtype", CHAR),
134
+ Column("typcategory", CHAR),
135
+ Column("typispreferred", Boolean),
136
+ Column("typisdefined", Boolean),
137
+ Column("typdelim", CHAR),
138
+ Column("typrelid", OID),
139
+ Column("typelem", OID),
140
+ Column("typarray", OID),
141
+ Column("typinput", REGPROC),
142
+ Column("typoutput", REGPROC),
143
+ Column("typreceive", REGPROC),
144
+ Column("typsend", REGPROC),
145
+ Column("typmodin", REGPROC),
146
+ Column("typmodout", REGPROC),
147
+ Column("typanalyze", REGPROC),
148
+ Column("typalign", CHAR),
149
+ Column("typstorage", CHAR),
150
+ Column("typnotnull", Boolean),
151
+ Column("typbasetype", OID),
152
+ Column("typtypmod", Integer),
153
+ Column("typndims", Integer),
154
+ Column("typcollation", OID, info={"server_version": (9, 1)}),
155
+ Column("typdefault", Text),
156
+ )
157
+
158
+ pg_index = Table(
159
+ "pg_index",
160
+ pg_catalog_meta,
161
+ Column("indexrelid", OID),
162
+ Column("indrelid", OID),
163
+ Column("indnatts", SmallInteger),
164
+ Column("indnkeyatts", SmallInteger, info={"server_version": (11,)}),
165
+ Column("indisunique", Boolean),
166
+ Column("indnullsnotdistinct", Boolean, info={"server_version": (15,)}),
167
+ Column("indisprimary", Boolean),
168
+ Column("indisexclusion", Boolean, info={"server_version": (9, 1)}),
169
+ Column("indimmediate", Boolean),
170
+ Column("indisclustered", Boolean),
171
+ Column("indisvalid", Boolean),
172
+ Column("indcheckxmin", Boolean),
173
+ Column("indisready", Boolean),
174
+ Column("indislive", Boolean, info={"server_version": (9, 3)}), # 9.3
175
+ Column("indisreplident", Boolean),
176
+ Column("indkey", INT2VECTOR),
177
+ Column("indcollation", OIDVECTOR, info={"server_version": (9, 1)}), # 9.1
178
+ Column("indclass", OIDVECTOR),
179
+ Column("indoption", INT2VECTOR),
180
+ Column("indexprs", PG_NODE_TREE),
181
+ Column("indpred", PG_NODE_TREE),
182
+ )
183
+
184
+ pg_attribute = Table(
185
+ "pg_attribute",
186
+ pg_catalog_meta,
187
+ Column("attrelid", OID),
188
+ Column("attname", NAME),
189
+ Column("atttypid", OID),
190
+ Column("attstattarget", Integer),
191
+ Column("attlen", SmallInteger),
192
+ Column("attnum", SmallInteger),
193
+ Column("attndims", Integer),
194
+ Column("attcacheoff", Integer),
195
+ Column("atttypmod", Integer),
196
+ Column("attbyval", Boolean),
197
+ Column("attstorage", CHAR),
198
+ Column("attalign", CHAR),
199
+ Column("attnotnull", Boolean),
200
+ Column("atthasdef", Boolean),
201
+ Column("atthasmissing", Boolean, info={"server_version": (11,)}),
202
+ Column("attidentity", CHAR, info={"server_version": (10,)}),
203
+ Column("attgenerated", CHAR, info={"server_version": (12,)}),
204
+ Column("attisdropped", Boolean),
205
+ Column("attislocal", Boolean),
206
+ Column("attinhcount", Integer),
207
+ Column("attcollation", OID, info={"server_version": (9, 1)}),
208
+ )
209
+
210
+ pg_constraint = Table(
211
+ "pg_constraint",
212
+ pg_catalog_meta,
213
+ Column("oid", OID), # 9.3
214
+ Column("conname", NAME),
215
+ Column("connamespace", OID),
216
+ Column("contype", CHAR),
217
+ Column("condeferrable", Boolean),
218
+ Column("condeferred", Boolean),
219
+ Column("convalidated", Boolean, info={"server_version": (9, 1)}),
220
+ Column("conrelid", OID),
221
+ Column("contypid", OID),
222
+ Column("conindid", OID),
223
+ Column("conparentid", OID, info={"server_version": (11,)}),
224
+ Column("confrelid", OID),
225
+ Column("confupdtype", CHAR),
226
+ Column("confdeltype", CHAR),
227
+ Column("confmatchtype", CHAR),
228
+ Column("conislocal", Boolean),
229
+ Column("coninhcount", Integer),
230
+ Column("connoinherit", Boolean, info={"server_version": (9, 2)}),
231
+ Column("conkey", ARRAY(SmallInteger)),
232
+ Column("confkey", ARRAY(SmallInteger)),
233
+ )
234
+
235
+ pg_sequence = Table(
236
+ "pg_sequence",
237
+ pg_catalog_meta,
238
+ Column("seqrelid", OID),
239
+ Column("seqtypid", OID),
240
+ Column("seqstart", BigInteger),
241
+ Column("seqincrement", BigInteger),
242
+ Column("seqmax", BigInteger),
243
+ Column("seqmin", BigInteger),
244
+ Column("seqcache", BigInteger),
245
+ Column("seqcycle", Boolean),
246
+ info={"server_version": (10,)},
247
+ )
248
+
249
+ pg_attrdef = Table(
250
+ "pg_attrdef",
251
+ pg_catalog_meta,
252
+ Column("oid", OID, info={"server_version": (9, 3)}),
253
+ Column("adrelid", OID),
254
+ Column("adnum", SmallInteger),
255
+ Column("adbin", PG_NODE_TREE),
256
+ )
257
+
258
+ pg_description = Table(
259
+ "pg_description",
260
+ pg_catalog_meta,
261
+ Column("objoid", OID),
262
+ Column("classoid", OID),
263
+ Column("objsubid", Integer),
264
+ Column("description", Text(collation="C")),
265
+ )
266
+
267
+ pg_enum = Table(
268
+ "pg_enum",
269
+ pg_catalog_meta,
270
+ Column("oid", OID, info={"server_version": (9, 3)}),
271
+ Column("enumtypid", OID),
272
+ Column("enumsortorder", Float(), info={"server_version": (9, 1)}),
273
+ Column("enumlabel", NAME),
274
+ )
275
+
276
+ pg_am = Table(
277
+ "pg_am",
278
+ pg_catalog_meta,
279
+ Column("oid", OID, info={"server_version": (9, 3)}),
280
+ Column("amname", NAME),
281
+ Column("amhandler", REGPROC, info={"server_version": (9, 6)}),
282
+ Column("amtype", CHAR, info={"server_version": (9, 6)}),
283
+ )
284
+
285
+ pg_collation = Table(
286
+ "pg_collation",
287
+ pg_catalog_meta,
288
+ Column("oid", OID, info={"server_version": (9, 3)}),
289
+ Column("collname", NAME),
290
+ Column("collnamespace", OID),
291
+ Column("collowner", OID),
292
+ Column("collprovider", CHAR, info={"server_version": (10,)}),
293
+ Column("collisdeterministic", Boolean, info={"server_version": (12,)}),
294
+ Column("collencoding", Integer),
295
+ Column("collcollate", Text),
296
+ Column("collctype", Text),
297
+ Column("colliculocale", Text),
298
+ Column("collicurules", Text, info={"server_version": (16,)}),
299
+ Column("collversion", Text, info={"server_version": (10,)}),
300
+ )
@@ -0,0 +1,175 @@
1
+ # dialects/postgresql/provision.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
+
9
+ import time
10
+
11
+ from ... import exc
12
+ from ... import inspect
13
+ from ... import text
14
+ from ...testing import warn_test_suite
15
+ from ...testing.provision import create_db
16
+ from ...testing.provision import drop_all_schema_objects_post_tables
17
+ from ...testing.provision import drop_all_schema_objects_pre_tables
18
+ from ...testing.provision import drop_db
19
+ from ...testing.provision import log
20
+ from ...testing.provision import post_configure_engine
21
+ from ...testing.provision import prepare_for_drop_tables
22
+ from ...testing.provision import set_default_schema_on_connection
23
+ from ...testing.provision import temp_table_keyword_args
24
+ from ...testing.provision import upsert
25
+
26
+
27
+ @create_db.for_db("postgresql")
28
+ def _pg_create_db(cfg, eng, ident):
29
+ template_db = cfg.options.postgresql_templatedb
30
+
31
+ with eng.execution_options(isolation_level="AUTOCOMMIT").begin() as conn:
32
+ if not template_db:
33
+ template_db = conn.exec_driver_sql(
34
+ "select current_database()"
35
+ ).scalar()
36
+
37
+ attempt = 0
38
+ while True:
39
+ try:
40
+ conn.exec_driver_sql(
41
+ "CREATE DATABASE %s TEMPLATE %s" % (ident, template_db)
42
+ )
43
+ except exc.OperationalError as err:
44
+ attempt += 1
45
+ if attempt >= 3:
46
+ raise
47
+ if "accessed by other users" in str(err):
48
+ log.info(
49
+ "Waiting to create %s, URI %r, "
50
+ "template DB %s is in use sleeping for .5",
51
+ ident,
52
+ eng.url,
53
+ template_db,
54
+ )
55
+ time.sleep(0.5)
56
+ except:
57
+ raise
58
+ else:
59
+ break
60
+
61
+
62
+ @drop_db.for_db("postgresql")
63
+ def _pg_drop_db(cfg, eng, ident):
64
+ with eng.connect().execution_options(isolation_level="AUTOCOMMIT") as conn:
65
+ with conn.begin():
66
+ conn.execute(
67
+ text(
68
+ "select pg_terminate_backend(pid) from pg_stat_activity "
69
+ "where usename=current_user and pid != pg_backend_pid() "
70
+ "and datname=:dname"
71
+ ),
72
+ dict(dname=ident),
73
+ )
74
+ conn.exec_driver_sql("DROP DATABASE %s" % ident)
75
+
76
+
77
+ @temp_table_keyword_args.for_db("postgresql")
78
+ def _postgresql_temp_table_keyword_args(cfg, eng):
79
+ return {"prefixes": ["TEMPORARY"]}
80
+
81
+
82
+ @set_default_schema_on_connection.for_db("postgresql")
83
+ def _postgresql_set_default_schema_on_connection(
84
+ cfg, dbapi_connection, schema_name
85
+ ):
86
+ existing_autocommit = dbapi_connection.autocommit
87
+ dbapi_connection.autocommit = True
88
+ cursor = dbapi_connection.cursor()
89
+ cursor.execute("SET SESSION search_path='%s'" % schema_name)
90
+ cursor.close()
91
+ dbapi_connection.autocommit = existing_autocommit
92
+
93
+
94
+ @drop_all_schema_objects_pre_tables.for_db("postgresql")
95
+ def drop_all_schema_objects_pre_tables(cfg, eng):
96
+ with eng.connect().execution_options(isolation_level="AUTOCOMMIT") as conn:
97
+ for xid in conn.exec_driver_sql(
98
+ "select gid from pg_prepared_xacts"
99
+ ).scalars():
100
+ conn.exec_driver_sql("ROLLBACK PREPARED '%s'" % xid)
101
+
102
+
103
+ @drop_all_schema_objects_post_tables.for_db("postgresql")
104
+ def drop_all_schema_objects_post_tables(cfg, eng):
105
+ from sqlalchemy.dialects import postgresql
106
+
107
+ inspector = inspect(eng)
108
+ with eng.begin() as conn:
109
+ for enum in inspector.get_enums("*"):
110
+ conn.execute(
111
+ postgresql.DropEnumType(
112
+ postgresql.ENUM(name=enum["name"], schema=enum["schema"])
113
+ )
114
+ )
115
+
116
+
117
+ @prepare_for_drop_tables.for_db("postgresql")
118
+ def prepare_for_drop_tables(config, connection):
119
+ """Ensure there are no locks on the current username/database."""
120
+
121
+ result = connection.exec_driver_sql(
122
+ "select pid, state, wait_event_type, query "
123
+ # "select pg_terminate_backend(pid), state, wait_event_type "
124
+ "from pg_stat_activity where "
125
+ "usename=current_user "
126
+ "and datname=current_database() and state='idle in transaction' "
127
+ "and pid != pg_backend_pid()"
128
+ )
129
+ rows = result.all() # noqa
130
+ if rows:
131
+ warn_test_suite(
132
+ "PostgreSQL may not be able to DROP tables due to "
133
+ "idle in transaction: %s"
134
+ % ("; ".join(row._mapping["query"] for row in rows))
135
+ )
136
+
137
+
138
+ @upsert.for_db("postgresql")
139
+ def _upsert(
140
+ cfg, table, returning, *, set_lambda=None, sort_by_parameter_order=False
141
+ ):
142
+ from sqlalchemy.dialects.postgresql import insert
143
+
144
+ stmt = insert(table)
145
+
146
+ table_pk = inspect(table).selectable
147
+
148
+ if set_lambda:
149
+ stmt = stmt.on_conflict_do_update(
150
+ index_elements=table_pk.primary_key, set_=set_lambda(stmt.excluded)
151
+ )
152
+ else:
153
+ stmt = stmt.on_conflict_do_nothing()
154
+
155
+ stmt = stmt.returning(
156
+ *returning, sort_by_parameter_order=sort_by_parameter_order
157
+ )
158
+ return stmt
159
+
160
+
161
+ _extensions = [
162
+ ("citext", (13,)),
163
+ ("hstore", (13,)),
164
+ ]
165
+
166
+
167
+ @post_configure_engine.for_db("postgresql")
168
+ def _create_citext_extension(url, engine, follower_ident):
169
+ with engine.connect() as conn:
170
+ for extension, min_version in _extensions:
171
+ if conn.dialect.server_version_info >= min_version:
172
+ conn.execute(
173
+ text(f"CREATE EXTENSION IF NOT EXISTS {extension}")
174
+ )
175
+ conn.commit()