SQLAlchemy 2.1.0rc1__cp315-cp315-win_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (276) hide show
  1. sqlalchemy/__init__.py +299 -0
  2. sqlalchemy/connectors/__init__.py +18 -0
  3. sqlalchemy/connectors/aioodbc.py +171 -0
  4. sqlalchemy/connectors/asyncio.py +476 -0
  5. sqlalchemy/connectors/pyodbc.py +248 -0
  6. sqlalchemy/dialects/__init__.py +62 -0
  7. sqlalchemy/dialects/_typing.py +29 -0
  8. sqlalchemy/dialects/mssql/__init__.py +88 -0
  9. sqlalchemy/dialects/mssql/aioodbc.py +63 -0
  10. sqlalchemy/dialects/mssql/base.py +4833 -0
  11. sqlalchemy/dialects/mssql/information_schema.py +345 -0
  12. sqlalchemy/dialects/mssql/json.py +140 -0
  13. sqlalchemy/dialects/mssql/mssqlpython.py +242 -0
  14. sqlalchemy/dialects/mssql/provision.py +196 -0
  15. sqlalchemy/dialects/mssql/pymssql.py +130 -0
  16. sqlalchemy/dialects/mssql/pyodbc.py +697 -0
  17. sqlalchemy/dialects/mysql/__init__.py +106 -0
  18. sqlalchemy/dialects/mysql/_mariadb_shim.py +312 -0
  19. sqlalchemy/dialects/mysql/aiomysql.py +260 -0
  20. sqlalchemy/dialects/mysql/asyncmy.py +241 -0
  21. sqlalchemy/dialects/mysql/base.py +3896 -0
  22. sqlalchemy/dialects/mysql/cymysql.py +107 -0
  23. sqlalchemy/dialects/mysql/dml.py +279 -0
  24. sqlalchemy/dialects/mysql/enumerated.py +277 -0
  25. sqlalchemy/dialects/mysql/expression.py +146 -0
  26. sqlalchemy/dialects/mysql/json.py +92 -0
  27. sqlalchemy/dialects/mysql/mariadb.py +67 -0
  28. sqlalchemy/dialects/mysql/mariadbconnector.py +314 -0
  29. sqlalchemy/dialects/mysql/mysqlconnector.py +291 -0
  30. sqlalchemy/dialects/mysql/mysqldb.py +318 -0
  31. sqlalchemy/dialects/mysql/provision.py +153 -0
  32. sqlalchemy/dialects/mysql/pymysql.py +188 -0
  33. sqlalchemy/dialects/mysql/pyodbc.py +157 -0
  34. sqlalchemy/dialects/mysql/reflection.py +724 -0
  35. sqlalchemy/dialects/mysql/reserved_words.py +570 -0
  36. sqlalchemy/dialects/mysql/types.py +845 -0
  37. sqlalchemy/dialects/oracle/__init__.py +85 -0
  38. sqlalchemy/dialects/oracle/base.py +3847 -0
  39. sqlalchemy/dialects/oracle/cx_oracle.py +1736 -0
  40. sqlalchemy/dialects/oracle/dictionary.py +507 -0
  41. sqlalchemy/dialects/oracle/json.py +157 -0
  42. sqlalchemy/dialects/oracle/oracledb.py +898 -0
  43. sqlalchemy/dialects/oracle/provision.py +288 -0
  44. sqlalchemy/dialects/oracle/types.py +367 -0
  45. sqlalchemy/dialects/oracle/vector.py +366 -0
  46. sqlalchemy/dialects/postgresql/__init__.py +170 -0
  47. sqlalchemy/dialects/postgresql/_psycopg_common.py +232 -0
  48. sqlalchemy/dialects/postgresql/array.py +534 -0
  49. sqlalchemy/dialects/postgresql/asyncpg.py +1318 -0
  50. sqlalchemy/dialects/postgresql/base.py +5935 -0
  51. sqlalchemy/dialects/postgresql/bitstring.py +327 -0
  52. sqlalchemy/dialects/postgresql/dml.py +360 -0
  53. sqlalchemy/dialects/postgresql/ext.py +599 -0
  54. sqlalchemy/dialects/postgresql/hstore.py +422 -0
  55. sqlalchemy/dialects/postgresql/json.py +411 -0
  56. sqlalchemy/dialects/postgresql/named_types.py +535 -0
  57. sqlalchemy/dialects/postgresql/operators.py +129 -0
  58. sqlalchemy/dialects/postgresql/pg8000.py +655 -0
  59. sqlalchemy/dialects/postgresql/pg_catalog.py +345 -0
  60. sqlalchemy/dialects/postgresql/provision.py +202 -0
  61. sqlalchemy/dialects/postgresql/psycopg.py +800 -0
  62. sqlalchemy/dialects/postgresql/psycopg2.py +860 -0
  63. sqlalchemy/dialects/postgresql/psycopg2cffi.py +62 -0
  64. sqlalchemy/dialects/postgresql/ranges.py +1002 -0
  65. sqlalchemy/dialects/postgresql/types.py +388 -0
  66. sqlalchemy/dialects/sqlite/__init__.py +59 -0
  67. sqlalchemy/dialects/sqlite/aiosqlite.py +375 -0
  68. sqlalchemy/dialects/sqlite/base.py +3103 -0
  69. sqlalchemy/dialects/sqlite/dml.py +314 -0
  70. sqlalchemy/dialects/sqlite/json.py +134 -0
  71. sqlalchemy/dialects/sqlite/provision.py +237 -0
  72. sqlalchemy/dialects/sqlite/pysqlcipher.py +166 -0
  73. sqlalchemy/dialects/sqlite/pysqlite.py +959 -0
  74. sqlalchemy/dialects/type_migration_guidelines.txt +145 -0
  75. sqlalchemy/engine/__init__.py +62 -0
  76. sqlalchemy/engine/_processors_cy.cp315-win_arm64.pyd +0 -0
  77. sqlalchemy/engine/_processors_cy.py +92 -0
  78. sqlalchemy/engine/_result_cy.cp315-win_arm64.pyd +0 -0
  79. sqlalchemy/engine/_result_cy.py +711 -0
  80. sqlalchemy/engine/_row_cy.cp315-win_arm64.pyd +0 -0
  81. sqlalchemy/engine/_row_cy.py +232 -0
  82. sqlalchemy/engine/_util_cy.cp315-win_arm64.pyd +0 -0
  83. sqlalchemy/engine/_util_cy.py +136 -0
  84. sqlalchemy/engine/base.py +3357 -0
  85. sqlalchemy/engine/characteristics.py +155 -0
  86. sqlalchemy/engine/create.py +877 -0
  87. sqlalchemy/engine/cursor.py +2425 -0
  88. sqlalchemy/engine/default.py +2627 -0
  89. sqlalchemy/engine/events.py +965 -0
  90. sqlalchemy/engine/interfaces.py +3636 -0
  91. sqlalchemy/engine/mock.py +133 -0
  92. sqlalchemy/engine/processors.py +83 -0
  93. sqlalchemy/engine/reflection.py +2141 -0
  94. sqlalchemy/engine/result.py +2012 -0
  95. sqlalchemy/engine/row.py +397 -0
  96. sqlalchemy/engine/strategies.py +16 -0
  97. sqlalchemy/engine/url.py +922 -0
  98. sqlalchemy/engine/util.py +164 -0
  99. sqlalchemy/event/__init__.py +26 -0
  100. sqlalchemy/event/api.py +220 -0
  101. sqlalchemy/event/attr.py +675 -0
  102. sqlalchemy/event/base.py +473 -0
  103. sqlalchemy/event/legacy.py +259 -0
  104. sqlalchemy/event/registry.py +391 -0
  105. sqlalchemy/events.py +17 -0
  106. sqlalchemy/exc.py +939 -0
  107. sqlalchemy/ext/__init__.py +10 -0
  108. sqlalchemy/ext/associationproxy.py +2073 -0
  109. sqlalchemy/ext/asyncio/__init__.py +29 -0
  110. sqlalchemy/ext/asyncio/base.py +281 -0
  111. sqlalchemy/ext/asyncio/engine.py +1487 -0
  112. sqlalchemy/ext/asyncio/exc.py +21 -0
  113. sqlalchemy/ext/asyncio/result.py +994 -0
  114. sqlalchemy/ext/asyncio/scoping.py +1679 -0
  115. sqlalchemy/ext/asyncio/session.py +2006 -0
  116. sqlalchemy/ext/automap.py +1702 -0
  117. sqlalchemy/ext/baked.py +558 -0
  118. sqlalchemy/ext/compiler.py +601 -0
  119. sqlalchemy/ext/declarative/__init__.py +65 -0
  120. sqlalchemy/ext/declarative/extensions.py +561 -0
  121. sqlalchemy/ext/horizontal_shard.py +481 -0
  122. sqlalchemy/ext/hybrid.py +1877 -0
  123. sqlalchemy/ext/indexable.py +364 -0
  124. sqlalchemy/ext/instrumentation.py +450 -0
  125. sqlalchemy/ext/mutable.py +1081 -0
  126. sqlalchemy/ext/orderinglist.py +440 -0
  127. sqlalchemy/ext/serializer.py +184 -0
  128. sqlalchemy/future/__init__.py +17 -0
  129. sqlalchemy/future/engine.py +15 -0
  130. sqlalchemy/inspection.py +188 -0
  131. sqlalchemy/log.py +279 -0
  132. sqlalchemy/orm/__init__.py +176 -0
  133. sqlalchemy/orm/_orm_constructors.py +2694 -0
  134. sqlalchemy/orm/_typing.py +180 -0
  135. sqlalchemy/orm/attributes.py +2868 -0
  136. sqlalchemy/orm/base.py +991 -0
  137. sqlalchemy/orm/bulk_persistence.py +2168 -0
  138. sqlalchemy/orm/clsregistry.py +630 -0
  139. sqlalchemy/orm/collections.py +1569 -0
  140. sqlalchemy/orm/context.py +3475 -0
  141. sqlalchemy/orm/decl_api.py +2283 -0
  142. sqlalchemy/orm/decl_base.py +2320 -0
  143. sqlalchemy/orm/dependency.py +1306 -0
  144. sqlalchemy/orm/descriptor_props.py +1183 -0
  145. sqlalchemy/orm/dynamic.py +306 -0
  146. sqlalchemy/orm/evaluator.py +378 -0
  147. sqlalchemy/orm/events.py +3387 -0
  148. sqlalchemy/orm/exc.py +237 -0
  149. sqlalchemy/orm/identity.py +302 -0
  150. sqlalchemy/orm/instrumentation.py +749 -0
  151. sqlalchemy/orm/interfaces.py +1595 -0
  152. sqlalchemy/orm/loading.py +1712 -0
  153. sqlalchemy/orm/mapped_collection.py +557 -0
  154. sqlalchemy/orm/mapper.py +4465 -0
  155. sqlalchemy/orm/path_registry.py +907 -0
  156. sqlalchemy/orm/persistence.py +1790 -0
  157. sqlalchemy/orm/properties.py +972 -0
  158. sqlalchemy/orm/query.py +3528 -0
  159. sqlalchemy/orm/relationships.py +3608 -0
  160. sqlalchemy/orm/scoping.py +2233 -0
  161. sqlalchemy/orm/session.py +5468 -0
  162. sqlalchemy/orm/state.py +1175 -0
  163. sqlalchemy/orm/state_changes.py +196 -0
  164. sqlalchemy/orm/strategies.py +3552 -0
  165. sqlalchemy/orm/strategy_options.py +2648 -0
  166. sqlalchemy/orm/sync.py +164 -0
  167. sqlalchemy/orm/unitofwork.py +797 -0
  168. sqlalchemy/orm/util.py +2461 -0
  169. sqlalchemy/orm/writeonly.py +701 -0
  170. sqlalchemy/pool/__init__.py +41 -0
  171. sqlalchemy/pool/base.py +1540 -0
  172. sqlalchemy/pool/events.py +375 -0
  173. sqlalchemy/pool/impl.py +583 -0
  174. sqlalchemy/py.typed +0 -0
  175. sqlalchemy/schema.py +75 -0
  176. sqlalchemy/sql/__init__.py +156 -0
  177. sqlalchemy/sql/_annotated_cols.py +402 -0
  178. sqlalchemy/sql/_cache_key_cy.cp315-win_arm64.pyd +0 -0
  179. sqlalchemy/sql/_cache_key_cy.py +363 -0
  180. sqlalchemy/sql/_dml_constructors.py +132 -0
  181. sqlalchemy/sql/_elements_constructors.py +2190 -0
  182. sqlalchemy/sql/_orm_types.py +19 -0
  183. sqlalchemy/sql/_selectable_constructors.py +840 -0
  184. sqlalchemy/sql/_typing.py +500 -0
  185. sqlalchemy/sql/_util_cy.cp315-win_arm64.pyd +0 -0
  186. sqlalchemy/sql/_util_cy.pxd +11 -0
  187. sqlalchemy/sql/_util_cy.py +127 -0
  188. sqlalchemy/sql/annotation.py +590 -0
  189. sqlalchemy/sql/base.py +2702 -0
  190. sqlalchemy/sql/cache_key.py +915 -0
  191. sqlalchemy/sql/coercions.py +1373 -0
  192. sqlalchemy/sql/compiler.py +8453 -0
  193. sqlalchemy/sql/crud.py +1816 -0
  194. sqlalchemy/sql/ddl.py +1962 -0
  195. sqlalchemy/sql/default_comparator.py +660 -0
  196. sqlalchemy/sql/dml.py +2018 -0
  197. sqlalchemy/sql/elements.py +6057 -0
  198. sqlalchemy/sql/events.py +458 -0
  199. sqlalchemy/sql/expression.py +171 -0
  200. sqlalchemy/sql/functions.py +2380 -0
  201. sqlalchemy/sql/lambdas.py +1442 -0
  202. sqlalchemy/sql/naming.py +204 -0
  203. sqlalchemy/sql/operators.py +2909 -0
  204. sqlalchemy/sql/roles.py +332 -0
  205. sqlalchemy/sql/schema.py +7075 -0
  206. sqlalchemy/sql/selectable.py +7634 -0
  207. sqlalchemy/sql/sqltypes.py +4130 -0
  208. sqlalchemy/sql/traversals.py +1041 -0
  209. sqlalchemy/sql/type_api.py +2450 -0
  210. sqlalchemy/sql/util.py +1496 -0
  211. sqlalchemy/sql/visitors.py +1153 -0
  212. sqlalchemy/testing/__init__.py +97 -0
  213. sqlalchemy/testing/assertions.py +1007 -0
  214. sqlalchemy/testing/assertsql.py +519 -0
  215. sqlalchemy/testing/asyncio.py +128 -0
  216. sqlalchemy/testing/cancellation.py +237 -0
  217. sqlalchemy/testing/config.py +440 -0
  218. sqlalchemy/testing/engines.py +482 -0
  219. sqlalchemy/testing/entities.py +117 -0
  220. sqlalchemy/testing/exclusions.py +501 -0
  221. sqlalchemy/testing/fixtures/__init__.py +30 -0
  222. sqlalchemy/testing/fixtures/base.py +426 -0
  223. sqlalchemy/testing/fixtures/mypy.py +247 -0
  224. sqlalchemy/testing/fixtures/orm.py +227 -0
  225. sqlalchemy/testing/fixtures/sql.py +538 -0
  226. sqlalchemy/testing/pickleable.py +155 -0
  227. sqlalchemy/testing/plugin/__init__.py +6 -0
  228. sqlalchemy/testing/plugin/bootstrap.py +50 -0
  229. sqlalchemy/testing/plugin/plugin_base.py +828 -0
  230. sqlalchemy/testing/plugin/pytestplugin.py +896 -0
  231. sqlalchemy/testing/profiles_file.py +350 -0
  232. sqlalchemy/testing/profiling.py +294 -0
  233. sqlalchemy/testing/provision.py +633 -0
  234. sqlalchemy/testing/requirements.py +1971 -0
  235. sqlalchemy/testing/schema.py +198 -0
  236. sqlalchemy/testing/suite/__init__.py +19 -0
  237. sqlalchemy/testing/suite/test_cte.py +237 -0
  238. sqlalchemy/testing/suite/test_ddl.py +420 -0
  239. sqlalchemy/testing/suite/test_dialect.py +776 -0
  240. sqlalchemy/testing/suite/test_insert.py +630 -0
  241. sqlalchemy/testing/suite/test_reflection.py +3815 -0
  242. sqlalchemy/testing/suite/test_results.py +660 -0
  243. sqlalchemy/testing/suite/test_rowcount.py +258 -0
  244. sqlalchemy/testing/suite/test_select.py +2112 -0
  245. sqlalchemy/testing/suite/test_sequence.py +317 -0
  246. sqlalchemy/testing/suite/test_table_via_select.py +686 -0
  247. sqlalchemy/testing/suite/test_types.py +2271 -0
  248. sqlalchemy/testing/suite/test_unicode_ddl.py +189 -0
  249. sqlalchemy/testing/suite/test_update_delete.py +139 -0
  250. sqlalchemy/testing/util.py +575 -0
  251. sqlalchemy/testing/warnings.py +52 -0
  252. sqlalchemy/types.py +75 -0
  253. sqlalchemy/util/__init__.py +165 -0
  254. sqlalchemy/util/_collections.py +688 -0
  255. sqlalchemy/util/_collections_cy.cp315-win_arm64.pyd +0 -0
  256. sqlalchemy/util/_collections_cy.pxd +8 -0
  257. sqlalchemy/util/_collections_cy.py +516 -0
  258. sqlalchemy/util/_has_cython.py +48 -0
  259. sqlalchemy/util/_immutabledict_cy.cp315-win_arm64.pyd +0 -0
  260. sqlalchemy/util/_immutabledict_cy.py +240 -0
  261. sqlalchemy/util/compat.py +298 -0
  262. sqlalchemy/util/concurrency.py +272 -0
  263. sqlalchemy/util/cython.py +95 -0
  264. sqlalchemy/util/deprecations.py +401 -0
  265. sqlalchemy/util/langhelpers.py +2797 -0
  266. sqlalchemy/util/preloaded.py +153 -0
  267. sqlalchemy/util/queue.py +304 -0
  268. sqlalchemy/util/tool_support.py +202 -0
  269. sqlalchemy/util/topological.py +120 -0
  270. sqlalchemy/util/typing.py +709 -0
  271. sqlalchemy-2.1.0rc1.dist-info/METADATA +270 -0
  272. sqlalchemy-2.1.0rc1.dist-info/RECORD +276 -0
  273. sqlalchemy-2.1.0rc1.dist-info/WHEEL +5 -0
  274. sqlalchemy-2.1.0rc1.dist-info/licenses/AUTHORS +30 -0
  275. sqlalchemy-2.1.0rc1.dist-info/licenses/LICENSE +19 -0
  276. sqlalchemy-2.1.0rc1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,507 @@
