sqlspec 0.47.0__cp314-cp314-win_amd64.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 (621) hide show
  1. f68e0789eb443ecb1c2c__mypyc.cp314-win_amd64.pyd +0 -0
  2. sqlspec/__init__.py +167 -0
  3. sqlspec/__main__.py +12 -0
  4. sqlspec/__metadata__.py +14 -0
  5. sqlspec/_typing.py +714 -0
  6. sqlspec/adapters/__init__.py +0 -0
  7. sqlspec/adapters/adbc/__init__.py +13 -0
  8. sqlspec/adapters/adbc/_typing.py +106 -0
  9. sqlspec/adapters/adbc/adk/__init__.py +5 -0
  10. sqlspec/adapters/adbc/adk/store.py +1280 -0
  11. sqlspec/adapters/adbc/config.py +378 -0
  12. sqlspec/adapters/adbc/core.cp314-win_amd64.pyd +0 -0
  13. sqlspec/adapters/adbc/core.py +922 -0
  14. sqlspec/adapters/adbc/data_dictionary.py +339 -0
  15. sqlspec/adapters/adbc/driver.py +534 -0
  16. sqlspec/adapters/adbc/events/__init__.py +5 -0
  17. sqlspec/adapters/adbc/events/store.py +285 -0
  18. sqlspec/adapters/adbc/litestar/__init__.py +5 -0
  19. sqlspec/adapters/adbc/litestar/store.py +534 -0
  20. sqlspec/adapters/adbc/type_converter.cp314-win_amd64.pyd +0 -0
  21. sqlspec/adapters/adbc/type_converter.py +142 -0
  22. sqlspec/adapters/aiomysql/__init__.py +21 -0
  23. sqlspec/adapters/aiomysql/_typing.py +137 -0
  24. sqlspec/adapters/aiomysql/adk/__init__.py +5 -0
  25. sqlspec/adapters/aiomysql/adk/store.py +678 -0
  26. sqlspec/adapters/aiomysql/config.py +305 -0
  27. sqlspec/adapters/aiomysql/core.cp314-win_amd64.pyd +0 -0
  28. sqlspec/adapters/aiomysql/core.py +536 -0
  29. sqlspec/adapters/aiomysql/data_dictionary.py +121 -0
  30. sqlspec/adapters/aiomysql/driver.py +386 -0
  31. sqlspec/adapters/aiomysql/events/__init__.py +5 -0
  32. sqlspec/adapters/aiomysql/events/store.py +104 -0
  33. sqlspec/adapters/aiomysql/litestar/__init__.py +5 -0
  34. sqlspec/adapters/aiomysql/litestar/store.py +314 -0
  35. sqlspec/adapters/aiosqlite/__init__.py +26 -0
  36. sqlspec/adapters/aiosqlite/_typing.py +109 -0
  37. sqlspec/adapters/aiosqlite/adk/__init__.py +5 -0
  38. sqlspec/adapters/aiosqlite/adk/store.py +829 -0
  39. sqlspec/adapters/aiosqlite/config.py +315 -0
  40. sqlspec/adapters/aiosqlite/core.cp314-win_amd64.pyd +0 -0
  41. sqlspec/adapters/aiosqlite/core.py +315 -0
  42. sqlspec/adapters/aiosqlite/data_dictionary.py +202 -0
  43. sqlspec/adapters/aiosqlite/driver.py +311 -0
  44. sqlspec/adapters/aiosqlite/events/__init__.py +5 -0
  45. sqlspec/adapters/aiosqlite/events/store.py +20 -0
  46. sqlspec/adapters/aiosqlite/litestar/__init__.py +5 -0
  47. sqlspec/adapters/aiosqlite/litestar/store.py +279 -0
  48. sqlspec/adapters/aiosqlite/pool.cp314-win_amd64.pyd +0 -0
  49. sqlspec/adapters/aiosqlite/pool.py +734 -0
  50. sqlspec/adapters/asyncmy/__init__.py +21 -0
  51. sqlspec/adapters/asyncmy/_typing.py +113 -0
  52. sqlspec/adapters/asyncmy/adk/__init__.py +5 -0
  53. sqlspec/adapters/asyncmy/adk/store.py +644 -0
  54. sqlspec/adapters/asyncmy/config.py +307 -0
  55. sqlspec/adapters/asyncmy/core.cp314-win_amd64.pyd +0 -0
  56. sqlspec/adapters/asyncmy/core.py +538 -0
  57. sqlspec/adapters/asyncmy/data_dictionary.py +122 -0
  58. sqlspec/adapters/asyncmy/driver.py +391 -0
  59. sqlspec/adapters/asyncmy/events/__init__.py +5 -0
  60. sqlspec/adapters/asyncmy/events/store.py +104 -0
  61. sqlspec/adapters/asyncmy/litestar/__init__.py +5 -0
  62. sqlspec/adapters/asyncmy/litestar/store.py +296 -0
  63. sqlspec/adapters/asyncpg/__init__.py +26 -0
  64. sqlspec/adapters/asyncpg/_typing.py +103 -0
  65. sqlspec/adapters/asyncpg/adk/__init__.py +5 -0
  66. sqlspec/adapters/asyncpg/adk/store.py +483 -0
  67. sqlspec/adapters/asyncpg/config.py +575 -0
  68. sqlspec/adapters/asyncpg/core.cp314-win_amd64.pyd +0 -0
  69. sqlspec/adapters/asyncpg/core.py +480 -0
  70. sqlspec/adapters/asyncpg/data_dictionary.py +157 -0
  71. sqlspec/adapters/asyncpg/driver.py +487 -0
  72. sqlspec/adapters/asyncpg/events/__init__.py +6 -0
  73. sqlspec/adapters/asyncpg/events/_hub.py +181 -0
  74. sqlspec/adapters/asyncpg/events/backend.py +210 -0
  75. sqlspec/adapters/asyncpg/events/store.py +40 -0
  76. sqlspec/adapters/asyncpg/litestar/__init__.py +5 -0
  77. sqlspec/adapters/asyncpg/litestar/store.py +251 -0
  78. sqlspec/adapters/bigquery/__init__.py +15 -0
  79. sqlspec/adapters/bigquery/_typing.py +108 -0
  80. sqlspec/adapters/bigquery/config.py +362 -0
  81. sqlspec/adapters/bigquery/core.cp314-win_amd64.pyd +0 -0
  82. sqlspec/adapters/bigquery/core.py +768 -0
  83. sqlspec/adapters/bigquery/data_dictionary.py +120 -0
  84. sqlspec/adapters/bigquery/driver.py +542 -0
  85. sqlspec/adapters/bigquery/events/__init__.py +5 -0
  86. sqlspec/adapters/bigquery/events/store.py +139 -0
  87. sqlspec/adapters/bigquery/litestar/__init__.py +5 -0
  88. sqlspec/adapters/bigquery/litestar/store.py +325 -0
  89. sqlspec/adapters/bigquery/type_converter.cp314-win_amd64.pyd +0 -0
  90. sqlspec/adapters/bigquery/type_converter.py +107 -0
  91. sqlspec/adapters/cockroach_asyncpg/__init__.py +26 -0
  92. sqlspec/adapters/cockroach_asyncpg/_typing.py +73 -0
  93. sqlspec/adapters/cockroach_asyncpg/adk/__init__.py +3 -0
  94. sqlspec/adapters/cockroach_asyncpg/adk/store.py +465 -0
  95. sqlspec/adapters/cockroach_asyncpg/config.py +248 -0
  96. sqlspec/adapters/cockroach_asyncpg/core.cp314-win_amd64.pyd +0 -0
  97. sqlspec/adapters/cockroach_asyncpg/core.py +55 -0
  98. sqlspec/adapters/cockroach_asyncpg/data_dictionary.py +110 -0
  99. sqlspec/adapters/cockroach_asyncpg/driver.py +142 -0
  100. sqlspec/adapters/cockroach_asyncpg/events/__init__.py +3 -0
  101. sqlspec/adapters/cockroach_asyncpg/events/store.py +20 -0
  102. sqlspec/adapters/cockroach_asyncpg/litestar/__init__.py +3 -0
  103. sqlspec/adapters/cockroach_asyncpg/litestar/store.py +142 -0
  104. sqlspec/adapters/cockroach_psycopg/__init__.py +39 -0
  105. sqlspec/adapters/cockroach_psycopg/_typing.py +137 -0
  106. sqlspec/adapters/cockroach_psycopg/adk/__init__.py +13 -0
  107. sqlspec/adapters/cockroach_psycopg/adk/store.py +1039 -0
  108. sqlspec/adapters/cockroach_psycopg/config.py +511 -0
  109. sqlspec/adapters/cockroach_psycopg/core.cp314-win_amd64.pyd +0 -0
  110. sqlspec/adapters/cockroach_psycopg/core.py +63 -0
  111. sqlspec/adapters/cockroach_psycopg/data_dictionary.py +220 -0
  112. sqlspec/adapters/cockroach_psycopg/driver.py +273 -0
  113. sqlspec/adapters/cockroach_psycopg/events/__init__.py +6 -0
  114. sqlspec/adapters/cockroach_psycopg/events/store.py +34 -0
  115. sqlspec/adapters/cockroach_psycopg/litestar/__init__.py +3 -0
  116. sqlspec/adapters/cockroach_psycopg/litestar/store.py +327 -0
  117. sqlspec/adapters/duckdb/__init__.py +29 -0
  118. sqlspec/adapters/duckdb/_typing.py +104 -0
  119. sqlspec/adapters/duckdb/adk/__init__.py +14 -0
  120. sqlspec/adapters/duckdb/adk/store.py +935 -0
  121. sqlspec/adapters/duckdb/config.py +386 -0
  122. sqlspec/adapters/duckdb/core.cp314-win_amd64.pyd +0 -0
  123. sqlspec/adapters/duckdb/core.py +332 -0
  124. sqlspec/adapters/duckdb/data_dictionary.py +140 -0
  125. sqlspec/adapters/duckdb/driver.py +426 -0
  126. sqlspec/adapters/duckdb/events/__init__.py +5 -0
  127. sqlspec/adapters/duckdb/events/store.py +57 -0
  128. sqlspec/adapters/duckdb/litestar/__init__.py +5 -0
  129. sqlspec/adapters/duckdb/litestar/store.py +330 -0
  130. sqlspec/adapters/duckdb/pool.cp314-win_amd64.pyd +0 -0
  131. sqlspec/adapters/duckdb/pool.py +350 -0
  132. sqlspec/adapters/duckdb/type_converter.cp314-win_amd64.pyd +0 -0
  133. sqlspec/adapters/duckdb/type_converter.py +118 -0
  134. sqlspec/adapters/mysqlconnector/__init__.py +39 -0
  135. sqlspec/adapters/mysqlconnector/_typing.py +186 -0
  136. sqlspec/adapters/mysqlconnector/adk/__init__.py +15 -0
  137. sqlspec/adapters/mysqlconnector/adk/store.py +1183 -0
  138. sqlspec/adapters/mysqlconnector/config.py +421 -0
  139. sqlspec/adapters/mysqlconnector/core.cp314-win_amd64.pyd +0 -0
  140. sqlspec/adapters/mysqlconnector/core.py +472 -0
  141. sqlspec/adapters/mysqlconnector/data_dictionary.py +230 -0
  142. sqlspec/adapters/mysqlconnector/driver.py +516 -0
  143. sqlspec/adapters/mysqlconnector/events/__init__.py +8 -0
  144. sqlspec/adapters/mysqlconnector/events/store.py +98 -0
  145. sqlspec/adapters/mysqlconnector/litestar/__init__.py +5 -0
  146. sqlspec/adapters/mysqlconnector/litestar/store.py +426 -0
  147. sqlspec/adapters/oracledb/__init__.py +39 -0
  148. sqlspec/adapters/oracledb/_json_handlers.cp314-win_amd64.pyd +0 -0
  149. sqlspec/adapters/oracledb/_json_handlers.py +196 -0
  150. sqlspec/adapters/oracledb/_param_types.cp314-win_amd64.pyd +0 -0
  151. sqlspec/adapters/oracledb/_param_types.py +46 -0
  152. sqlspec/adapters/oracledb/_typing.py +258 -0
  153. sqlspec/adapters/oracledb/_uuid_handlers.cp314-win_amd64.pyd +0 -0
  154. sqlspec/adapters/oracledb/_uuid_handlers.py +163 -0
  155. sqlspec/adapters/oracledb/_vector_handlers.cp314-win_amd64.pyd +0 -0
  156. sqlspec/adapters/oracledb/_vector_handlers.py +228 -0
  157. sqlspec/adapters/oracledb/adk/__init__.py +21 -0
  158. sqlspec/adapters/oracledb/adk/store.py +2453 -0
  159. sqlspec/adapters/oracledb/config.py +575 -0
  160. sqlspec/adapters/oracledb/core.cp314-win_amd64.pyd +0 -0
  161. sqlspec/adapters/oracledb/core.py +820 -0
  162. sqlspec/adapters/oracledb/data_dictionary.py +404 -0
  163. sqlspec/adapters/oracledb/driver.py +1277 -0
  164. sqlspec/adapters/oracledb/events/__init__.py +16 -0
  165. sqlspec/adapters/oracledb/events/_hub.py +345 -0
  166. sqlspec/adapters/oracledb/events/backend.py +300 -0
  167. sqlspec/adapters/oracledb/events/store.py +420 -0
  168. sqlspec/adapters/oracledb/litestar/__init__.py +5 -0
  169. sqlspec/adapters/oracledb/litestar/store.py +781 -0
  170. sqlspec/adapters/oracledb/migrations.py +539 -0
  171. sqlspec/adapters/oracledb/type_converter.cp314-win_amd64.pyd +0 -0
  172. sqlspec/adapters/oracledb/type_converter.py +211 -0
  173. sqlspec/adapters/psqlpy/__init__.py +18 -0
  174. sqlspec/adapters/psqlpy/_typing.py +121 -0
  175. sqlspec/adapters/psqlpy/adk/__init__.py +5 -0
  176. sqlspec/adapters/psqlpy/adk/store.py +591 -0
  177. sqlspec/adapters/psqlpy/config.py +376 -0
  178. sqlspec/adapters/psqlpy/core.cp314-win_amd64.pyd +0 -0
  179. sqlspec/adapters/psqlpy/core.py +694 -0
  180. sqlspec/adapters/psqlpy/data_dictionary.py +121 -0
  181. sqlspec/adapters/psqlpy/driver.py +411 -0
  182. sqlspec/adapters/psqlpy/events/__init__.py +6 -0
  183. sqlspec/adapters/psqlpy/events/_hub.py +204 -0
  184. sqlspec/adapters/psqlpy/events/backend.py +210 -0
  185. sqlspec/adapters/psqlpy/events/store.py +20 -0
  186. sqlspec/adapters/psqlpy/litestar/__init__.py +5 -0
  187. sqlspec/adapters/psqlpy/litestar/store.py +270 -0
  188. sqlspec/adapters/psqlpy/type_converter.cp314-win_amd64.pyd +0 -0
  189. sqlspec/adapters/psqlpy/type_converter.py +113 -0
  190. sqlspec/adapters/psycopg/__init__.py +38 -0
  191. sqlspec/adapters/psycopg/_typing.py +218 -0
  192. sqlspec/adapters/psycopg/adk/__init__.py +10 -0
  193. sqlspec/adapters/psycopg/adk/store.py +1106 -0
  194. sqlspec/adapters/psycopg/config.py +695 -0
  195. sqlspec/adapters/psycopg/core.cp314-win_amd64.pyd +0 -0
  196. sqlspec/adapters/psycopg/core.py +520 -0
  197. sqlspec/adapters/psycopg/data_dictionary.py +278 -0
  198. sqlspec/adapters/psycopg/driver.py +1033 -0
  199. sqlspec/adapters/psycopg/events/__init__.py +20 -0
  200. sqlspec/adapters/psycopg/events/_hub.py +388 -0
  201. sqlspec/adapters/psycopg/events/backend.py +398 -0
  202. sqlspec/adapters/psycopg/events/store.py +42 -0
  203. sqlspec/adapters/psycopg/litestar/__init__.py +5 -0
  204. sqlspec/adapters/psycopg/litestar/store.py +554 -0
  205. sqlspec/adapters/psycopg/type_converter.cp314-win_amd64.pyd +0 -0
  206. sqlspec/adapters/psycopg/type_converter.py +93 -0
  207. sqlspec/adapters/pymysql/__init__.py +21 -0
  208. sqlspec/adapters/pymysql/_typing.py +92 -0
  209. sqlspec/adapters/pymysql/adk/__init__.py +5 -0
  210. sqlspec/adapters/pymysql/adk/store.py +657 -0
  211. sqlspec/adapters/pymysql/config.py +176 -0
  212. sqlspec/adapters/pymysql/core.cp314-win_amd64.pyd +0 -0
  213. sqlspec/adapters/pymysql/core.py +469 -0
  214. sqlspec/adapters/pymysql/data_dictionary.py +120 -0
  215. sqlspec/adapters/pymysql/driver.py +271 -0
  216. sqlspec/adapters/pymysql/events/__init__.py +5 -0
  217. sqlspec/adapters/pymysql/events/store.py +50 -0
  218. sqlspec/adapters/pymysql/litestar/__init__.py +5 -0
  219. sqlspec/adapters/pymysql/litestar/store.py +232 -0
  220. sqlspec/adapters/pymysql/pool.cp314-win_amd64.pyd +0 -0
  221. sqlspec/adapters/pymysql/pool.py +184 -0
  222. sqlspec/adapters/spanner/__init__.py +33 -0
  223. sqlspec/adapters/spanner/_typing.py +102 -0
  224. sqlspec/adapters/spanner/adk/__init__.py +5 -0
  225. sqlspec/adapters/spanner/adk/store.py +758 -0
  226. sqlspec/adapters/spanner/config.py +355 -0
  227. sqlspec/adapters/spanner/core.cp314-win_amd64.pyd +0 -0
  228. sqlspec/adapters/spanner/core.py +263 -0
  229. sqlspec/adapters/spanner/data_dictionary.py +120 -0
  230. sqlspec/adapters/spanner/driver.py +407 -0
  231. sqlspec/adapters/spanner/events/__init__.py +5 -0
  232. sqlspec/adapters/spanner/events/store.py +187 -0
  233. sqlspec/adapters/spanner/litestar/__init__.py +5 -0
  234. sqlspec/adapters/spanner/litestar/store.py +291 -0
  235. sqlspec/adapters/spanner/type_converter.cp314-win_amd64.pyd +0 -0
  236. sqlspec/adapters/spanner/type_converter.py +342 -0
  237. sqlspec/adapters/sqlite/__init__.py +19 -0
  238. sqlspec/adapters/sqlite/_typing.py +123 -0
  239. sqlspec/adapters/sqlite/adk/__init__.py +5 -0
  240. sqlspec/adapters/sqlite/adk/store.py +992 -0
  241. sqlspec/adapters/sqlite/config.py +240 -0
  242. sqlspec/adapters/sqlite/core.cp314-win_amd64.pyd +0 -0
  243. sqlspec/adapters/sqlite/core.py +357 -0
  244. sqlspec/adapters/sqlite/data_dictionary.py +198 -0
  245. sqlspec/adapters/sqlite/driver.py +527 -0
  246. sqlspec/adapters/sqlite/events/__init__.py +5 -0
  247. sqlspec/adapters/sqlite/events/store.py +20 -0
  248. sqlspec/adapters/sqlite/litestar/__init__.py +5 -0
  249. sqlspec/adapters/sqlite/litestar/store.py +316 -0
  250. sqlspec/adapters/sqlite/pool.cp314-win_amd64.pyd +0 -0
  251. sqlspec/adapters/sqlite/pool.py +237 -0
  252. sqlspec/adapters/sqlite/type_converter.cp314-win_amd64.pyd +0 -0
  253. sqlspec/adapters/sqlite/type_converter.py +114 -0
  254. sqlspec/base.py +832 -0
  255. sqlspec/builder/__init__.py +181 -0
  256. sqlspec/builder/_base.cp314-win_amd64.pyd +0 -0
  257. sqlspec/builder/_base.py +1071 -0
  258. sqlspec/builder/_column.cp314-win_amd64.pyd +0 -0
  259. sqlspec/builder/_column.py +521 -0
  260. sqlspec/builder/_ddl.cp314-win_amd64.pyd +0 -0
  261. sqlspec/builder/_ddl.py +1691 -0
  262. sqlspec/builder/_delete.cp314-win_amd64.pyd +0 -0
  263. sqlspec/builder/_delete.py +95 -0
  264. sqlspec/builder/_dml.cp314-win_amd64.pyd +0 -0
  265. sqlspec/builder/_dml.py +386 -0
  266. sqlspec/builder/_explain.cp314-win_amd64.pyd +0 -0
  267. sqlspec/builder/_explain.py +579 -0
  268. sqlspec/builder/_expression_wrappers.cp314-win_amd64.pyd +0 -0
  269. sqlspec/builder/_expression_wrappers.py +46 -0
  270. sqlspec/builder/_factory.cp314-win_amd64.pyd +0 -0
  271. sqlspec/builder/_factory.py +1884 -0
  272. sqlspec/builder/_insert.cp314-win_amd64.pyd +0 -0
  273. sqlspec/builder/_insert.py +405 -0
  274. sqlspec/builder/_join.cp314-win_amd64.pyd +0 -0
  275. sqlspec/builder/_join.py +489 -0
  276. sqlspec/builder/_merge.cp314-win_amd64.pyd +0 -0
  277. sqlspec/builder/_merge.py +823 -0
  278. sqlspec/builder/_parsing_utils.cp314-win_amd64.pyd +0 -0
  279. sqlspec/builder/_parsing_utils.py +295 -0
  280. sqlspec/builder/_select.cp314-win_amd64.pyd +0 -0
  281. sqlspec/builder/_select.py +1666 -0
  282. sqlspec/builder/_temporal.cp314-win_amd64.pyd +0 -0
  283. sqlspec/builder/_temporal.py +167 -0
  284. sqlspec/builder/_update.cp314-win_amd64.pyd +0 -0
  285. sqlspec/builder/_update.py +173 -0
  286. sqlspec/builder/_vector_distance.cp314-win_amd64.pyd +0 -0
  287. sqlspec/builder/_vector_distance.py +330 -0
  288. sqlspec/cli.py +1095 -0
  289. sqlspec/config.py +2383 -0
  290. sqlspec/core/__init__.py +372 -0
  291. sqlspec/core/_correlation.cp314-win_amd64.pyd +0 -0
  292. sqlspec/core/_correlation.py +176 -0
  293. sqlspec/core/_pagination.py +42 -0
  294. sqlspec/core/_pool.cp314-win_amd64.pyd +0 -0
  295. sqlspec/core/_pool.py +76 -0
  296. sqlspec/core/cache.cp314-win_amd64.pyd +0 -0
  297. sqlspec/core/cache.py +1085 -0
  298. sqlspec/core/compiler.cp314-win_amd64.pyd +0 -0
  299. sqlspec/core/compiler.py +1090 -0
  300. sqlspec/core/config_runtime.cp314-win_amd64.pyd +0 -0
  301. sqlspec/core/config_runtime.py +174 -0
  302. sqlspec/core/explain.cp314-win_amd64.pyd +0 -0
  303. sqlspec/core/explain.py +275 -0
  304. sqlspec/core/filters.cp314-win_amd64.pyd +0 -0
  305. sqlspec/core/filters.py +969 -0
  306. sqlspec/core/hashing.cp314-win_amd64.pyd +0 -0
  307. sqlspec/core/hashing.py +266 -0
  308. sqlspec/core/metrics.cp314-win_amd64.pyd +0 -0
  309. sqlspec/core/metrics.py +83 -0
  310. sqlspec/core/parameters/__init__.py +72 -0
  311. sqlspec/core/parameters/_alignment.cp314-win_amd64.pyd +0 -0
  312. sqlspec/core/parameters/_alignment.py +283 -0
  313. sqlspec/core/parameters/_converter.cp314-win_amd64.pyd +0 -0
  314. sqlspec/core/parameters/_converter.py +554 -0
  315. sqlspec/core/parameters/_processor.cp314-win_amd64.pyd +0 -0
  316. sqlspec/core/parameters/_processor.py +1182 -0
  317. sqlspec/core/parameters/_registry.cp314-win_amd64.pyd +0 -0
  318. sqlspec/core/parameters/_registry.py +206 -0
  319. sqlspec/core/parameters/_transformers.cp314-win_amd64.pyd +0 -0
  320. sqlspec/core/parameters/_transformers.py +324 -0
  321. sqlspec/core/parameters/_types.cp314-win_amd64.pyd +0 -0
  322. sqlspec/core/parameters/_types.py +536 -0
  323. sqlspec/core/parameters/_validator.cp314-win_amd64.pyd +0 -0
  324. sqlspec/core/parameters/_validator.py +171 -0
  325. sqlspec/core/pipeline.cp314-win_amd64.pyd +0 -0
  326. sqlspec/core/pipeline.py +333 -0
  327. sqlspec/core/query_modifiers.cp314-win_amd64.pyd +0 -0
  328. sqlspec/core/query_modifiers.py +508 -0
  329. sqlspec/core/result/__init__.py +25 -0
  330. sqlspec/core/result/_base.cp314-win_amd64.pyd +0 -0
  331. sqlspec/core/result/_base.py +1232 -0
  332. sqlspec/core/result/_io.cp314-win_amd64.pyd +0 -0
  333. sqlspec/core/result/_io.py +28 -0
  334. sqlspec/core/splitter.cp314-win_amd64.pyd +0 -0
  335. sqlspec/core/splitter.py +1021 -0
  336. sqlspec/core/sqlcommenter.cp314-win_amd64.pyd +0 -0
  337. sqlspec/core/sqlcommenter.py +249 -0
  338. sqlspec/core/stack.cp314-win_amd64.pyd +0 -0
  339. sqlspec/core/stack.py +163 -0
  340. sqlspec/core/statement.cp314-win_amd64.pyd +0 -0
  341. sqlspec/core/statement.py +1865 -0
  342. sqlspec/core/type_converter.cp314-win_amd64.pyd +0 -0
  343. sqlspec/core/type_converter.py +340 -0
  344. sqlspec/data_dictionary/__init__.py +22 -0
  345. sqlspec/data_dictionary/_loader.cp314-win_amd64.pyd +0 -0
  346. sqlspec/data_dictionary/_loader.py +138 -0
  347. sqlspec/data_dictionary/_registry.cp314-win_amd64.pyd +0 -0
  348. sqlspec/data_dictionary/_registry.py +74 -0
  349. sqlspec/data_dictionary/_types.cp314-win_amd64.pyd +0 -0
  350. sqlspec/data_dictionary/_types.py +121 -0
  351. sqlspec/data_dictionary/dialects/__init__.py +21 -0
  352. sqlspec/data_dictionary/dialects/bigquery.cp314-win_amd64.pyd +0 -0
  353. sqlspec/data_dictionary/dialects/bigquery.py +81 -0
  354. sqlspec/data_dictionary/dialects/cockroachdb.cp314-win_amd64.pyd +0 -0
  355. sqlspec/data_dictionary/dialects/cockroachdb.py +54 -0
  356. sqlspec/data_dictionary/dialects/duckdb.cp314-win_amd64.pyd +0 -0
  357. sqlspec/data_dictionary/dialects/duckdb.py +47 -0
  358. sqlspec/data_dictionary/dialects/mysql.cp314-win_amd64.pyd +0 -0
  359. sqlspec/data_dictionary/dialects/mysql.py +53 -0
  360. sqlspec/data_dictionary/dialects/oracle.cp314-win_amd64.pyd +0 -0
  361. sqlspec/data_dictionary/dialects/oracle.py +197 -0
  362. sqlspec/data_dictionary/dialects/postgres.cp314-win_amd64.pyd +0 -0
  363. sqlspec/data_dictionary/dialects/postgres.py +69 -0
  364. sqlspec/data_dictionary/dialects/spanner.cp314-win_amd64.pyd +0 -0
  365. sqlspec/data_dictionary/dialects/spanner.py +37 -0
  366. sqlspec/data_dictionary/dialects/sqlite.cp314-win_amd64.pyd +0 -0
  367. sqlspec/data_dictionary/dialects/sqlite.py +59 -0
  368. sqlspec/data_dictionary/sql/.gitkeep +0 -0
  369. sqlspec/data_dictionary/sql/bigquery/columns.sql +23 -0
  370. sqlspec/data_dictionary/sql/bigquery/foreign_keys.sql +34 -0
  371. sqlspec/data_dictionary/sql/bigquery/indexes.sql +19 -0
  372. sqlspec/data_dictionary/sql/bigquery/tables.sql +33 -0
  373. sqlspec/data_dictionary/sql/bigquery/version.sql +3 -0
  374. sqlspec/data_dictionary/sql/cockroachdb/columns.sql +34 -0
  375. sqlspec/data_dictionary/sql/cockroachdb/foreign_keys.sql +40 -0
  376. sqlspec/data_dictionary/sql/cockroachdb/indexes.sql +32 -0
  377. sqlspec/data_dictionary/sql/cockroachdb/tables.sql +44 -0
  378. sqlspec/data_dictionary/sql/cockroachdb/version.sql +3 -0
  379. sqlspec/data_dictionary/sql/duckdb/columns.sql +23 -0
  380. sqlspec/data_dictionary/sql/duckdb/foreign_keys.sql +36 -0
  381. sqlspec/data_dictionary/sql/duckdb/indexes.sql +19 -0
  382. sqlspec/data_dictionary/sql/duckdb/tables.sql +38 -0
  383. sqlspec/data_dictionary/sql/duckdb/version.sql +3 -0
  384. sqlspec/data_dictionary/sql/mysql/columns.sql +23 -0
  385. sqlspec/data_dictionary/sql/mysql/foreign_keys.sql +28 -0
  386. sqlspec/data_dictionary/sql/mysql/indexes.sql +26 -0
  387. sqlspec/data_dictionary/sql/mysql/tables.sql +33 -0
  388. sqlspec/data_dictionary/sql/mysql/version.sql +3 -0
  389. sqlspec/data_dictionary/sql/oracle/columns.sql +23 -0
  390. sqlspec/data_dictionary/sql/oracle/foreign_keys.sql +48 -0
  391. sqlspec/data_dictionary/sql/oracle/indexes.sql +44 -0
  392. sqlspec/data_dictionary/sql/oracle/tables.sql +25 -0
  393. sqlspec/data_dictionary/sql/oracle/version.sql +20 -0
  394. sqlspec/data_dictionary/sql/postgres/columns.sql +34 -0
  395. sqlspec/data_dictionary/sql/postgres/foreign_keys.sql +40 -0
  396. sqlspec/data_dictionary/sql/postgres/indexes.sql +56 -0
  397. sqlspec/data_dictionary/sql/postgres/tables.sql +44 -0
  398. sqlspec/data_dictionary/sql/postgres/version.sql +3 -0
  399. sqlspec/data_dictionary/sql/spanner/columns.sql +23 -0
  400. sqlspec/data_dictionary/sql/spanner/foreign_keys.sql +70 -0
  401. sqlspec/data_dictionary/sql/spanner/indexes.sql +30 -0
  402. sqlspec/data_dictionary/sql/spanner/tables.sql +9 -0
  403. sqlspec/data_dictionary/sql/spanner/version.sql +3 -0
  404. sqlspec/data_dictionary/sql/sqlite/columns.sql +23 -0
  405. sqlspec/data_dictionary/sql/sqlite/foreign_keys.sql +22 -0
  406. sqlspec/data_dictionary/sql/sqlite/indexes.sql +7 -0
  407. sqlspec/data_dictionary/sql/sqlite/tables.sql +28 -0
  408. sqlspec/data_dictionary/sql/sqlite/version.sql +3 -0
  409. sqlspec/dialects/__init__.py +22 -0
  410. sqlspec/dialects/_compat.cp314-win_amd64.pyd +0 -0
  411. sqlspec/dialects/_compat.py +14 -0
  412. sqlspec/dialects/postgres/__init__.py +9 -0
  413. sqlspec/dialects/postgres/_generators.cp314-win_amd64.pyd +0 -0
  414. sqlspec/dialects/postgres/_generators.py +57 -0
  415. sqlspec/dialects/postgres/_operators.cp314-win_amd64.pyd +0 -0
  416. sqlspec/dialects/postgres/_operators.py +81 -0
  417. sqlspec/dialects/postgres/_paradedb.py +50 -0
  418. sqlspec/dialects/postgres/_pgvector.py +36 -0
  419. sqlspec/dialects/spanner/__init__.py +6 -0
  420. sqlspec/dialects/spanner/_generators.cp314-win_amd64.pyd +0 -0
  421. sqlspec/dialects/spanner/_generators.py +206 -0
  422. sqlspec/dialects/spanner/_spangres.py +77 -0
  423. sqlspec/dialects/spanner/_spanner.py +179 -0
  424. sqlspec/driver/__init__.py +49 -0
  425. sqlspec/driver/_async.cp314-win_amd64.pyd +0 -0
  426. sqlspec/driver/_async.py +1830 -0
  427. sqlspec/driver/_common.cp314-win_amd64.pyd +0 -0
  428. sqlspec/driver/_common.py +2292 -0
  429. sqlspec/driver/_exception_handler.cp314-win_amd64.pyd +0 -0
  430. sqlspec/driver/_exception_handler.py +108 -0
  431. sqlspec/driver/_query_cache.cp314-win_amd64.pyd +0 -0
  432. sqlspec/driver/_query_cache.py +96 -0
  433. sqlspec/driver/_sql_helpers.cp314-win_amd64.pyd +0 -0
  434. sqlspec/driver/_sql_helpers.py +139 -0
  435. sqlspec/driver/_storage_helpers.cp314-win_amd64.pyd +0 -0
  436. sqlspec/driver/_storage_helpers.py +153 -0
  437. sqlspec/driver/_sync.cp314-win_amd64.pyd +0 -0
  438. sqlspec/driver/_sync.py +1817 -0
  439. sqlspec/exceptions.cp314-win_amd64.pyd +0 -0
  440. sqlspec/exceptions.py +480 -0
  441. sqlspec/extensions/__init__.py +0 -0
  442. sqlspec/extensions/adk/__init__.py +84 -0
  443. sqlspec/extensions/adk/_config_utils.py +199 -0
  444. sqlspec/extensions/adk/_types.cp314-win_amd64.pyd +0 -0
  445. sqlspec/extensions/adk/_types.py +41 -0
  446. sqlspec/extensions/adk/artifact/__init__.py +57 -0
  447. sqlspec/extensions/adk/artifact/_types.cp314-win_amd64.pyd +0 -0
  448. sqlspec/extensions/adk/artifact/_types.py +32 -0
  449. sqlspec/extensions/adk/artifact/service.py +508 -0
  450. sqlspec/extensions/adk/artifact/store.py +361 -0
  451. sqlspec/extensions/adk/converters.py +212 -0
  452. sqlspec/extensions/adk/memory/__init__.py +69 -0
  453. sqlspec/extensions/adk/memory/_types.cp314-win_amd64.pyd +0 -0
  454. sqlspec/extensions/adk/memory/_types.py +30 -0
  455. sqlspec/extensions/adk/memory/converters.py +225 -0
  456. sqlspec/extensions/adk/memory/service.py +316 -0
  457. sqlspec/extensions/adk/memory/store.py +525 -0
  458. sqlspec/extensions/adk/migrations/0001_create_adk_tables.py +184 -0
  459. sqlspec/extensions/adk/migrations/__init__.py +0 -0
  460. sqlspec/extensions/adk/service.py +279 -0
  461. sqlspec/extensions/adk/store.py +590 -0
  462. sqlspec/extensions/events/__init__.py +51 -0
  463. sqlspec/extensions/events/_channel.py +703 -0
  464. sqlspec/extensions/events/_hints.cp314-win_amd64.pyd +0 -0
  465. sqlspec/extensions/events/_hints.py +45 -0
  466. sqlspec/extensions/events/_models.py +23 -0
  467. sqlspec/extensions/events/_payload.cp314-win_amd64.pyd +0 -0
  468. sqlspec/extensions/events/_payload.py +69 -0
  469. sqlspec/extensions/events/_protocols.py +134 -0
  470. sqlspec/extensions/events/_queue.py +462 -0
  471. sqlspec/extensions/events/_store.py +209 -0
  472. sqlspec/extensions/events/migrations/0001_create_event_queue.py +59 -0
  473. sqlspec/extensions/events/migrations/__init__.py +3 -0
  474. sqlspec/extensions/fastapi/__init__.py +22 -0
  475. sqlspec/extensions/fastapi/extension.py +391 -0
  476. sqlspec/extensions/fastapi/providers.cp314-win_amd64.pyd +0 -0
  477. sqlspec/extensions/fastapi/providers.py +712 -0
  478. sqlspec/extensions/flask/__init__.py +38 -0
  479. sqlspec/extensions/flask/_state.py +87 -0
  480. sqlspec/extensions/flask/_utils.py +71 -0
  481. sqlspec/extensions/flask/extension.py +539 -0
  482. sqlspec/extensions/litestar/__init__.py +31 -0
  483. sqlspec/extensions/litestar/_utils.py +52 -0
  484. sqlspec/extensions/litestar/channels.py +165 -0
  485. sqlspec/extensions/litestar/cli.py +102 -0
  486. sqlspec/extensions/litestar/config.py +90 -0
  487. sqlspec/extensions/litestar/handlers.py +316 -0
  488. sqlspec/extensions/litestar/migrations/0001_create_session_table.py +137 -0
  489. sqlspec/extensions/litestar/migrations/__init__.py +3 -0
  490. sqlspec/extensions/litestar/plugin.py +1066 -0
  491. sqlspec/extensions/litestar/providers.cp314-win_amd64.pyd +0 -0
  492. sqlspec/extensions/litestar/providers.py +784 -0
  493. sqlspec/extensions/litestar/store.py +298 -0
  494. sqlspec/extensions/otel/__init__.py +58 -0
  495. sqlspec/extensions/prometheus/__init__.py +113 -0
  496. sqlspec/extensions/sanic/__init__.py +19 -0
  497. sqlspec/extensions/sanic/_state.py +43 -0
  498. sqlspec/extensions/sanic/_utils.py +127 -0
  499. sqlspec/extensions/sanic/extension.py +647 -0
  500. sqlspec/extensions/starlette/__init__.py +22 -0
  501. sqlspec/extensions/starlette/_state.py +42 -0
  502. sqlspec/extensions/starlette/_utils.py +96 -0
  503. sqlspec/extensions/starlette/extension.py +374 -0
  504. sqlspec/extensions/starlette/middleware.py +281 -0
  505. sqlspec/loader.cp314-win_amd64.pyd +0 -0
  506. sqlspec/loader.py +727 -0
  507. sqlspec/migrations/__init__.py +39 -0
  508. sqlspec/migrations/base.cp314-win_amd64.pyd +0 -0
  509. sqlspec/migrations/base.py +862 -0
  510. sqlspec/migrations/commands.py +2151 -0
  511. sqlspec/migrations/context.cp314-win_amd64.pyd +0 -0
  512. sqlspec/migrations/context.py +157 -0
  513. sqlspec/migrations/fix.cp314-win_amd64.pyd +0 -0
  514. sqlspec/migrations/fix.py +204 -0
  515. sqlspec/migrations/loaders.cp314-win_amd64.pyd +0 -0
  516. sqlspec/migrations/loaders.py +443 -0
  517. sqlspec/migrations/runner.cp314-win_amd64.pyd +0 -0
  518. sqlspec/migrations/runner.py +1195 -0
  519. sqlspec/migrations/squash.cp314-win_amd64.pyd +0 -0
  520. sqlspec/migrations/squash.py +490 -0
  521. sqlspec/migrations/templates.cp314-win_amd64.pyd +0 -0
  522. sqlspec/migrations/templates.py +234 -0
  523. sqlspec/migrations/tracker.cp314-win_amd64.pyd +0 -0
  524. sqlspec/migrations/tracker.py +792 -0
  525. sqlspec/migrations/utils.cp314-win_amd64.pyd +0 -0
  526. sqlspec/migrations/utils.py +256 -0
  527. sqlspec/migrations/validation.cp314-win_amd64.pyd +0 -0
  528. sqlspec/migrations/validation.py +359 -0
  529. sqlspec/migrations/version.cp314-win_amd64.pyd +0 -0
  530. sqlspec/migrations/version.py +446 -0
  531. sqlspec/observability/__init__.py +57 -0
  532. sqlspec/observability/_common.cp314-win_amd64.pyd +0 -0
  533. sqlspec/observability/_common.py +77 -0
  534. sqlspec/observability/_config.cp314-win_amd64.pyd +0 -0
  535. sqlspec/observability/_config.py +364 -0
  536. sqlspec/observability/_diagnostics.cp314-win_amd64.pyd +0 -0
  537. sqlspec/observability/_diagnostics.py +74 -0
  538. sqlspec/observability/_dispatcher.cp314-win_amd64.pyd +0 -0
  539. sqlspec/observability/_dispatcher.py +200 -0
  540. sqlspec/observability/_formatters/__init__.py +13 -0
  541. sqlspec/observability/_formatters/_aws.cp314-win_amd64.pyd +0 -0
  542. sqlspec/observability/_formatters/_aws.py +102 -0
  543. sqlspec/observability/_formatters/_azure.cp314-win_amd64.pyd +0 -0
  544. sqlspec/observability/_formatters/_azure.py +96 -0
  545. sqlspec/observability/_formatters/_base.cp314-win_amd64.pyd +0 -0
  546. sqlspec/observability/_formatters/_base.py +57 -0
  547. sqlspec/observability/_formatters/_gcp.cp314-win_amd64.pyd +0 -0
  548. sqlspec/observability/_formatters/_gcp.py +131 -0
  549. sqlspec/observability/_formatting.py +58 -0
  550. sqlspec/observability/_observer.cp314-win_amd64.pyd +0 -0
  551. sqlspec/observability/_observer.py +361 -0
  552. sqlspec/observability/_runtime.cp314-win_amd64.pyd +0 -0
  553. sqlspec/observability/_runtime.py +461 -0
  554. sqlspec/observability/_sampling.cp314-win_amd64.pyd +0 -0
  555. sqlspec/observability/_sampling.py +188 -0
  556. sqlspec/observability/_spans.cp314-win_amd64.pyd +0 -0
  557. sqlspec/observability/_spans.py +161 -0
  558. sqlspec/protocols.py +955 -0
  559. sqlspec/py.typed +0 -0
  560. sqlspec/service.py +433 -0
  561. sqlspec/storage/__init__.py +48 -0
  562. sqlspec/storage/_arrow_payload.py +68 -0
  563. sqlspec/storage/_paths.cp314-win_amd64.pyd +0 -0
  564. sqlspec/storage/_paths.py +58 -0
  565. sqlspec/storage/_utils.py +46 -0
  566. sqlspec/storage/backends/__init__.py +1 -0
  567. sqlspec/storage/backends/base.cp314-win_amd64.pyd +0 -0
  568. sqlspec/storage/backends/base.py +374 -0
  569. sqlspec/storage/backends/fsspec.py +574 -0
  570. sqlspec/storage/backends/local.py +468 -0
  571. sqlspec/storage/backends/obstore.py +956 -0
  572. sqlspec/storage/errors.cp314-win_amd64.pyd +0 -0
  573. sqlspec/storage/errors.py +102 -0
  574. sqlspec/storage/pipeline.cp314-win_amd64.pyd +0 -0
  575. sqlspec/storage/pipeline.py +628 -0
  576. sqlspec/storage/registry.cp314-win_amd64.pyd +0 -0
  577. sqlspec/storage/registry.py +329 -0
  578. sqlspec/typing.py +405 -0
  579. sqlspec/utils/__init__.py +7 -0
  580. sqlspec/utils/arrow_helpers.py +384 -0
  581. sqlspec/utils/config_tools.cp314-win_amd64.pyd +0 -0
  582. sqlspec/utils/config_tools.py +314 -0
  583. sqlspec/utils/correlation.cp314-win_amd64.pyd +0 -0
  584. sqlspec/utils/correlation.py +134 -0
  585. sqlspec/utils/deprecation.cp314-win_amd64.pyd +0 -0
  586. sqlspec/utils/deprecation.py +157 -0
  587. sqlspec/utils/dispatch.cp314-win_amd64.pyd +0 -0
  588. sqlspec/utils/dispatch.py +101 -0
  589. sqlspec/utils/fixtures.cp314-win_amd64.pyd +0 -0
  590. sqlspec/utils/fixtures.py +260 -0
  591. sqlspec/utils/logging.cp314-win_amd64.pyd +0 -0
  592. sqlspec/utils/logging.py +251 -0
  593. sqlspec/utils/module_loader.py +306 -0
  594. sqlspec/utils/portal.cp314-win_amd64.pyd +0 -0
  595. sqlspec/utils/portal.py +377 -0
  596. sqlspec/utils/schema.cp314-win_amd64.pyd +0 -0
  597. sqlspec/utils/schema.py +1040 -0
  598. sqlspec/utils/serializers/__init__.py +30 -0
  599. sqlspec/utils/serializers/_json.cp314-win_amd64.pyd +0 -0
  600. sqlspec/utils/serializers/_json.py +415 -0
  601. sqlspec/utils/serializers/_numpy.cp314-win_amd64.pyd +0 -0
  602. sqlspec/utils/serializers/_numpy.py +65 -0
  603. sqlspec/utils/serializers/_schema.cp314-win_amd64.pyd +0 -0
  604. sqlspec/utils/serializers/_schema.py +285 -0
  605. sqlspec/utils/singleton.cp314-win_amd64.pyd +0 -0
  606. sqlspec/utils/singleton.py +41 -0
  607. sqlspec/utils/sync_tools.cp314-win_amd64.pyd +0 -0
  608. sqlspec/utils/sync_tools.py +316 -0
  609. sqlspec/utils/text.cp314-win_amd64.pyd +0 -0
  610. sqlspec/utils/text.py +109 -0
  611. sqlspec/utils/type_converters.cp314-win_amd64.pyd +0 -0
  612. sqlspec/utils/type_converters.py +216 -0
  613. sqlspec/utils/type_guards.cp314-win_amd64.pyd +0 -0
  614. sqlspec/utils/type_guards.py +1508 -0
  615. sqlspec/utils/uuids.cp314-win_amd64.pyd +0 -0
  616. sqlspec/utils/uuids.py +241 -0
  617. sqlspec-0.47.0.dist-info/METADATA +202 -0
  618. sqlspec-0.47.0.dist-info/RECORD +621 -0
  619. sqlspec-0.47.0.dist-info/WHEEL +4 -0
  620. sqlspec-0.47.0.dist-info/entry_points.txt +6 -0
  621. sqlspec-0.47.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,176 @@