1
+ # dialects/oracle/dictionary.py
2
+ # Copyright (C) 2005-2026 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 .types import DATE
10
+ from .types import LONG
11
+ from .types import NUMBER
12
+ from .types import RAW
13
+ from .types import VARCHAR2
14
+ from ... import Column
15
+ from ... import MetaData
16
+ from ... import Table
17
+ from ... import table
18
+ from ...sql.sqltypes import CHAR
19
+
20
+ # constants
21
+ DB_LINK_PLACEHOLDER = "__$sa_dblink$__"
22
+ # tables
23
+ dual = table("dual")
24
+ dictionary_meta = MetaData()
25
+
26
+ # NOTE: all the dictionary_meta are aliases because oracle does not like
27
+ # using the full table@dblink for every column in query, and complains with
28
+ # ORA-00960: ambiguous column naming in select list
29
+ all_tables = Table(
30
+ "all_tables" + DB_LINK_PLACEHOLDER,
31
+ dictionary_meta,
32
+ Column("owner", VARCHAR2(128), nullable=False),
33
+ Column("table_name", VARCHAR2(128), nullable=False),
34
+ Column("tablespace_name", VARCHAR2(30)),
35
+ Column("cluster_name", VARCHAR2(128)),
36
+ Column("iot_name", VARCHAR2(128)),
37
+ Column("status", VARCHAR2(8)),
38
+ Column("pct_free", NUMBER),
39
+ Column("pct_used", NUMBER),
40
+ Column("ini_trans", NUMBER),
41
+ Column("max_trans", NUMBER),
42
+ Column("initial_extent", NUMBER),
43
+ Column("next_extent", NUMBER),
44
+ Column("min_extents", NUMBER),
45
+ Column("max_extents", NUMBER),
46
+ Column("pct_increase", NUMBER),
47
+ Column("freelists", NUMBER),
48
+ Column("freelist_groups", NUMBER),
49
+ Column("logging", VARCHAR2(3)),
50
+ Column("backed_up", VARCHAR2(1)),
51
+ Column("num_rows", NUMBER),
52
+ Column("blocks", NUMBER),
53
+ Column("empty_blocks", NUMBER),
54
+ Column("avg_space", NUMBER),
55
+ Column("chain_cnt", NUMBER),
56
+ Column("avg_row_len", NUMBER),
57
+ Column("avg_space_freelist_blocks", NUMBER),
58
+ Column("num_freelist_blocks", NUMBER),
59
+ Column("degree", VARCHAR2(10)),
60
+ Column("instances", VARCHAR2(10)),
61
+ Column("cache", VARCHAR2(5)),
62
+ Column("table_lock", VARCHAR2(8)),
63
+ Column("sample_size", NUMBER),
64
+ Column("last_analyzed", DATE),
65
+ Column("partitioned", VARCHAR2(3)),
66
+ Column("iot_type", VARCHAR2(12)),
67
+ Column("temporary", VARCHAR2(1)),
68
+ Column("secondary", VARCHAR2(1)),
69
+ Column("nested", VARCHAR2(3)),
70
+ Column("buffer_pool", VARCHAR2(7)),
71
+ Column("flash_cache", VARCHAR2(7)),
72
+ Column("cell_flash_cache", VARCHAR2(7)),
73
+ Column("row_movement", VARCHAR2(8)),
74
+ Column("global_stats", VARCHAR2(3)),
75
+ Column("user_stats", VARCHAR2(3)),
76
+ Column("duration", VARCHAR2(15)),
77
+ Column("skip_corrupt", VARCHAR2(8)),
78
+ Column("monitoring", VARCHAR2(3)),
79
+ Column("cluster_owner", VARCHAR2(128)),
80
+ Column("dependencies", VARCHAR2(8)),
81
+ Column("compression", VARCHAR2(8)),
82
+ Column("compress_for", VARCHAR2(30)),
83
+ Column("dropped", VARCHAR2(3)),
84
+ Column("read_only", VARCHAR2(3)),
85
+ Column("segment_created", VARCHAR2(3)),
86
+ Column("result_cache", VARCHAR2(7)),
87
+ Column("clustering", VARCHAR2(3)),
88
+ Column("activity_tracking", VARCHAR2(23)),
89
+ Column("dml_timestamp", VARCHAR2(25)),
90
+ Column("has_identity", VARCHAR2(3)),
91
+ Column("container_data", VARCHAR2(3)),
92
+ Column("inmemory", VARCHAR2(8)),
93
+ Column("inmemory_priority", VARCHAR2(8)),
94
+ Column("inmemory_distribute", VARCHAR2(15)),
95
+ Column("inmemory_compression", VARCHAR2(17)),
96
+ Column("inmemory_duplicate", VARCHAR2(13)),
97
+ Column("default_collation", VARCHAR2(100)),
98
+ Column("duplicated", VARCHAR2(1)),
99
+ Column("sharded", VARCHAR2(1)),
100
+ Column("externally_sharded", VARCHAR2(1)),
101
+ Column("externally_duplicated", VARCHAR2(1)),
102
+ Column("external", VARCHAR2(3)),
103
+ Column("hybrid", VARCHAR2(3)),
104
+ Column("cellmemory", VARCHAR2(24)),
105
+ Column("containers_default", VARCHAR2(3)),
106
+ Column("container_map", VARCHAR2(3)),
107
+ Column("extended_data_link", VARCHAR2(3)),
108
+ Column("extended_data_link_map", VARCHAR2(3)),
109
+ Column("inmemory_service", VARCHAR2(12)),
110
+ Column("inmemory_service_name", VARCHAR2(1000)),
111
+ Column("container_map_object", VARCHAR2(3)),
112
+ Column("memoptimize_read", VARCHAR2(8)),
113
+ Column("memoptimize_write", VARCHAR2(8)),
114
+ Column("has_sensitive_column", VARCHAR2(3)),
115
+ Column("admit_null", VARCHAR2(3)),
116
+ Column("data_link_dml_enabled", VARCHAR2(3)),
117
+ Column("logical_replication", VARCHAR2(8)),
118
+ ).alias("a_tables")
119
+
120
+ all_views = Table(
121
+ "all_views" + DB_LINK_PLACEHOLDER,
122
+ dictionary_meta,
123
+ Column("owner", VARCHAR2(128), nullable=False),
124
+ Column("view_name", VARCHAR2(128), nullable=False),
125
+ Column("text_length", NUMBER),
126
+ Column("text", LONG),
127
+ Column("text_vc", VARCHAR2(4000)),
128
+ Column("type_text_length", NUMBER),
129
+ Column("type_text", VARCHAR2(4000)),
130
+ Column("oid_text_length", NUMBER),
131
+ Column("oid_text", VARCHAR2(4000)),
132
+ Column("view_type_owner", VARCHAR2(128)),
133
+ Column("view_type", VARCHAR2(128)),
134
+ Column("superview_name", VARCHAR2(128)),
135
+ Column("editioning_view", VARCHAR2(1)),
136
+ Column("read_only", VARCHAR2(1)),
137
+ Column("container_data", VARCHAR2(1)),
138
+ Column("bequeath", VARCHAR2(12)),
139
+ Column("origin_con_id", VARCHAR2(256)),
140
+ Column("default_collation", VARCHAR2(100)),
141
+ Column("containers_default", VARCHAR2(3)),
142
+ Column("container_map", VARCHAR2(3)),
143
+ Column("extended_data_link", VARCHAR2(3)),
144
+ Column("extended_data_link_map", VARCHAR2(3)),
145
+ Column("has_sensitive_column", VARCHAR2(3)),
146
+ Column("admit_null", VARCHAR2(3)),
147
+ Column("pdb_local_only", VARCHAR2(3)),
148
+ ).alias("a_views")
149
+
150
+ all_sequences = Table(
151
+ "all_sequences" + DB_LINK_PLACEHOLDER,
152
+ dictionary_meta,
153
+ Column("sequence_owner", VARCHAR2(128), nullable=False),
154
+ Column("sequence_name", VARCHAR2(128), nullable=False),
155
+ Column("min_value", NUMBER),
156
+ Column("max_value", NUMBER),
157
+ Column("increment_by", NUMBER, nullable=False),
158
+ Column("cycle_flag", VARCHAR2(1)),
159
+ Column("order_flag", VARCHAR2(1)),
160
+ Column("cache_size", NUMBER, nullable=False),
161
+ Column("last_number", NUMBER, nullable=False),
162
+ Column("scale_flag", VARCHAR2(1)),
163
+ Column("extend_flag", VARCHAR2(1)),
164
+ Column("sharded_flag", VARCHAR2(1)),
165
+ Column("session_flag", VARCHAR2(1)),
166
+ Column("keep_value", VARCHAR2(1)),
167
+ ).alias("a_sequences")
168
+
169
+ all_users = Table(
170
+ "all_users" + DB_LINK_PLACEHOLDER,
171
+ dictionary_meta,
172
+ Column("username", VARCHAR2(128), nullable=False),
173
+ Column("user_id", NUMBER, nullable=False),
174
+ Column("created", DATE, nullable=False),
175
+ Column("common", VARCHAR2(3)),
176
+ Column("oracle_maintained", VARCHAR2(1)),
177
+ Column("inherited", VARCHAR2(3)),
178
+ Column("default_collation", VARCHAR2(100)),
179
+ Column("implicit", VARCHAR2(3)),
180
+ Column("all_shard", VARCHAR2(3)),
181
+ Column("external_shard", VARCHAR2(3)),
182
+ ).alias("a_users")
183
+
184
+ all_mviews = Table(
185
+ "all_mviews" + DB_LINK_PLACEHOLDER,
186
+ dictionary_meta,
187
+ Column("owner", VARCHAR2(128), nullable=False),
188
+ Column("mview_name", VARCHAR2(128), nullable=False),
189
+ Column("container_name", VARCHAR2(128), nullable=False),
190
+ Column("query", LONG),
191
+ Column("query_len", NUMBER(38)),
192
+ Column("updatable", VARCHAR2(1)),
193
+ Column("update_log", VARCHAR2(128)),
194
+ Column("master_rollback_seg", VARCHAR2(128)),
195
+ Column("master_link", VARCHAR2(128)),
196
+ Column("rewrite_enabled", VARCHAR2(1)),
197
+ Column("rewrite_capability", VARCHAR2(9)),
198
+ Column("refresh_mode", VARCHAR2(6)),
199
+ Column("refresh_method", VARCHAR2(8)),
200
+ Column("build_mode", VARCHAR2(9)),
201
+ Column("fast_refreshable", VARCHAR2(18)),
202
+ Column("last_refresh_type", VARCHAR2(8)),
203
+ Column("last_refresh_date", DATE),
204
+ Column("last_refresh_end_time", DATE),
205
+ Column("staleness", VARCHAR2(19)),
206
+ Column("after_fast_refresh", VARCHAR2(19)),
207
+ Column("unknown_prebuilt", VARCHAR2(1)),
208
+ Column("unknown_plsql_func", VARCHAR2(1)),
209
+ Column("unknown_external_table", VARCHAR2(1)),
210
+ Column("unknown_consider_fresh", VARCHAR2(1)),
211
+ Column("unknown_import", VARCHAR2(1)),
212
+ Column("unknown_trusted_fd", VARCHAR2(1)),
213
+ Column("compile_state", VARCHAR2(19)),
214
+ Column("use_no_index", VARCHAR2(1)),
215
+ Column("stale_since", DATE),
216
+ Column("num_pct_tables", NUMBER),
217
+ Column("num_fresh_pct_regions", NUMBER),
218
+ Column("num_stale_pct_regions", NUMBER),
219
+ Column("segment_created", VARCHAR2(3)),
220
+ Column("evaluation_edition", VARCHAR2(128)),
221
+ Column("unusable_before", VARCHAR2(128)),
222
+ Column("unusable_beginning", VARCHAR2(128)),
223
+ Column("default_collation", VARCHAR2(100)),
224
+ Column("on_query_computation", VARCHAR2(1)),
225
+ Column("auto", VARCHAR2(3)),
226
+ ).alias("a_mviews")
227
+
228
+ all_tab_identity_cols = Table(
229
+ "all_tab_identity_cols" + DB_LINK_PLACEHOLDER,
230
+ dictionary_meta,
231
+ Column("owner", VARCHAR2(128), nullable=False),
232
+ Column("table_name", VARCHAR2(128), nullable=False),
233
+ Column("column_name", VARCHAR2(128), nullable=False),
234
+ Column("generation_type", VARCHAR2(10)),
235
+ Column("sequence_name", VARCHAR2(128), nullable=False),
236
+ Column("identity_options", VARCHAR2(298)),
237
+ ).alias("a_tab_identity_cols")
238
+
239
+ all_tab_cols = Table(
240
+ "all_tab_cols" + DB_LINK_PLACEHOLDER,
241
+ dictionary_meta,
242
+ Column("owner", VARCHAR2(128), nullable=False),
243
+ Column("table_name", VARCHAR2(128), nullable=False),
244
+ Column("column_name", VARCHAR2(128), nullable=False),
245
+ Column("data_type", VARCHAR2(128)),
246
+ Column("data_type_mod", VARCHAR2(3)),
247
+ Column("data_type_owner", VARCHAR2(128)),
248
+ Column("data_length", NUMBER, nullable=False),
249
+ Column("data_precision", NUMBER),
250
+ Column("data_scale", NUMBER),
251
+ Column("nullable", VARCHAR2(1)),
252
+ Column("column_id", NUMBER),
253
+ Column("default_length", NUMBER),
254
+ Column("data_default", LONG),
255
+ Column("num_distinct", NUMBER),
256
+ Column("low_value", RAW(1000)),
257
+ Column("high_value", RAW(1000)),
258
+ Column("density", NUMBER),
259
+ Column("num_nulls", NUMBER),
260
+ Column("num_buckets", NUMBER),
261
+ Column("last_analyzed", DATE),
262
+ Column("sample_size", NUMBER),
263
+ Column("character_set_name", VARCHAR2(44)),
264
+ Column("char_col_decl_length", NUMBER),
265
+ Column("global_stats", VARCHAR2(3)),
266
+ Column("user_stats", VARCHAR2(3)),
267
+ Column("avg_col_len", NUMBER),
268
+ Column("char_length", NUMBER),
269
+ Column("char_used", VARCHAR2(1)),
270
+ Column("v80_fmt_image", VARCHAR2(3)),
271
+ Column("data_upgraded", VARCHAR2(3)),
272
+ Column("hidden_column", VARCHAR2(3)),
273
+ Column("virtual_column", VARCHAR2(3)),
274
+ Column("segment_column_id", NUMBER),
275
+ Column("internal_column_id", NUMBER, nullable=False),
276
+ Column("histogram", VARCHAR2(15)),
277
+ Column("qualified_col_name", VARCHAR2(4000)),
278
+ Column("user_generated", VARCHAR2(3)),
279
+ Column("default_on_null", VARCHAR2(3)),
280
+ Column("identity_column", VARCHAR2(3)),
281
+ Column("evaluation_edition", VARCHAR2(128)),
282
+ Column("unusable_before", VARCHAR2(128)),
283
+ Column("unusable_beginning", VARCHAR2(128)),
284
+ Column("collation", VARCHAR2(100)),
285
+ Column("collated_column_id", NUMBER),
286
+ ).alias("a_tab_cols")
287
+
288
+ all_tab_comments = Table(
289
+ "all_tab_comments" + DB_LINK_PLACEHOLDER,
290
+ dictionary_meta,
291
+ Column("owner", VARCHAR2(128), nullable=False),
292
+ Column("table_name", VARCHAR2(128), nullable=False),
293
+ Column("table_type", VARCHAR2(11)),
294
+ Column("comments", VARCHAR2(4000)),
295
+ Column("origin_con_id", NUMBER),
296
+ ).alias("a_tab_comments")
297
+
298
+ all_col_comments = Table(
299
+ "all_col_comments" + DB_LINK_PLACEHOLDER,
300
+ dictionary_meta,
301
+ Column("owner", VARCHAR2(128), nullable=False),
302
+ Column("table_name", VARCHAR2(128), nullable=False),
303
+ Column("column_name", VARCHAR2(128), nullable=False),
304
+ Column("comments", VARCHAR2(4000)),
305
+ Column("origin_con_id", NUMBER),
306
+ ).alias("a_col_comments")
307
+
308
+ all_mview_comments = Table(
309
+ "all_mview_comments" + DB_LINK_PLACEHOLDER,
310
+ dictionary_meta,
311
+ Column("owner", VARCHAR2(128), nullable=False),
312
+ Column("mview_name", VARCHAR2(128), nullable=False),
313
+ Column("comments", VARCHAR2(4000)),
314
+ ).alias("a_mview_comments")
315
+
316
+ all_ind_columns = Table(
317
+ "all_ind_columns" + DB_LINK_PLACEHOLDER,
318
+ dictionary_meta,
319
+ Column("index_owner", VARCHAR2(128), nullable=False),
320
+ Column("index_name", VARCHAR2(128), nullable=False),
321
+ Column("table_owner", VARCHAR2(128), nullable=False),
322
+ Column("table_name", VARCHAR2(128), nullable=False),
323
+ Column("column_name", VARCHAR2(4000)),
324
+ Column("column_position", NUMBER, nullable=False),
325
+ Column("column_length", NUMBER, nullable=False),
326
+ Column("char_length", NUMBER),
327
+ Column("descend", VARCHAR2(4)),
328
+ Column("collated_column_id", NUMBER),
329
+ ).alias("a_ind_columns")
330
+
331
+ all_indexes = Table(
332
+ "all_indexes" + DB_LINK_PLACEHOLDER,
333
+ dictionary_meta,
334
+ Column("owner", VARCHAR2(128), nullable=False),
335
+ Column("index_name", VARCHAR2(128), nullable=False),
336
+ Column("index_type", VARCHAR2(27)),
337
+ Column("table_owner", VARCHAR2(128), nullable=False),
338
+ Column("table_name", VARCHAR2(128), nullable=False),
339
+ Column("table_type", CHAR(11)),
340
+ Column("uniqueness", VARCHAR2(9)),
341
+ Column("compression", VARCHAR2(13)),
342
+ Column("prefix_length", NUMBER),
343
+ Column("tablespace_name", VARCHAR2(30)),
344
+ Column("ini_trans", NUMBER),
345
+ Column("max_trans", NUMBER),
346
+ Column("initial_extent", NUMBER),
347
+ Column("next_extent", NUMBER),
348
+ Column("min_extents", NUMBER),
349
+ Column("max_extents", NUMBER),
350
+ Column("pct_increase", NUMBER),
351
+ Column("pct_threshold", NUMBER),
352
+ Column("include_column", NUMBER),
353
+ Column("freelists", NUMBER),
354
+ Column("freelist_groups", NUMBER),
355
+ Column("pct_free", NUMBER),
356
+ Column("logging", VARCHAR2(3)),
357
+ Column("blevel", NUMBER),
358
+ Column("leaf_blocks", NUMBER),
359
+ Column("distinct_keys", NUMBER),
360
+ Column("avg_leaf_blocks_per_key", NUMBER),
361
+ Column("avg_data_blocks_per_key", NUMBER),
362
+ Column("clustering_factor", NUMBER),
363
+ Column("status", VARCHAR2(8)),
364
+ Column("num_rows", NUMBER),
365
+ Column("sample_size", NUMBER),
366
+ Column("last_analyzed", DATE),
367
+ Column("degree", VARCHAR2(40)),
368
+ Column("instances", VARCHAR2(40)),
369
+ Column("partitioned", VARCHAR2(3)),
370
+ Column("temporary", VARCHAR2(1)),
371
+ Column("generated", VARCHAR2(1)),
372
+ Column("secondary", VARCHAR2(1)),
373
+ Column("buffer_pool", VARCHAR2(7)),
374
+ Column("flash_cache", VARCHAR2(7)),
375
+ Column("cell_flash_cache", VARCHAR2(7)),
376
+ Column("user_stats", VARCHAR2(3)),
377
+ Column("duration", VARCHAR2(15)),
378
+ Column("pct_direct_access", NUMBER),
379
+ Column("ityp_owner", VARCHAR2(128)),
380
+ Column("ityp_name", VARCHAR2(128)),
381
+ Column("parameters", VARCHAR2(1000)),
382
+ Column("global_stats", VARCHAR2(3)),
383
+ Column("domidx_status", VARCHAR2(12)),
384
+ Column("domidx_opstatus", VARCHAR2(6)),
385
+ Column("funcidx_status", VARCHAR2(8)),
386
+ Column("join_index", VARCHAR2(3)),
387
+ Column("iot_redundant_pkey_elim", VARCHAR2(3)),
388
+ Column("dropped", VARCHAR2(3)),
389
+ Column("visibility", VARCHAR2(9)),
390
+ Column("domidx_management", VARCHAR2(14)),
391
+ Column("segment_created", VARCHAR2(3)),
392
+ Column("orphaned_entries", VARCHAR2(3)),
393
+ Column("indexing", VARCHAR2(7)),
394
+ Column("auto", VARCHAR2(3)),
395
+ ).alias("a_indexes")
396
+
397
+ all_ind_expressions = Table(
398
+ "all_ind_expressions" + DB_LINK_PLACEHOLDER,
399
+ dictionary_meta,
400
+ Column("index_owner", VARCHAR2(128), nullable=False),
401
+ Column("index_name", VARCHAR2(128), nullable=False),
402
+ Column("table_owner", VARCHAR2(128), nullable=False),
403
+ Column("table_name", VARCHAR2(128), nullable=False),
404
+ Column("column_expression", LONG),
405
+ Column("column_position", NUMBER, nullable=False),
406
+ ).alias("a_ind_expressions")
407
+
408
+ all_constraints = Table(
409
+ "all_constraints" + DB_LINK_PLACEHOLDER,
410
+ dictionary_meta,
411
+ Column("owner", VARCHAR2(128)),
412
+ Column("constraint_name", VARCHAR2(128)),
413
+ Column("constraint_type", VARCHAR2(1)),
414
+ Column("table_name", VARCHAR2(128)),
415
+ Column("search_condition", LONG),
416
+ Column("search_condition_vc", VARCHAR2(4000)),
417
+ Column("r_owner", VARCHAR2(128)),
418
+ Column("r_constraint_name", VARCHAR2(128)),
419
+ Column("delete_rule", VARCHAR2(9)),
420
+ Column("status", VARCHAR2(8)),
421
+ Column("deferrable", VARCHAR2(14)),
422
+ Column("deferred", VARCHAR2(9)),
423
+ Column("validated", VARCHAR2(13)),
424
+ Column("generated", VARCHAR2(14)),
425
+ Column("bad", VARCHAR2(3)),
426
+ Column("rely", VARCHAR2(4)),
427
+ Column("last_change", DATE),
428
+ Column("index_owner", VARCHAR2(128)),
429
+ Column("index_name", VARCHAR2(128)),
430
+ Column("invalid", VARCHAR2(7)),
431
+ Column("view_related", VARCHAR2(14)),
432
+ Column("origin_con_id", VARCHAR2(256)),
433
+ ).alias("a_constraints")
434
+
435
+ all_cons_columns = Table(
436
+ "all_cons_columns" + DB_LINK_PLACEHOLDER,
437
+ dictionary_meta,
438
+ Column("owner", VARCHAR2(128), nullable=False),
439
+ Column("constraint_name", VARCHAR2(128), nullable=False),
440
+ Column("table_name", VARCHAR2(128), nullable=False),
441
+ Column("column_name", VARCHAR2(4000)),
442
+ Column("position", NUMBER),
443
+ ).alias("a_cons_columns")
444
+
445
+ # TODO figure out if it's still relevant, since there is no mention from here
446
+ # https://docs.oracle.com/en/database/oracle/oracle-database/21/refrn/ALL_DB_LINKS.html
447
+ # original note:
448
+ # using user_db_links here since all_db_links appears
449
+ # to have more restricted permissions.
450
+ # https://docs.oracle.com/cd/B28359_01/server.111/b28310/ds_admin005.htm
451
+ # will need to hear from more users if we are doing
452
+ # the right thing here. See [ticket:2619]
453
+ all_db_links = Table(
454
+ "all_db_links" + DB_LINK_PLACEHOLDER,
455
+ dictionary_meta,
456
+ Column("owner", VARCHAR2(128), nullable=False),
457
+ Column("db_link", VARCHAR2(128), nullable=False),
458
+ Column("username", VARCHAR2(128)),
459
+ Column("host", VARCHAR2(2000)),
460
+ Column("created", DATE, nullable=False),
461
+ Column("hidden", VARCHAR2(3)),
462
+ Column("shard_internal", VARCHAR2(3)),
463
+ Column("valid", VARCHAR2(3)),
464
+ Column("intra_cdb", VARCHAR2(3)),
465
+ ).alias("a_db_links")
466
+
467
+ all_synonyms = Table(
468
+ "all_synonyms" + DB_LINK_PLACEHOLDER,
469
+ dictionary_meta,
470
+ Column("owner", VARCHAR2(128)),
471
+ Column("synonym_name", VARCHAR2(128)),
472
+ Column("table_owner", VARCHAR2(128)),
473
+ Column("table_name", VARCHAR2(128)),
474
+ Column("db_link", VARCHAR2(128)),
475
+ Column("origin_con_id", VARCHAR2(256)),
476
+ ).alias("a_synonyms")
477
+
478
+ all_objects = Table(
479
+ "all_objects" + DB_LINK_PLACEHOLDER,
480
+ dictionary_meta,
481
+ Column("owner", VARCHAR2(128), nullable=False),
482
+ Column("object_name", VARCHAR2(128), nullable=False),
483
+ Column("subobject_name", VARCHAR2(128)),
484
+ Column("object_id", NUMBER, nullable=False),
485
+ Column("data_object_id", NUMBER),
486
+ Column("object_type", VARCHAR2(23)),
487
+ Column("created", DATE, nullable=False),
488
+ Column("last_ddl_time", DATE, nullable=False),
489
+ Column("timestamp", VARCHAR2(19)),
490
+ Column("status", VARCHAR2(7)),
491
+ Column("temporary", VARCHAR2(1)),
492
+ Column("generated", VARCHAR2(1)),
493
+ Column("secondary", VARCHAR2(1)),
494
+ Column("namespace", NUMBER, nullable=False),
495
+ Column("edition_name", VARCHAR2(128)),
496
+ Column("sharing", VARCHAR2(13)),
497
+ Column("editionable", VARCHAR2(1)),
498
+ Column("oracle_maintained", VARCHAR2(1)),
499
+ Column("application", VARCHAR2(1)),
500
+ Column("default_collation", VARCHAR2(100)),
501
+ Column("duplicated", VARCHAR2(1)),
502
+ Column("sharded", VARCHAR2(1)),
503
+ Column("created_appid", NUMBER),
504
+ Column("created_vsnid", NUMBER),
505
+ Column("modified_appid", NUMBER),
506
+ Column("modified_vsnid", NUMBER),
507
+ ).alias("a_objects")
@@ -0,0 +1,157 @@
1
+ # dialects/oracle/json.py
2
+ # Copyright (C) 2005-2025 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 __future__ import annotations
10
+
11
+ from typing import Any
12
+ from typing import TYPE_CHECKING
13
+ from typing import TypeVar
14
+
15
+ from ... import types as sqltypes
16
+ from ...sql.base import _NoArg
17
+ from ...sql.base import NO_ARG
18
+ from ...sql.sqltypes import _T_JSON
19
+
20
+ if TYPE_CHECKING:
21
+ from ...engine.interfaces import Dialect
22
+ from ...sql.type_api import _BindProcessorType
23
+ from ...sql.type_api import _LiteralProcessorType
24
+
25
+ _T = TypeVar("_T", bound=Any)
26
+
27
+
28
+ class JSON(sqltypes.JSON[_T_JSON]):
29
+ """Oracle JSON type.
30
+
31
+ .. versionadded:: 2.1
32
+
33
+ Oracle Database supports JSON storage and querying for character and BLOB
34
+ datatypes in Oracle 12c, and supports a dedicated JSON data type as of
35
+ Oracle 21c. SQLAlchemy supports both of these scenarios when using the
36
+ oracledb DBAPI. This type is used implicitly whenever the base
37
+ :class:`_types.JSON` datatype is used against an Oracle backend, or may be
38
+ constructed directly for access to Oracle-specific parameters such as
39
+ :paramref:`_oracle.JSON.use_blob`.
40
+
41
+ Index operations are adapted to render using the ``JSON_QUERY`` and
42
+ ``JSON_VALUE`` functions at the database level.
43
+
44
+ **Platform Support** - When using Oracle Database versions prior to 21c,
45
+ BLOB is used as the storage format. In 21c or later, the native JSON
46
+ datatype is used. This can be overridden using the
47
+ :paramref:`_oracle.JSON.use_blob` parameter.
48
+
49
+ **Serialization / Deserialization** - JSON serialization of bound
50
+ parameters uses Python ``json.dumps()`` by default rather than oracledb's
51
+ native serializer, in order to support the
52
+ :paramref:`_sqltypes.JSON.none_as_null` feature. The default serializer
53
+ does **not** accept Python ``Decimal`` objects; to use a custom serializer,
54
+ pass :paramref:`_sa.create_engine.json_serializer` to
55
+ :func:`_sa.create_engine`.
56
+
57
+ When using the native JSON datatype (21c+), deserialization uses oracledb's
58
+ native deserializer by default, which is required for JSON values larger
59
+ than 32767 bytes. However, this deserializer returns all numeric values as
60
+ ``Decimal`` since Oracle Database stores JSON numbers using its internal
61
+ NUMBER type. To receive standard Python numeric types, pass
62
+ ``json_deserializer=json.loads`` via
63
+ :paramref:`_sa.create_engine.json_deserializer`; note that this limits
64
+ maximum JSON value size to 32767 bytes. When using BLOB storage,
65
+ SQLAlchemy deserializes using ``json.loads()`` directly rather than the
66
+ oracledb deserializer.
67
+
68
+ **CHECK Constraint with BLOB** - When using BLOB storage, either on Oracle
69
+ Database versions prior to 21c or via the :paramref:`_oracle.JSON.use_blob`
70
+ parameter, the oracledb driver documentation recommends adding a
71
+ ``<colname> IS JSON`` check constraint to indicate to the driver that the
72
+ column stores JSON data. This constraint is **not** automatically
73
+ generated by :class:`_oracle.JSON` and is not required by SQLAlchemy's
74
+ implementation in order to read JSON data from the column. If desired, it
75
+ can be added explicitly using :class:`_schema.CheckConstraint`.
76
+
77
+ .. seealso::
78
+
79
+ :class:`_types.JSON` - main documentation for the generic
80
+ cross-platform JSON datatype.
81
+
82
+ """
83
+
84
+ use_blob: bool | _NoArg
85
+
86
+ def __init__(
87
+ self, none_as_null: bool = False, use_blob: bool | _NoArg = NO_ARG
88
+ ):
89
+ """Construct a :class:`_oracle.JSON` type.
90
+
91
+ :param none_as_null=False: if True, persist the value ``None`` as a SQL
92
+ NULL value, not the JSON encoding of ``null``. See the notes at
93
+ :paramref:`_sqltypes.JSON.none_as_null` for complete background on
94
+ this option.
95
+
96
+ :param use_blob: A boolean parameter indicating if the type should be
97
+ rendered in DDL using BLOB instead of JSON. Normally, JSON or BLOB
98
+ is chosen automatically based on the version of Oracle in use
99
+ (21c or greater for JSON). If the parameter is left at its default
100
+ value of the ``NO_ARG`` constant, this automatic selection is used.
101
+ However when ``True``, the BLOB datatype will be used unconditionally,
102
+ and if ``False``, JSON will be used unconditionally (including on
103
+ backends older than 21c, which will raise an error by the server.
104
+ This may be used to assert that only JSON-supporting backends
105
+ should be used).
106
+
107
+ """
108
+
109
+ super().__init__(none_as_null=none_as_null)
110
+ self.use_blob = use_blob
111
+
112
+
113
+ class _FormatTypeMixin:
114
+ def _format_value(self, value: Any) -> str:
115
+ raise NotImplementedError()
116
+
117
+ def bind_processor(self, dialect: Dialect) -> _BindProcessorType[Any]:
118
+ super_proc = self.string_bind_processor(dialect) # type: ignore[attr-defined] # noqa: E501
119
+
120
+ def process(value: Any) -> Any:
121
+ value = self._format_value(value)
122
+ if super_proc:
123
+ value = super_proc(value)
124
+ return value
125
+
126
+ return process
127
+
128
+ def literal_processor(
129
+ self, dialect: Dialect
130
+ ) -> _LiteralProcessorType[Any]:
131
+ super_proc = self.string_literal_processor(dialect) # type: ignore[attr-defined] # noqa: E501
132
+
133
+ def process(value: Any) -> str:
134
+ value = self._format_value(value)
135
+ if super_proc:
136
+ value = super_proc(value)
137
+ return value # type: ignore[no-any-return]
138
+
139
+ return process
140
+
141
+
142
+ class JSONIndexType(_FormatTypeMixin, sqltypes.JSON.JSONIndexType):
143
+ def _format_value(self, value: Any) -> str:
144
+ if isinstance(value, int):
145
+ return f"$[{value}]"
146
+ else:
147
+ return f'$."{value}"'
148
+
149
+
150
+ class JSONPathType(_FormatTypeMixin, sqltypes.JSON.JSONPathType):
151
+ def _format_value(self, value: Any) -> str:
152
+ return "$%s" % (
153
+ "".join(
154
+ f"[{elem}]" if isinstance(elem, int) else f'."{elem}"'
155
+ for elem in value
156
+ )
157
+ )