1
+ """PyMySQL database configuration."""
2
+
3
+ from typing import TYPE_CHECKING, Any, ClassVar, TypedDict, cast
4
+
5
+ from typing_extensions import NotRequired
6
+
7
+ from sqlspec.adapters.pymysql._typing import PyMysqlConnection, PyMysqlCursor, PyMysqlSessionContext
8
+ from sqlspec.adapters.pymysql.core import apply_driver_features, default_statement_config
9
+ from sqlspec.adapters.pymysql.driver import PyMysqlDriver, PyMysqlExceptionHandler
10
+ from sqlspec.adapters.pymysql.pool import PyMysqlConnectionPool
11
+ from sqlspec.config import ExtensionConfigs, SyncDatabaseConfig
12
+ from sqlspec.driver._sync import SyncPoolConnectionContext, SyncPoolSessionFactory
13
+ from sqlspec.extensions.events import EventRuntimeHints
14
+ from sqlspec.utils.config_tools import normalize_connection_config
15
+
16
+ if TYPE_CHECKING:
17
+ from collections.abc import Callable
18
+
19
+ from sqlspec.core import StatementConfig
20
+ from sqlspec.observability import ObservabilityConfig
21
+
22
+ __all__ = ("PyMysqlConfig", "PyMysqlConnectionParams", "PyMysqlDriverFeatures", "PyMysqlPoolParams")
23
+
24
+
25
+ class PyMysqlConnectionParams(TypedDict):
26
+ """PyMySQL connection parameters."""
27
+
28
+ host: NotRequired[str]
29
+ user: NotRequired[str]
30
+ password: NotRequired[str]
31
+ database: NotRequired[str]
32
+ port: NotRequired[int]
33
+ unix_socket: NotRequired[str]
34
+ charset: NotRequired[str]
35
+ connect_timeout: NotRequired[int]
36
+ read_timeout: NotRequired[int]
37
+ write_timeout: NotRequired[int]
38
+ autocommit: NotRequired[bool]
39
+ ssl: NotRequired["dict[str, Any]"]
40
+ client_flag: NotRequired[int]
41
+ cursorclass: NotRequired[type]
42
+ init_command: NotRequired[str]
43
+ sql_mode: NotRequired[str]
44
+ extra: NotRequired["dict[str, Any]"]
45
+
46
+
47
+ class PyMysqlPoolParams(PyMysqlConnectionParams):
48
+ """PyMySQL pool parameters."""
49
+
50
+ pool_recycle_seconds: NotRequired[int]
51
+ health_check_interval: NotRequired[float]
52
+
53
+
54
+ class PyMysqlDriverFeatures(TypedDict):
55
+ """PyMySQL driver feature flags.
56
+
57
+ json_serializer: Custom JSON serializer function.
58
+ Defaults to sqlspec.utils.serializers.to_json.
59
+ json_deserializer: Custom JSON deserializer function.
60
+ Defaults to sqlspec.utils.serializers.from_json.
61
+ on_connection_create: Callback executed when a connection is created.
62
+ Receives the raw pymysql connection for low-level driver configuration.
63
+ Runs after connection creation.
64
+ enable_events: Enable database event channel support.
65
+ events_backend: Event channel backend selection.
66
+ """
67
+
68
+ json_serializer: NotRequired["Callable[[Any], str]"]
69
+ json_deserializer: NotRequired["Callable[[str], Any]"]
70
+ on_connection_create: "NotRequired[Callable[[PyMysqlConnection], None]]"
71
+ enable_events: NotRequired[bool]
72
+ events_backend: NotRequired[str]
73
+
74
+
75
+ class PyMysqlConnectionContext(SyncPoolConnectionContext):
76
+ """Context manager for PyMySQL connections."""
77
+
78
+ __slots__ = ()
79
+
80
+
81
+ class _PyMysqlSessionConnectionHandler(SyncPoolSessionFactory):
82
+ __slots__ = ()
83
+
84
+
85
+ class PyMysqlConfig(SyncDatabaseConfig[PyMysqlConnection, PyMysqlConnectionPool, PyMysqlDriver]):
86
+ """Configuration for PyMySQL synchronous connections."""
87
+
88
+ driver_type: "ClassVar[type[PyMysqlDriver]]" = PyMysqlDriver
89
+ connection_type: "ClassVar[type[PyMysqlConnection]]" = cast("type[PyMysqlConnection]", PyMysqlConnection)
90
+ supports_transactional_ddl: "ClassVar[bool]" = False
91
+ supports_native_arrow_export: "ClassVar[bool]" = True
92
+ supports_native_arrow_import: "ClassVar[bool]" = True
93
+ supports_native_parquet_export: "ClassVar[bool]" = True
94
+ supports_native_parquet_import: "ClassVar[bool]" = True
95
+ _connection_context_class: "ClassVar[type[PyMysqlConnectionContext]]" = PyMysqlConnectionContext
96
+ _session_factory_class: "ClassVar[type[_PyMysqlSessionConnectionHandler]]" = _PyMysqlSessionConnectionHandler
97
+ _session_context_class: "ClassVar[type[PyMysqlSessionContext]]" = PyMysqlSessionContext
98
+ _default_statement_config = default_statement_config
99
+
100
+ def __init__(
101
+ self,
102
+ *,
103
+ connection_config: "PyMysqlPoolParams | dict[str, Any] | None" = None,
104
+ connection_instance: "PyMysqlConnectionPool | None" = None,
105
+ migration_config: "dict[str, Any] | None" = None,
106
+ statement_config: "StatementConfig | None" = None,
107
+ driver_features: "PyMysqlDriverFeatures | dict[str, Any] | None" = None,
108
+ bind_key: "str | None" = None,
109
+ extension_config: "ExtensionConfigs | None" = None,
110
+ observability_config: "ObservabilityConfig | None" = None,
111
+ **kwargs: Any,
112
+ ) -> None:
113
+ connection_config = normalize_connection_config(connection_config)
114
+ connection_config.setdefault("host", "localhost")
115
+ connection_config.setdefault("port", 3306)
116
+
117
+ statement_config = statement_config or default_statement_config
118
+ statement_config, driver_features = apply_driver_features(statement_config, driver_features)
119
+
120
+ # Extract user connection hook before storing driver_features
121
+ features_dict = dict(driver_features) if driver_features else {}
122
+ self._user_connection_hook: Callable[[PyMysqlConnection], None] | None = features_dict.pop(
123
+ "on_connection_create", None
124
+ )
125
+
126
+ super().__init__(
127
+ connection_config=connection_config,
128
+ connection_instance=connection_instance,
129
+ migration_config=migration_config,
130
+ statement_config=statement_config,
131
+ driver_features=features_dict,
132
+ bind_key=bind_key,
133
+ extension_config=extension_config,
134
+ observability_config=observability_config,
135
+ **kwargs,
136
+ )
137
+
138
+ def _create_pool(self) -> "PyMysqlConnectionPool":
139
+ config = dict(self.connection_config)
140
+ pool_recycle = config.pop("pool_recycle_seconds", 86400)
141
+ health_check = config.pop("health_check_interval", 30.0)
142
+ extra = config.pop("extra", {})
143
+ config.update(extra)
144
+ return PyMysqlConnectionPool(
145
+ config,
146
+ recycle_seconds=pool_recycle,
147
+ health_check_interval=health_check,
148
+ on_connection_create=self._user_connection_hook,
149
+ )
150
+
151
+ def _close_pool(self) -> None:
152
+ if self.connection_instance:
153
+ self.connection_instance.close()
154
+
155
+ def create_connection(self) -> PyMysqlConnection:
156
+ pool = self.provide_pool()
157
+ return pool.acquire()
158
+
159
+ def get_signature_namespace(self) -> "dict[str, Any]":
160
+ namespace = super().get_signature_namespace()
161
+ namespace.update({
162
+ "PyMysqlConnectionContext": PyMysqlConnectionContext,
163
+ "PyMysqlConnection": PyMysqlConnection,
164
+ "PyMysqlConnectionParams": PyMysqlConnectionParams,
165
+ "PyMysqlConnectionPool": PyMysqlConnectionPool,
166
+ "PyMysqlCursor": PyMysqlCursor,
167
+ "PyMysqlDriver": PyMysqlDriver,
168
+ "PyMysqlDriverFeatures": PyMysqlDriverFeatures,
169
+ "PyMysqlExceptionHandler": PyMysqlExceptionHandler,
170
+ "PyMysqlPoolParams": PyMysqlPoolParams,
171
+ "PyMysqlSessionContext": PyMysqlSessionContext,
172
+ })
173
+ return namespace
174
+
175
+ def get_event_runtime_hints(self) -> "EventRuntimeHints":
176
+ return EventRuntimeHints(poll_interval=0.25, lease_seconds=5, select_for_update=True, skip_locked=True)
@@ -0,0 +1,469 @@
1
+ """PyMySQL adapter compiled helpers."""
2
+
3
+ from collections.abc import Callable, Sized
4
+ from typing import TYPE_CHECKING, Any
5
+
6
+ from sqlspec.core import DriverParameterProfile, ParameterStyle, StatementConfig, build_statement_config_from_profile
7
+ from sqlspec.exceptions import (
8
+ CheckViolationError,
9
+ ConnectionTimeoutError,
10
+ DatabaseConnectionError,
11
+ DataError,
12
+ DeadlockError,
13
+ ForeignKeyViolationError,
14
+ IntegrityError,
15
+ NotNullViolationError,
16
+ PermissionDeniedError,
17
+ QueryTimeoutError,
18
+ SQLParsingError,
19
+ SQLSpecError,
20
+ TransactionError,
21
+ UniqueViolationError,
22
+ )
23
+ from sqlspec.utils.serializers import from_json, to_json
24
+ from sqlspec.utils.type_converters import build_uuid_coercions
25
+ from sqlspec.utils.type_guards import has_cursor_metadata, has_lastrowid, has_rowcount
26
+
27
+ if TYPE_CHECKING:
28
+ from collections.abc import Mapping, Sequence
29
+
30
+ __all__ = (
31
+ "apply_driver_features",
32
+ "build_insert_statement",
33
+ "build_profile",
34
+ "build_statement_config",
35
+ "collect_rows",
36
+ "create_mapped_exception",
37
+ "default_statement_config",
38
+ "detect_json_columns",
39
+ "detect_json_columns_from_description",
40
+ "driver_profile",
41
+ "format_identifier",
42
+ "normalize_execute_many_parameters",
43
+ "normalize_execute_parameters",
44
+ "normalize_lastrowid",
45
+ "resolve_column_names",
46
+ "resolve_many_rowcount",
47
+ "resolve_rowcount",
48
+ )
49
+
50
+ # MySQL error codes for constraint violations
51
+ MYSQL_ER_DUP_ENTRY = 1062
52
+ MYSQL_ER_NO_DEFAULT_FOR_FIELD = 1364
53
+ MYSQL_ER_CHECK_CONSTRAINT_VIOLATED = 3819
54
+
55
+ # MySQL error codes for permission/access errors
56
+ MYSQL_ER_DBACCESS_DENIED = 1044
57
+ MYSQL_ER_ACCESS_DENIED = 1045
58
+ MYSQL_ER_TABLEACCESS_DENIED = 1142
59
+
60
+ # MySQL error codes for transaction errors
61
+ MYSQL_ER_LOCK_WAIT_TIMEOUT = 1205
62
+ MYSQL_ER_LOCK_DEADLOCK = 1213
63
+
64
+ # MySQL error codes for connection errors
65
+ MYSQL_CR_CONNECTION_ERROR = 2002
66
+ MYSQL_CR_CONN_HOST_ERROR = 2003
67
+ MYSQL_CR_UNKNOWN_HOST = 2005
68
+ MYSQL_CR_SERVER_GONE_ERROR = 2006
69
+ MYSQL_CR_SERVER_LOST = 2013
70
+ MYSQL_SYNTAX_ERROR_MIN = 1064
71
+ MYSQL_SYNTAX_ERROR_MAX_EXCLUSIVE = 1100
72
+
73
+ _MYSQL_MIGRATION_ERROR_CODES = frozenset((1061, 1091))
74
+ _MYSQL_SQLSTATE_EXACT_DISPATCH: dict[str, tuple[type[SQLSpecError], str]] = {
75
+ "23505": (UniqueViolationError, "unique constraint violation"),
76
+ "23503": (ForeignKeyViolationError, "foreign key constraint violation"),
77
+ "23502": (NotNullViolationError, "not-null constraint violation"),
78
+ "23514": (CheckViolationError, "check constraint violation"),
79
+ }
80
+ _MYSQL_SQLSTATE_PREFIX_DISPATCH: dict[str, tuple[type[SQLSpecError], str]] = {
81
+ "23": (IntegrityError, "integrity constraint violation"),
82
+ "28": (PermissionDeniedError, "authorization error"),
83
+ "40": (TransactionError, "transaction error"),
84
+ "42": (SQLParsingError, "SQL syntax error"),
85
+ "08": (DatabaseConnectionError, "connection error"),
86
+ "22": (DataError, "data error"),
87
+ }
88
+ _MYSQL_CONSTRAINT_ERROR_DISPATCH: dict[int, tuple[type[SQLSpecError], str]] = {
89
+ MYSQL_ER_DUP_ENTRY: (UniqueViolationError, "unique constraint violation"),
90
+ 1216: (ForeignKeyViolationError, "foreign key constraint violation"),
91
+ 1217: (ForeignKeyViolationError, "foreign key constraint violation"),
92
+ 1451: (ForeignKeyViolationError, "foreign key constraint violation"),
93
+ 1452: (ForeignKeyViolationError, "foreign key constraint violation"),
94
+ 1048: (NotNullViolationError, "not-null constraint violation"),
95
+ MYSQL_ER_NO_DEFAULT_FOR_FIELD: (NotNullViolationError, "not-null constraint violation"),
96
+ MYSQL_ER_CHECK_CONSTRAINT_VIOLATED: (CheckViolationError, "check constraint violation"),
97
+ }
98
+ _MYSQL_ACCESS_ERROR_DISPATCH: dict[int, tuple[type[SQLSpecError], str]] = {
99
+ MYSQL_ER_DBACCESS_DENIED: (PermissionDeniedError, "access denied"),
100
+ MYSQL_ER_ACCESS_DENIED: (PermissionDeniedError, "access denied"),
101
+ MYSQL_ER_TABLEACCESS_DENIED: (PermissionDeniedError, "access denied"),
102
+ }
103
+ _MYSQL_TRANSACTION_ERROR_DISPATCH: dict[int, tuple[type[SQLSpecError], str]] = {
104
+ MYSQL_ER_LOCK_DEADLOCK: (DeadlockError, "deadlock detected"),
105
+ MYSQL_ER_LOCK_WAIT_TIMEOUT: (QueryTimeoutError, "lock wait timeout"),
106
+ }
107
+ _MYSQL_CONNECTION_ERROR_DISPATCH: dict[int, tuple[type[SQLSpecError], str]] = {
108
+ MYSQL_CR_SERVER_LOST: (ConnectionTimeoutError, "connection lost"),
109
+ MYSQL_CR_CONNECTION_ERROR: (DatabaseConnectionError, "connection error"),
110
+ MYSQL_CR_CONN_HOST_ERROR: (DatabaseConnectionError, "connection error"),
111
+ MYSQL_CR_UNKNOWN_HOST: (DatabaseConnectionError, "connection error"),
112
+ MYSQL_CR_SERVER_GONE_ERROR: (DatabaseConnectionError, "connection error"),
113
+ }
114
+
115
+
116
+ def _bool_to_int(value: bool) -> int:
117
+ return int(value)
118
+
119
+
120
+ def _quote_mysql_identifier(identifier: str) -> str:
121
+ normalized = identifier.replace("`", "``")
122
+ return f"`{normalized}`"
123
+
124
+
125
+ def format_identifier(identifier: str) -> str:
126
+ cleaned = identifier.strip()
127
+ if not cleaned:
128
+ msg = "Table name must not be empty"
129
+ raise SQLSpecError(msg)
130
+ parts = [part for part in cleaned.split(".") if part]
131
+ formatted = ".".join(_quote_mysql_identifier(part) for part in parts)
132
+ return formatted or _quote_mysql_identifier(cleaned)
133
+
134
+
135
+ def build_insert_statement(table: str, columns: "list[str]") -> str:
136
+ column_clause = ", ".join(_quote_mysql_identifier(column) for column in columns)
137
+ placeholders = ", ".join("%s" for _ in columns)
138
+ return f"INSERT INTO {format_identifier(table)} ({column_clause}) VALUES ({placeholders})"
139
+
140
+
141
+ def normalize_execute_parameters(parameters: Any) -> Any:
142
+ """Normalize parameters for PyMySQL execute calls."""
143
+ return parameters or None
144
+
145
+
146
+ def normalize_execute_many_parameters(parameters: Any) -> Any:
147
+ """Normalize parameters for PyMySQL executemany calls."""
148
+ if not parameters:
149
+ msg = "execute_many requires parameters"
150
+ raise ValueError(msg)
151
+ return parameters
152
+
153
+
154
+ def build_profile() -> "DriverParameterProfile":
155
+ """Create the PyMySQL driver parameter profile."""
156
+ coercions: dict[type, Callable[[Any], Any]] = {bool: _bool_to_int, **build_uuid_coercions()}
157
+ return DriverParameterProfile(
158
+ name="PyMySQL",
159
+ default_style=ParameterStyle.QMARK,
160
+ supported_styles={ParameterStyle.QMARK},
161
+ default_execution_style=ParameterStyle.POSITIONAL_PYFORMAT,
162
+ supported_execution_styles={ParameterStyle.POSITIONAL_PYFORMAT},
163
+ has_native_list_expansion=False,
164
+ preserve_parameter_format=True,
165
+ needs_static_script_compilation=True,
166
+ allow_mixed_parameter_styles=False,
167
+ preserve_original_params_for_many=False,
168
+ json_serializer_strategy="helper",
169
+ custom_type_coercions=coercions,
170
+ default_dialect="mysql",
171
+ )
172
+
173
+
174
+ driver_profile = build_profile()
175
+
176
+
177
+ def build_statement_config(
178
+ *, json_serializer: "Callable[[Any], str] | None" = None, json_deserializer: "Callable[[str], Any] | None" = None
179
+ ) -> "StatementConfig":
180
+ """Construct the PyMySQL statement configuration with optional JSON codecs."""
181
+ serializer = json_serializer or to_json
182
+ deserializer = json_deserializer or from_json
183
+ profile = driver_profile
184
+ return build_statement_config_from_profile(
185
+ profile, statement_overrides={"dialect": "mysql"}, json_serializer=serializer, json_deserializer=deserializer
186
+ )
187
+
188
+
189
+ default_statement_config = build_statement_config()
190
+
191
+
192
+ def apply_driver_features(
193
+ statement_config: "StatementConfig", driver_features: "Mapping[str, Any] | None"
194
+ ) -> "tuple[StatementConfig, dict[str, Any]]":
195
+ """Apply PyMySQL driver feature defaults to statement config."""
196
+ features: dict[str, Any] = dict(driver_features) if driver_features else {}
197
+ json_serializer = features.setdefault("json_serializer", to_json)
198
+ json_deserializer = features.setdefault("json_deserializer", from_json)
199
+
200
+ if json_serializer is not None:
201
+ parameter_config = statement_config.parameter_config.with_json_serializers(
202
+ json_serializer, deserializer=json_deserializer
203
+ )
204
+ statement_config = statement_config.replace(parameter_config=parameter_config)
205
+
206
+ return statement_config, features
207
+
208
+
209
+ def _create_mysql_error(
210
+ error: Any, sqlstate: "str | None", code: "int | None", error_class: type[SQLSpecError], description: str
211
+ ) -> SQLSpecError:
212
+ """Create a MySQL error instance without raising it."""
213
+ code_str = f"[{sqlstate or code}]" if sqlstate or code else ""
214
+ msg = f"MySQL {description} {code_str}: {error}" if code_str else f"MySQL {description}: {error}"
215
+ exc = error_class(msg)
216
+ exc.__cause__ = error
217
+ return exc
218
+
219
+
220
+ def create_mapped_exception(error: Any, *, logger: Any | None = None) -> "SQLSpecError | bool":
221
+ """Map PyMySQL exceptions to SQLSpec errors.
222
+
223
+ This is a factory function that returns an exception instance rather than
224
+ raising. This pattern is more robust for use in __exit__ handlers and
225
+ avoids issues with exception control flow in different Python versions.
226
+
227
+ Mapping priority:
228
+ 1. Specific error codes (most reliable for MySQL)
229
+ 2. SQLSTATE codes (where available)
230
+ 3. Generic error code ranges
231
+ 4. Default SQLSpecError fallback
232
+
233
+ Args:
234
+ error: The PyMySQL exception to map
235
+ logger: Optional logger for migration warnings
236
+
237
+ Returns:
238
+ True to suppress expected migration errors, or a SQLSpec exception
239
+ """
240
+ error_args = getattr(error, "args", ())
241
+ error_code = error_args[0] if error_args and isinstance(error_args[0], int) else None
242
+ sqlstate_attr = getattr(error, "sqlstate", None)
243
+ sqlstate = sqlstate_attr if isinstance(sqlstate_attr, str) else None
244
+ sqlstate_prefix = sqlstate[:2] if isinstance(sqlstate, str) and sqlstate else None
245
+
246
+ # Migration-specific errors to suppress
247
+ if error_code in _MYSQL_MIGRATION_ERROR_CODES:
248
+ if logger is not None:
249
+ logger.warning("PyMySQL expected migration error (ignoring): %s", error)
250
+ return True
251
+
252
+ dispatch = _MYSQL_SQLSTATE_EXACT_DISPATCH.get(sqlstate) if sqlstate is not None else None
253
+ if dispatch is not None:
254
+ return _create_mysql_error(error, sqlstate, error_code, dispatch[0], dispatch[1])
255
+
256
+ dispatch = _MYSQL_CONSTRAINT_ERROR_DISPATCH.get(error_code) if error_code is not None else None
257
+ if dispatch is not None:
258
+ return _create_mysql_error(error, sqlstate, error_code, dispatch[0], dispatch[1])
259
+
260
+ if sqlstate_prefix == "23":
261
+ dispatch = _MYSQL_SQLSTATE_PREFIX_DISPATCH["23"]
262
+ return _create_mysql_error(error, sqlstate, error_code, dispatch[0], dispatch[1])
263
+
264
+ dispatch = _MYSQL_ACCESS_ERROR_DISPATCH.get(error_code) if error_code is not None else None
265
+ if dispatch is not None:
266
+ return _create_mysql_error(error, sqlstate, error_code, dispatch[0], dispatch[1])
267
+ if sqlstate_prefix == "28":
268
+ dispatch = _MYSQL_SQLSTATE_PREFIX_DISPATCH["28"]
269
+ return _create_mysql_error(error, sqlstate, error_code, dispatch[0], dispatch[1])
270
+
271
+ dispatch = _MYSQL_TRANSACTION_ERROR_DISPATCH.get(error_code) if error_code is not None else None
272
+ if dispatch is not None:
273
+ return _create_mysql_error(error, sqlstate, error_code, dispatch[0], dispatch[1])
274
+ if sqlstate_prefix == "40":
275
+ dispatch = _MYSQL_SQLSTATE_PREFIX_DISPATCH["40"]
276
+ return _create_mysql_error(error, sqlstate, error_code, dispatch[0], dispatch[1])
277
+
278
+ if sqlstate_prefix == "42":
279
+ dispatch = _MYSQL_SQLSTATE_PREFIX_DISPATCH["42"]
280
+ return _create_mysql_error(error, sqlstate, error_code, dispatch[0], dispatch[1])
281
+ if isinstance(error_code, int) and MYSQL_SYNTAX_ERROR_MIN <= error_code < MYSQL_SYNTAX_ERROR_MAX_EXCLUSIVE:
282
+ return _create_mysql_error(error, sqlstate, error_code, SQLParsingError, "SQL syntax error")
283
+
284
+ if sqlstate_prefix == "08":
285
+ dispatch = _MYSQL_SQLSTATE_PREFIX_DISPATCH["08"]
286
+ return _create_mysql_error(error, sqlstate, error_code, dispatch[0], dispatch[1])
287
+ dispatch = _MYSQL_CONNECTION_ERROR_DISPATCH.get(error_code) if error_code is not None else None
288
+ if dispatch is not None:
289
+ return _create_mysql_error(error, sqlstate, error_code, dispatch[0], dispatch[1])
290
+
291
+ if sqlstate_prefix == "22":
292
+ dispatch = _MYSQL_SQLSTATE_PREFIX_DISPATCH["22"]
293
+ return _create_mysql_error(error, sqlstate, error_code, dispatch[0], dispatch[1])
294
+
295
+ return _create_mysql_error(error, sqlstate, error_code, SQLSpecError, "database error")
296
+
297
+
298
+ def resolve_column_names(description: "Sequence[Any] | None") -> "list[str]":
299
+ """Resolve ordered column names from cursor metadata."""
300
+ if not description:
301
+ return []
302
+ return [desc[0] for desc in description]
303
+
304
+
305
+ def detect_json_columns_from_description(
306
+ description: "Sequence[Any] | None", json_type_codes: "set[int]"
307
+ ) -> "list[int]":
308
+ """Identify JSON column indexes from pre-fetched cursor description metadata."""
309
+ if not description or not json_type_codes:
310
+ return []
311
+
312
+ json_indexes: list[int] = []
313
+ append = json_indexes.append
314
+ for index, column in enumerate(description):
315
+ if isinstance(column, (tuple, list)):
316
+ type_code = column[1] if len(column) > 1 else None
317
+ else:
318
+ type_code = getattr(column, "type_code", None)
319
+ if type_code in json_type_codes:
320
+ append(index)
321
+ return json_indexes
322
+
323
+
324
+ def detect_json_columns(
325
+ cursor: Any, json_type_codes: "set[int]", description: "Sequence[Any] | None" = None
326
+ ) -> "list[int]":
327
+ """Identify JSON column indexes from cursor metadata."""
328
+ if description is None:
329
+ if not has_cursor_metadata(cursor):
330
+ return []
331
+ description = cursor.description
332
+ return detect_json_columns_from_description(description, json_type_codes)
333
+
334
+
335
+ def _deserialize_pymysql_json_dict_rows(
336
+ column_names: "list[str]",
337
+ rows: "list[dict[str, Any]]",
338
+ json_indexes: "list[int]",
339
+ deserializer: "Callable[[Any], Any]",
340
+ *,
341
+ logger: Any | None = None,
342
+ ) -> "list[dict[str, Any]]":
343
+ """Apply JSON deserialization to dict rows (DictCursor path)."""
344
+ if not rows or not column_names or not json_indexes:
345
+ return rows
346
+
347
+ target_columns = [column_names[index] for index in json_indexes if index < len(column_names)]
348
+ if not target_columns:
349
+ return rows
350
+
351
+ for row in rows:
352
+ for column in target_columns:
353
+ if column not in row:
354
+ continue
355
+ raw_value = row[column]
356
+ if raw_value is None:
357
+ continue
358
+ if isinstance(raw_value, bytearray):
359
+ raw_value = bytes(raw_value)
360
+ if not isinstance(raw_value, (str, bytes)):
361
+ continue
362
+ try:
363
+ row[column] = deserializer(raw_value)
364
+ except Exception:
365
+ if logger is not None:
366
+ logger.debug("Failed to deserialize JSON column %s", column, exc_info=True)
367
+ return rows
368
+
369
+
370
+ def _deserialize_pymysql_json_tuple_rows(
371
+ rows: "list[Any]", json_indexes: "list[int]", deserializer: "Callable[[Any], Any]", *, logger: Any | None = None
372
+ ) -> "list[Any]":
373
+ """Apply JSON deserialization to tuple rows using index-based access."""
374
+ if not rows or not json_indexes:
375
+ return rows
376
+
377
+ result: list[Any] = []
378
+ for row in rows:
379
+ row_list = list(row)
380
+ mutated = False
381
+ for idx in json_indexes:
382
+ if idx >= len(row_list):
383
+ continue
384
+ raw_value = row_list[idx]
385
+ if raw_value is None:
386
+ continue
387
+ if isinstance(raw_value, bytearray):
388
+ raw_value = bytes(raw_value)
389
+ if not isinstance(raw_value, (str, bytes)):
390
+ continue
391
+ try:
392
+ row_list[idx] = deserializer(raw_value)
393
+ mutated = True
394
+ except Exception:
395
+ if logger is not None:
396
+ logger.debug("Failed to deserialize JSON column index %d", idx, exc_info=True)
397
+ result.append(tuple(row_list) if mutated else row)
398
+ return result
399
+
400
+
401
+ def collect_rows(
402
+ fetched_data: "Sequence[Any] | None",
403
+ description: "Sequence[Any] | None",
404
+ json_indexes: "list[int]",
405
+ deserializer: "Callable[[Any], Any]",
406
+ *,
407
+ column_names: "list[str] | None" = None,
408
+ logger: Any | None = None,
409
+ ) -> "tuple[list[Any], list[str], str]":
410
+ """Collect PyMySQL rows with JSON decoding, preserving raw format.
411
+
412
+ Returns:
413
+ Tuple of (rows, column_names, row_format).
414
+ """
415
+ if not description:
416
+ return [], [], "tuple"
417
+ resolved_column_names = resolve_column_names(description) if column_names is None else column_names
418
+ if not fetched_data:
419
+ return [], resolved_column_names, "tuple"
420
+
421
+ first_row = fetched_data[0]
422
+ if isinstance(first_row, dict):
423
+ if not json_indexes:
424
+ rows = fetched_data if isinstance(fetched_data, list) else list(fetched_data)
425
+ return rows, resolved_column_names, "dict"
426
+ rows = [dict(row) for row in fetched_data]
427
+ rows = _deserialize_pymysql_json_dict_rows(
428
+ resolved_column_names, rows, json_indexes, deserializer, logger=logger
429
+ )
430
+ return rows, resolved_column_names, "dict"
431
+ rows = fetched_data if isinstance(fetched_data, list) else list(fetched_data)
432
+ if json_indexes:
433
+ rows = _deserialize_pymysql_json_tuple_rows(rows, json_indexes, deserializer, logger=logger)
434
+ return rows, resolved_column_names, "tuple"
435
+
436
+
437
+ def resolve_rowcount(cursor: Any) -> int:
438
+ """Resolve rowcount from a PyMySQL cursor."""
439
+ if not has_rowcount(cursor):
440
+ return 0
441
+ rowcount = cursor.rowcount
442
+ if isinstance(rowcount, int) and rowcount >= 0:
443
+ return rowcount
444
+ return 0
445
+
446
+
447
+ def resolve_many_rowcount(cursor: Any, parameters: Any, *, fallback_count: "int | None" = None) -> int:
448
+ """Resolve execute_many rowcount using cursor metadata with payload fallback."""
449
+ rowcount = resolve_rowcount(cursor)
450
+ if rowcount > 0:
451
+ return rowcount
452
+ if fallback_count is not None:
453
+ return fallback_count
454
+ if isinstance(parameters, Sized):
455
+ return len(parameters)
456
+ return 0
457
+
458
+
459
+ def normalize_lastrowid(cursor: Any) -> int | None:
460
+ """Normalize lastrowid for PyMySQL when rowcount indicates success."""
461
+ if not has_rowcount(cursor):
462
+ return None
463
+ rowcount = cursor.rowcount
464
+ if not isinstance(rowcount, int) or rowcount <= 0:
465
+ return None
466
+ if not has_lastrowid(cursor):
467
+ return None
468
+ last_id = cursor.lastrowid
469
+ return last_id if isinstance(last_id, int) else None