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
sqlspec/config.py ADDED
@@ -0,0 +1,2383 @@
1
+ """Database configuration surfaces for SQLSpec adapters.
2
+
3
+ This module is intentionally interpreted even though compiled modules consume
4
+ its config classes. The public configuration API is stability-critical for
5
+ compiled callers: keep constructor fields, protocol attributes, migration
6
+ refresh behavior, storage capability hooks, and provider context managers
7
+ runtime-visible and backwards coherent. Move small pure helpers into compiled
8
+ modules only after proving the boundary with installed-wheel smoke coverage.
9
+ """
10
+
11
+ import asyncio
12
+ import threading
13
+ from abc import ABC, abstractmethod
14
+ from collections.abc import Callable
15
+ from inspect import Signature, signature
16
+ from pathlib import Path
17
+ from typing import TYPE_CHECKING, Any, ClassVar, Generic, Literal, TypeAlias, TypeVar, cast
18
+
19
+ from typing_extensions import NotRequired, TypedDict
20
+
21
+ from sqlspec.core.config_runtime import (
22
+ build_default_statement_config,
23
+ close_async_pool,
24
+ close_sync_pool,
25
+ create_async_pool,
26
+ create_sync_pool,
27
+ seed_runtime_driver_features,
28
+ )
29
+ from sqlspec.exceptions import MissingDependencyError
30
+ from sqlspec.extensions.events import EventRuntimeHints
31
+ from sqlspec.loader import SQLFileLoader
32
+ from sqlspec.migrations import AsyncMigrationTracker, SyncMigrationTracker, create_migration_commands
33
+ from sqlspec.observability import ObservabilityConfig, ObservabilityRuntime
34
+ from sqlspec.utils.logging import get_logger
35
+ from sqlspec.utils.module_loader import ensure_pyarrow
36
+
37
+ if TYPE_CHECKING:
38
+ from collections.abc import Awaitable
39
+ from contextlib import AbstractAsyncContextManager, AbstractContextManager
40
+
41
+ from sqlspec.core import StatementConfig
42
+ from sqlspec.driver import AsyncDriverAdapterBase, SyncDriverAdapterBase
43
+ from sqlspec.migrations.commands import AsyncMigrationCommands, SyncMigrationCommands
44
+ from sqlspec.storage import StorageCapabilities
45
+
46
+
47
+ __all__ = (
48
+ "ADKCompressionConfig",
49
+ "ADKConfig",
50
+ "ADKPartitionConfig",
51
+ "ADKRetentionConfig",
52
+ "ADKSqliteOptimizationConfig",
53
+ "AsyncConfigT",
54
+ "AsyncDatabaseConfig",
55
+ "ConfigT",
56
+ "DatabaseConfigProtocol",
57
+ "DriverT",
58
+ "EventsConfig",
59
+ "ExtensionConfigs",
60
+ "FastAPIConfig",
61
+ "FlaskConfig",
62
+ "LifecycleConfig",
63
+ "LitestarConfig",
64
+ "MigrationConfig",
65
+ "NoPoolAsyncConfig",
66
+ "NoPoolSyncConfig",
67
+ "OpenTelemetryConfig",
68
+ "PrometheusConfig",
69
+ "SanicConfig",
70
+ "StarletteConfig",
71
+ "SyncConfigT",
72
+ "SyncDatabaseConfig",
73
+ )
74
+
75
+ AsyncConfigT = TypeVar("AsyncConfigT", bound="AsyncDatabaseConfig[Any, Any, Any] | NoPoolAsyncConfig[Any, Any]")
76
+ SyncConfigT = TypeVar("SyncConfigT", bound="SyncDatabaseConfig[Any, Any, Any] | NoPoolSyncConfig[Any, Any]")
77
+ ConfigT = TypeVar(
78
+ "ConfigT",
79
+ bound="AsyncDatabaseConfig[Any, Any, Any] | NoPoolAsyncConfig[Any, Any] | SyncDatabaseConfig[Any, Any, Any] | NoPoolSyncConfig[Any, Any]",
80
+ )
81
+
82
+ ConnectionT = TypeVar("ConnectionT")
83
+ PoolT = TypeVar("PoolT")
84
+ DriverT = TypeVar("DriverT", bound="SyncDriverAdapterBase | AsyncDriverAdapterBase")
85
+
86
+ logger = get_logger("sqlspec.config")
87
+
88
+ DRIVER_FEATURE_LIFECYCLE_HOOKS: dict[str, str | None] = {
89
+ "on_connection_create": "connection",
90
+ "on_connection_destroy": "connection",
91
+ "on_pool_create": "pool",
92
+ "on_pool_destroying": "pool",
93
+ "on_pool_destroy": "pool",
94
+ "on_session_start": "session",
95
+ "on_session_end": "session",
96
+ }
97
+
98
+
99
+ class _DriverFeatureHookWrapper:
100
+ __slots__ = ("_callback", "_context_key", "_expects_argument")
101
+
102
+ def __init__(self, callback: "Callable[..., Any]", context_key: "str | None", expects_argument: bool) -> None:
103
+ self._callback = callback
104
+ self._context_key = context_key
105
+ self._expects_argument = expects_argument
106
+
107
+ def __call__(self, context: "dict[str, Any]") -> None:
108
+ if not self._expects_argument:
109
+ self._callback()
110
+ return
111
+ if self._context_key is None:
112
+ self._callback(context)
113
+ return
114
+ self._callback(context.get(self._context_key))
115
+
116
+
117
+ class LifecycleConfig(TypedDict):
118
+ """Lifecycle hooks for database adapters.
119
+
120
+ Each hook accepts a list of callables to support multiple handlers.
121
+ """
122
+
123
+ on_connection_create: NotRequired[list[Callable[[Any], None]]]
124
+ on_connection_destroy: NotRequired[list[Callable[[Any], None]]]
125
+ on_pool_create: NotRequired[list[Callable[[Any], None]]]
126
+ on_pool_destroying: NotRequired[list[Callable[[Any], Any]]]
127
+ on_pool_destroy: NotRequired[list[Callable[[Any], None]]]
128
+ on_session_start: NotRequired[list[Callable[[Any], None]]]
129
+ on_session_end: NotRequired[list[Callable[[Any], None]]]
130
+ on_query_start: NotRequired[list[Callable[[str, dict[str, Any]], None]]]
131
+ on_query_complete: NotRequired[list[Callable[[str, dict[str, Any], Any], None]]]
132
+ on_error: NotRequired[list[Callable[[Exception, str, dict[str, Any]], None]]]
133
+
134
+
135
+ class MigrationConfig(TypedDict):
136
+ """Configuration options for database migrations.
137
+
138
+ All fields are optional with default values.
139
+ """
140
+
141
+ script_location: NotRequired["str | Path"]
142
+ """Path to the migrations directory. Accepts string or Path object. Defaults to 'migrations'."""
143
+
144
+ version_table_name: NotRequired[str]
145
+ """Name of the table used to track applied migrations. Defaults to 'sqlspec_migrations'."""
146
+
147
+ project_root: NotRequired[str]
148
+ """Path to the project root directory. Used for relative path resolution."""
149
+
150
+ enabled: NotRequired[bool]
151
+ """Whether this configuration should be included in CLI operations. Defaults to True."""
152
+
153
+ auto_sync: NotRequired[bool]
154
+ """Enable automatic version reconciliation during upgrade. When enabled (default), SQLSpec automatically updates database tracking when migrations are renamed from timestamp to sequential format. Defaults to True."""
155
+
156
+ strict_ordering: NotRequired[bool]
157
+ """Enforce strict migration ordering. When enabled, prevents out-of-order migrations from being applied. Defaults to False."""
158
+
159
+ include_extensions: NotRequired["list[str]"]
160
+ """List of extension names whose migrations should be included. Extension migrations maintain separate versioning and are prefixed with 'ext_{name}_'.
161
+
162
+ Note: Extensions with migration support (litestar, adk, events) are auto-included when
163
+ their settings are present in ``extension_config``. Use ``exclude_extensions`` to opt out.
164
+ """
165
+
166
+ exclude_extensions: NotRequired["list[str]"]
167
+ """List of extension names to exclude from automatic migration inclusion.
168
+
169
+ When an extension is configured in ``extension_config``, its migrations are automatically
170
+ included. Use this to prevent that for specific extensions:
171
+
172
+ Example:
173
+ migration_config={
174
+ "exclude_extensions": ["events"] # Use ephemeral listen_notify, skip queue table
175
+ }
176
+ """
177
+
178
+ transactional: NotRequired[bool]
179
+ """Wrap migrations in transactions when supported. When enabled (default for adapters that support it), each migration runs in a transaction that is committed on success or rolled back on failure. This prevents partial migrations from leaving the database in an inconsistent state. Requires adapter support for transactional DDL. Defaults to True for PostgreSQL, SQLite, and DuckDB; False for MySQL, Oracle, and BigQuery. Individual migrations can override this with a '-- transactional: false' comment."""
180
+
181
+ use_logger: NotRequired[bool]
182
+ """Use Python logger instead of Rich console for migration output.
183
+
184
+ When True, migration progress is logged via structlog/logging instead of being
185
+ printed to the console with Rich formatting. This is useful for programmatic
186
+ usage where console output is not desired (e.g., in tests, automated scripts,
187
+ or production deployments with structured logging).
188
+
189
+ Can be overridden per-call via the ``use_logger`` parameter on ``migrate_up()``
190
+ and ``migrate_down()`` methods.
191
+
192
+ Defaults to False (Rich console output).
193
+ """
194
+
195
+ echo: NotRequired[bool]
196
+ """Echo migration output to the console.
197
+
198
+ When False, console output is suppressed. This is useful for script or CI
199
+ environments that need quiet stdout.
200
+
201
+ Defaults to True.
202
+ """
203
+
204
+ summary_only: NotRequired[bool]
205
+ """Emit a single summary log entry for migration commands.
206
+
207
+ When True and ``use_logger`` is enabled, per-migration output is suppressed
208
+ in favor of a single structured summary log event.
209
+
210
+ Defaults to False.
211
+ """
212
+
213
+
214
+ class FlaskConfig(TypedDict):
215
+ """Configuration options for Flask SQLSpec extension.
216
+
217
+ All fields are optional with sensible defaults. Use in extension_config["flask"]:
218
+
219
+ Example:
220
+ from sqlspec.adapters.asyncpg import AsyncpgConfig
221
+
222
+ config = AsyncpgConfig(
223
+ connection_config={"dsn": "postgresql://localhost/mydb"},
224
+ extension_config={
225
+ "flask": {
226
+ "commit_mode": "autocommit",
227
+ "session_key": "db"
228
+ }
229
+ }
230
+ )
231
+
232
+ Notes:
233
+ This TypedDict provides type safety for extension config.
234
+ Flask extension uses g object for request-scoped storage.
235
+ """
236
+
237
+ connection_key: NotRequired[str]
238
+ """Key for storing connection in Flask g object. Default: auto-generated from session_key."""
239
+
240
+ session_key: NotRequired[str]
241
+ """Key for accessing session via plugin.get_session(). Default: 'db_session'."""
242
+
243
+ commit_mode: NotRequired[Literal["manual", "autocommit", "autocommit_include_redirect"]]
244
+ """Transaction commit mode. Default: 'manual'.
245
+ - manual: No automatic commits, user handles explicitly
246
+ - autocommit: Commits on 2xx status, rollback otherwise
247
+ - autocommit_include_redirect: Commits on 2xx-3xx status, rollback otherwise
248
+ """
249
+
250
+ extra_commit_statuses: NotRequired[set[int]]
251
+ """Additional HTTP status codes that trigger commit. Default: None."""
252
+
253
+ extra_rollback_statuses: NotRequired[set[int]]
254
+ """Additional HTTP status codes that trigger rollback. Default: None."""
255
+
256
+ disable_di: NotRequired[bool]
257
+ """Disable built-in dependency injection. Default: False.
258
+ When True, the Flask extension will not register request hooks for managing
259
+ database connections and sessions. Users are responsible for managing the
260
+ database lifecycle manually via their own DI solution.
261
+ """
262
+
263
+ enable_sqlcommenter_middleware: NotRequired[bool]
264
+ """Control automatic SQLCommenter context population. Default: True.
265
+ When the driver's :class:`~sqlspec.core.statement.StatementConfig` has
266
+ ``enable_sqlcommenter=True``, request attributes are populated automatically.
267
+ Set to ``False`` to explicitly disable this behavior.
268
+ """
269
+
270
+
271
+ class LitestarConfig(TypedDict):
272
+ """Configuration options for Litestar SQLSpec plugin.
273
+
274
+ All fields are optional with sensible defaults.
275
+ """
276
+
277
+ session_table: NotRequired["bool | str"]
278
+ """Enable session table for server-side session storage.
279
+
280
+ - ``True``: Use default table name ('litestar_session')
281
+ - ``"custom_name"``: Use custom table name
282
+
283
+ When set, litestar extension migrations are auto-included to create the session table.
284
+ If you're only using litestar for DI/connection management (not session storage),
285
+ leave this unset to skip the migrations.
286
+ """
287
+
288
+ connection_key: NotRequired[str]
289
+ """Key for storing connection in ASGI scope. Default: 'db_connection'"""
290
+
291
+ pool_key: NotRequired[str]
292
+ """Key for storing connection pool in application state. Default: 'db_pool'"""
293
+
294
+ session_key: NotRequired[str]
295
+ """Key for storing session in ASGI scope. Default: 'db_session'"""
296
+
297
+ commit_mode: NotRequired[Literal["manual", "autocommit", "autocommit_include_redirect"]]
298
+ """Transaction commit mode. Default: 'manual'"""
299
+
300
+ enable_correlation_middleware: NotRequired[bool]
301
+ """Enable request correlation ID middleware. Default: True"""
302
+
303
+ correlation_header: NotRequired[str]
304
+ """HTTP header to read the request correlation ID from when middleware is enabled. Default: ``X-Request-ID``"""
305
+
306
+ extra_commit_statuses: NotRequired[set[int]]
307
+ """Additional HTTP status codes that trigger commit. Default: set()"""
308
+
309
+ extra_rollback_statuses: NotRequired[set[int]]
310
+ """Additional HTTP status codes that trigger rollback. Default: set()"""
311
+
312
+ disable_di: NotRequired[bool]
313
+ """Disable built-in dependency injection. Default: False.
314
+ When True, the Litestar plugin will not register dependency providers for managing
315
+ database connections, pools, and sessions. Users are responsible for managing the
316
+ database lifecycle manually via their own DI solution.
317
+ """
318
+
319
+ enable_sqlcommenter_middleware: NotRequired[bool]
320
+ """Control automatic SQLCommenter middleware registration. Default: True.
321
+ When the driver's :class:`~sqlspec.core.statement.StatementConfig` has
322
+ ``enable_sqlcommenter=True``, the middleware is registered automatically.
323
+ Set to ``False`` to explicitly disable middleware registration even when
324
+ SQLCommenter is enabled on the driver config.
325
+ """
326
+
327
+
328
+ class StarletteConfig(TypedDict):
329
+ """Configuration options for Starlette SQLSpec extension.
330
+
331
+ All fields are optional with sensible defaults. Use in extension_config["starlette"]:
332
+
333
+ Example:
334
+ from sqlspec.adapters.asyncpg import AsyncpgConfig
335
+
336
+ config = AsyncpgConfig(
337
+ connection_config={"dsn": "postgresql://localhost/mydb"},
338
+ extension_config={
339
+ "starlette": {
340
+ "commit_mode": "autocommit",
341
+ "session_key": "db"
342
+ }
343
+ }
344
+ )
345
+
346
+ Notes:
347
+ This TypedDict provides type safety for extension config.
348
+ """
349
+
350
+ connection_key: NotRequired[str]
351
+ """Key for storing connection in request.state. Default: 'db_connection'"""
352
+
353
+ pool_key: NotRequired[str]
354
+ """Key for storing connection pool in app.state. Default: 'db_pool'"""
355
+
356
+ session_key: NotRequired[str]
357
+ """Key for storing session in request.state. Default: 'db_session'"""
358
+
359
+ commit_mode: NotRequired[Literal["manual", "autocommit", "autocommit_include_redirect"]]
360
+ """Transaction commit mode. Default: 'manual'
361
+
362
+ - manual: No automatic commit/rollback
363
+ - autocommit: Commit on 2xx, rollback otherwise
364
+ - autocommit_include_redirect: Commit on 2xx-3xx, rollback otherwise
365
+ """
366
+
367
+ extra_commit_statuses: NotRequired[set[int]]
368
+ """Additional HTTP status codes that trigger commit. Default: set()
369
+
370
+ Example:
371
+ extra_commit_statuses={201, 202}
372
+ """
373
+
374
+ extra_rollback_statuses: NotRequired[set[int]]
375
+ """Additional HTTP status codes that trigger rollback. Default: set()
376
+
377
+ Example:
378
+ extra_rollback_statuses={409}
379
+ """
380
+
381
+ disable_di: NotRequired[bool]
382
+ """Disable built-in dependency injection. Default: False.
383
+ When True, the Starlette/FastAPI extension will not add middleware for managing
384
+ database connections and sessions. Users are responsible for managing the
385
+ database lifecycle manually via their own DI solution.
386
+ """
387
+
388
+ enable_sqlcommenter_middleware: NotRequired[bool]
389
+ """Control automatic SQLCommenter middleware registration. Default: True.
390
+ When the driver's :class:`~sqlspec.core.statement.StatementConfig` has
391
+ ``enable_sqlcommenter=True``, the middleware is registered automatically.
392
+ Set to ``False`` to explicitly disable middleware registration.
393
+ """
394
+
395
+ sqlcommenter_framework: NotRequired[str]
396
+ """Framework name for SQLCommenter attributes. Default: 'starlette'.
397
+ Set to 'fastapi' when using FastAPI.
398
+ """
399
+
400
+
401
+ class FastAPIConfig(StarletteConfig):
402
+ """Configuration options for FastAPI SQLSpec extension.
403
+
404
+ All fields are optional with sensible defaults. Use in ``extension_config["fastapi"]``.
405
+ SQLCommenter defaults the framework attribute to ``"fastapi"``.
406
+
407
+ Example:
408
+ from sqlspec.adapters.asyncpg import AsyncpgConfig
409
+
410
+ config = AsyncpgConfig(
411
+ connection_config={"dsn": "postgresql://localhost/mydb"},
412
+ extension_config={
413
+ "fastapi": {
414
+ "commit_mode": "autocommit",
415
+ "session_key": "db"
416
+ }
417
+ }
418
+ )
419
+ """
420
+
421
+
422
+ class SanicConfig(TypedDict):
423
+ """Configuration options for Sanic SQLSpec extension.
424
+
425
+ All fields are optional with sensible defaults. Use in ``extension_config["sanic"]``.
426
+
427
+ Example:
428
+ from sqlspec.adapters.asyncpg import AsyncpgConfig
429
+
430
+ config = AsyncpgConfig(
431
+ connection_config={"dsn": "postgresql://localhost/mydb"},
432
+ extension_config={
433
+ "sanic": {
434
+ "commit_mode": "autocommit",
435
+ "session_key": "db"
436
+ }
437
+ }
438
+ )
439
+
440
+ Notes:
441
+ This TypedDict provides type safety for extension config.
442
+ Sanic extension uses ``app.ctx`` for pools and ``request.ctx`` for
443
+ request-scoped connections and sessions.
444
+ """
445
+
446
+ connection_key: NotRequired[str]
447
+ """Key for storing connection in request.ctx. Default: 'db_connection'"""
448
+
449
+ pool_key: NotRequired[str]
450
+ """Key for storing connection pool in app.ctx. Default: 'db_pool'"""
451
+
452
+ session_key: NotRequired[str]
453
+ """Key for storing session in request.ctx. Default: 'db_session'"""
454
+
455
+ commit_mode: NotRequired[Literal["manual", "autocommit", "autocommit_include_redirect"]]
456
+ """Transaction commit mode. Default: 'manual'
457
+
458
+ - manual: No automatic commit/rollback
459
+ - autocommit: Commit on 2xx, rollback otherwise
460
+ - autocommit_include_redirect: Commit on 2xx-3xx, rollback otherwise
461
+ """
462
+
463
+ extra_commit_statuses: NotRequired[set[int]]
464
+ """Additional HTTP status codes that trigger commit. Default: set()"""
465
+
466
+ extra_rollback_statuses: NotRequired[set[int]]
467
+ """Additional HTTP status codes that trigger rollback. Default: set()"""
468
+
469
+ disable_di: NotRequired[bool]
470
+ """Disable built-in dependency injection. Default: False.
471
+ When True, the Sanic extension will not register request middleware for
472
+ managing database connections and sessions. Users are responsible for
473
+ managing the database lifecycle manually via their own DI solution.
474
+ """
475
+
476
+ enable_correlation_middleware: NotRequired[bool]
477
+ """Enable request correlation ID middleware. Default: False."""
478
+
479
+ correlation_header: NotRequired[str]
480
+ """HTTP header to read the request correlation ID from when middleware is enabled. Default: ``X-Request-ID``."""
481
+
482
+ correlation_headers: NotRequired[tuple[str, ...] | list[str]]
483
+ """Additional HTTP headers to read as correlation ID fallbacks."""
484
+
485
+ auto_trace_headers: NotRequired[bool]
486
+ """Read standard trace context headers as correlation ID fallbacks. Default: True."""
487
+
488
+ enable_sqlcommenter_middleware: NotRequired[bool]
489
+ """Control automatic SQLCommenter middleware registration. Default: True.
490
+ When the driver's :class:`~sqlspec.core.statement.StatementConfig` has
491
+ ``enable_sqlcommenter=True``, the middleware is registered automatically.
492
+ Set to ``False`` to explicitly disable middleware registration.
493
+ """
494
+
495
+ sqlcommenter_framework: NotRequired[str]
496
+ """Framework name for SQLCommenter attributes. Default: 'sanic'."""
497
+
498
+
499
+ class ADKPartitionConfig(TypedDict):
500
+ """Configuration for table partitioning and sharding strategies.
501
+
502
+ Controls how ADK tables are partitioned across backends that support it.
503
+ Backends without native partitioning support ignore these settings.
504
+
505
+ Example:
506
+ extension_config={
507
+ "adk": {
508
+ "partitioning": {
509
+ "strategy": "range",
510
+ "partition_key": "created_at",
511
+ "interval": "month",
512
+ }
513
+ }
514
+ }
515
+ """
516
+
517
+ strategy: NotRequired[Literal["range", "list", "hash"]]
518
+ """Partitioning strategy. Default: None (no partitioning).
519
+
520
+ - range: Partition by range of values (e.g., time-based)
521
+ - list: Partition by discrete value lists
522
+ - hash: Partition by hash of the partition key
523
+
524
+ Supported by: PostgreSQL, MySQL 8+, Oracle, Spanner.
525
+ Ignored by: SQLite, DuckDB.
526
+ """
527
+
528
+ partition_key: NotRequired[str]
529
+ """Column name used as the partition key.
530
+
531
+ For range partitioning with time-based data, this is typically a timestamp column
532
+ like 'created_at'. For hash partitioning, this is typically the primary key.
533
+ """
534
+
535
+ session_partition_key: NotRequired[str]
536
+ """Session-table partition key override for adapters that create separate ADK tables."""
537
+
538
+ events_partition_key: NotRequired[str]
539
+ """Event-table partition key override for adapters that create separate ADK tables."""
540
+
541
+ memory_partition_key: NotRequired[str]
542
+ """Memory-table partition key override for adapters that create separate ADK tables."""
543
+
544
+ interval: NotRequired[str]
545
+ """Partition interval for range partitioning.
546
+
547
+ Examples: 'day', 'week', 'month', 'year'.
548
+ Only meaningful when strategy is 'range'.
549
+ """
550
+
551
+ partition_count: NotRequired[int]
552
+ """Number of hash partitions for adapters that support hash-partitioned ADK tables."""
553
+
554
+ initial_less_than: NotRequired[str]
555
+ """Initial range-partition upper bound for adapters that require a seed partition."""
556
+
557
+
558
+ class ADKRetentionConfig(TypedDict):
559
+ """Configuration for data retention and TTL policies.
560
+
561
+ Controls automatic cleanup of expired data. Backends with native TTL support
562
+ (CockroachDB Row-Level TTL, Spanner Row Deletion Policy) use database-level
563
+ enforcement. Others fall back to application-level sweep queries.
564
+
565
+ Example:
566
+ extension_config={
567
+ "adk": {
568
+ "retention": {
569
+ "session_ttl_seconds": 86400,
570
+ "event_ttl_seconds": 604800,
571
+ "memory_ttl_seconds": 0,
572
+ }
573
+ }
574
+ }
575
+ """
576
+
577
+ session_ttl_seconds: NotRequired[int]
578
+ """TTL for session records in seconds. Default: 0 (no expiry).
579
+
580
+ When set, sessions older than this threshold are eligible for cleanup.
581
+ Backends with native TTL (CockroachDB, Spanner) enforce this at the database level.
582
+ Others require application-level cleanup via periodic sweep.
583
+ """
584
+
585
+ event_ttl_seconds: NotRequired[int]
586
+ """TTL for event records in seconds. Default: 0 (no expiry).
587
+
588
+ When set, events older than this threshold are eligible for cleanup.
589
+ """
590
+
591
+ memory_ttl_seconds: NotRequired[int]
592
+ """TTL for memory entries in seconds. Default: 0 (no expiry).
593
+
594
+ When set, memory entries older than this threshold are eligible for cleanup.
595
+ """
596
+
597
+ sweep_interval_seconds: NotRequired[int]
598
+ """Interval between application-level cleanup sweeps in seconds. Default: 3600 (1 hour).
599
+
600
+ Only used when the backend does not support native TTL enforcement.
601
+ Set to 0 to disable automatic sweeps (manual cleanup only).
602
+ """
603
+
604
+
605
+ class ADKCompressionConfig(TypedDict):
606
+ """Configuration for table-level compression.
607
+
608
+ Controls compression of ADK table storage. Support and algorithms vary by backend.
609
+
610
+ Example:
611
+ extension_config={
612
+ "adk": {
613
+ "compression": {
614
+ "enabled": True,
615
+ "algorithm": "zstd",
616
+ }
617
+ }
618
+ }
619
+ """
620
+
621
+ enabled: NotRequired[bool]
622
+ """Enable table compression. Default: False.
623
+
624
+ When True, adapters that support table-level compression will apply it
625
+ during table creation.
626
+ """
627
+
628
+ algorithm: NotRequired[str]
629
+ """Compression algorithm name. Backend-specific.
630
+
631
+ Examples:
632
+ - PostgreSQL (with TOAST): 'pglz', 'lz4' (PG14+)
633
+ - MySQL/InnoDB: 'zlib'
634
+ - Oracle: 'basic', 'oltp', 'query_high', 'archive_high'
635
+ - DuckDB: 'zstd', 'snappy'
636
+
637
+ When omitted, the backend default is used.
638
+ """
639
+
640
+ level: NotRequired[int]
641
+ """Compression level (where supported). Higher levels trade CPU for space savings.
642
+
643
+ Valid ranges depend on the algorithm and backend.
644
+ """
645
+
646
+
647
+ class ADKSqliteOptimizationConfig(TypedDict):
648
+ """SQLite-specific PRAGMA optimization settings.
649
+
650
+ Controls SQLite performance tuning parameters applied at connection time.
651
+ These settings are ignored by non-SQLite adapters.
652
+
653
+ Example:
654
+ extension_config={
655
+ "adk": {
656
+ "sqlite_optimization": {
657
+ "cache_size": -64000,
658
+ "mmap_size": 31457280,
659
+ "journal_size_limit": 67108864,
660
+ }
661
+ }
662
+ }
663
+ """
664
+
665
+ cache_size: NotRequired[int]
666
+ """SQLite page cache size. Default: -64000 (64 MB, negative means KiB).
667
+
668
+ Larger caches reduce disk I/O for read-heavy workloads.
669
+ Negative values specify size in KiB; positive values specify page count.
670
+ """
671
+
672
+ mmap_size: NotRequired[int]
673
+ """SQLite memory-mapped I/O size in bytes. Default: 31457280 (30 MB).
674
+
675
+ Enables memory-mapped I/O for faster reads. Set to 0 to disable.
676
+ """
677
+
678
+ journal_size_limit: NotRequired[int]
679
+ """SQLite journal file size limit in bytes. Default: 67108864 (64 MB).
680
+
681
+ Limits the size of the WAL or rollback journal file.
682
+ Prevents unbounded journal growth in write-heavy workloads.
683
+ """
684
+
685
+
686
+ class ADKConfig(TypedDict):
687
+ """Configuration options for ADK session and memory store extension.
688
+
689
+ All fields are optional with sensible defaults. Use in extension_config["adk"]:
690
+
691
+ Configuration supports three deployment scenarios:
692
+ 1. SQLSpec manages everything (runtime + migrations)
693
+ 2. SQLSpec runtime only (external migration tools like Alembic/Flyway)
694
+ 3. Selective features (sessions OR memory, not both)
695
+
696
+ Example:
697
+ from sqlspec.adapters.asyncpg import AsyncpgConfig
698
+
699
+ config = AsyncpgConfig(
700
+ connection_config={"dsn": "postgresql://localhost/mydb"},
701
+ extension_config={
702
+ "adk": {
703
+ "session_table": "my_sessions",
704
+ "events_table": "my_events",
705
+ "memory_table": "my_memories",
706
+ "memory_use_fts": True,
707
+ "owner_id_column": "tenant_id INTEGER REFERENCES tenants(id)"
708
+ }
709
+ }
710
+ )
711
+
712
+ Notes:
713
+ This TypedDict provides type safety for extension config but is not required.
714
+ You can use plain dicts as well.
715
+ """
716
+
717
+ enable_sessions: NotRequired[bool]
718
+ """Enable session store at runtime. Default: True.
719
+
720
+ When False: session service unavailable, session store operations disabled.
721
+ Independent of migration control - can use externally-managed tables.
722
+ """
723
+
724
+ enable_memory: NotRequired[bool]
725
+ """Enable memory store at runtime. Default: True.
726
+
727
+ When False: memory service unavailable, memory store operations disabled.
728
+ Independent of migration control - can use externally-managed tables.
729
+ """
730
+
731
+ include_sessions_migration: NotRequired[bool]
732
+ """Include session tables in SQLSpec migrations. Default: True.
733
+
734
+ When False: session migration DDL skipped (use external migration tools).
735
+ Decoupled from enable_sessions - allows external table management with SQLSpec runtime.
736
+ """
737
+
738
+ include_memory_migration: NotRequired[bool]
739
+ """Include memory tables in SQLSpec migrations. Default: True.
740
+
741
+ When False: memory migration DDL skipped (use external migration tools).
742
+ Decoupled from enable_memory - allows external table management with SQLSpec runtime.
743
+ """
744
+
745
+ session_table: NotRequired[str]
746
+ """Name of the sessions table. Default: 'adk_sessions'
747
+
748
+ Examples:
749
+ "agent_sessions"
750
+ "my_app_sessions"
751
+ "tenant_acme_sessions"
752
+ """
753
+
754
+ events_table: NotRequired[str]
755
+ """Name of the events table. Default: 'adk_events'
756
+
757
+ Examples:
758
+ "agent_events"
759
+ "my_app_events"
760
+ "tenant_acme_events"
761
+ """
762
+
763
+ memory_table: NotRequired[str]
764
+ """Name of the memory entries table. Default: 'adk_memory_entries'
765
+
766
+ Examples:
767
+ "agent_memories"
768
+ "my_app_memories"
769
+ "tenant_acme_memories"
770
+ """
771
+
772
+ artifact_table: NotRequired[str]
773
+ """Name of the artifact versions table. Default: 'adk_artifact_versions'
774
+
775
+ Examples:
776
+ "agent_artifacts"
777
+ "my_app_artifact_versions"
778
+ """
779
+
780
+ artifact_storage_uri: NotRequired[str]
781
+ """Base URI for artifact content storage.
782
+
783
+ Points to a ``sqlspec/storage/`` backend where artifact binary content
784
+ is stored. Can be a direct URI (``s3://bucket/path``, ``file:///path``)
785
+ or a registered alias in the storage registry.
786
+
787
+ Examples:
788
+ "s3://my-bucket/adk-artifacts/"
789
+ "file:///var/data/artifacts/"
790
+ "gcs://my-gcs-bucket/artifacts/"
791
+ """
792
+
793
+ memory_use_fts: NotRequired[bool]
794
+ """Enable full-text search when supported. Default: False.
795
+
796
+ When True, adapters will use their native FTS capabilities where available:
797
+ - PostgreSQL: to_tsvector/to_tsquery with GIN index
798
+ - SQLite: FTS5 virtual table
799
+ - DuckDB: FTS extension with match_bm25
800
+ - Oracle: CONTAINS() with CTXSYS.CONTEXT index
801
+ - Spanner: TOKENIZE_FULLTEXT with search index
802
+ - MySQL: MATCH...AGAINST with FULLTEXT index
803
+
804
+ When False, adapters use simple LIKE/ILIKE queries (works without indexes).
805
+ """
806
+
807
+ memory_max_results: NotRequired[int]
808
+ """Maximum number of results for memory search queries. Default: 20.
809
+
810
+ Limits the number of memory entries returned by search_memory().
811
+ Can be overridden per-query via the limit parameter.
812
+ """
813
+
814
+ owner_id_column: NotRequired[str]
815
+ """Optional owner ID column definition to link sessions/memories to a user, tenant, team, or other entity.
816
+
817
+ Format: "column_name TYPE [NOT NULL] REFERENCES table(column) [options...]"
818
+
819
+ The entire definition is passed through to DDL verbatim. We only parse
820
+ the column name (first word) for use in INSERT/SELECT statements.
821
+
822
+ This column is added to both session and memory tables for consistent
823
+ multi-tenant isolation.
824
+
825
+ Supports:
826
+ - Foreign key constraints: REFERENCES table(column)
827
+ - Nullable or NOT NULL
828
+ - CASCADE options: ON DELETE CASCADE, ON UPDATE CASCADE
829
+ - Dialect-specific options (DEFERRABLE, ENABLE VALIDATE, etc.)
830
+ - Plain columns without FK (just extra column storage)
831
+
832
+ Examples:
833
+ PostgreSQL with UUID FK:
834
+ "account_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE"
835
+
836
+ MySQL with BIGINT FK:
837
+ "user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE RESTRICT"
838
+
839
+ Oracle with NUMBER FK:
840
+ "user_id NUMBER(10) REFERENCES users(id) ENABLE VALIDATE"
841
+
842
+ SQLite with INTEGER FK:
843
+ "tenant_id INTEGER NOT NULL REFERENCES tenants(id)"
844
+
845
+ Nullable FK (optional relationship):
846
+ "workspace_id UUID REFERENCES workspaces(id) ON DELETE SET NULL"
847
+
848
+ No FK (just extra column):
849
+ "organization_name VARCHAR(128) NOT NULL"
850
+
851
+ Deferred constraint (PostgreSQL):
852
+ "user_id UUID REFERENCES users(id) DEFERRABLE INITIALLY DEFERRED"
853
+
854
+ Notes:
855
+ - Column name (first word) is extracted for INSERT/SELECT queries
856
+ - Rest of definition is passed through to CREATE TABLE DDL
857
+ - Database validates the DDL syntax (fail-fast on errors)
858
+ - Works with all database dialects (PostgreSQL, MySQL, SQLite, Oracle, etc.)
859
+ """
860
+
861
+ in_memory: NotRequired[bool]
862
+ """Enable in-memory table storage (Oracle-specific). Default: False.
863
+
864
+ When enabled, tables are created with the INMEMORY clause for Oracle Database,
865
+ which stores table data in columnar format in memory for faster query performance.
866
+
867
+ This is an Oracle-specific feature that requires:
868
+ - Oracle Database 12.1.0.2 or higher
869
+ - Database In-Memory option license (Enterprise Edition)
870
+ - Sufficient INMEMORY_SIZE configured in the database instance
871
+
872
+ Other database adapters ignore this setting.
873
+
874
+ Examples:
875
+ Oracle with in-memory enabled:
876
+ config = OracleAsyncConfig(
877
+ connection_config={"dsn": "oracle://..."},
878
+ extension_config={
879
+ "adk": {
880
+ "in_memory": True
881
+ }
882
+ }
883
+ )
884
+
885
+ Notes:
886
+ - Improves query performance for analytics (10-100x faster)
887
+ - Tables created with INMEMORY clause
888
+ - Requires Oracle Database In-Memory option license
889
+ - Ignored by non-Oracle adapters
890
+ """
891
+
892
+ shard_count: NotRequired[int]
893
+ """Optional hash shard count for session/event tables to reduce hotspotting.
894
+
895
+ When set (>1), adapters that support computed shard columns will create a
896
+ generated shard_id using MOD(FARM_FINGERPRINT(primary_key), shard_count) and
897
+ include it in the primary key and filters. Ignored by adapters that do not
898
+ support computed shards.
899
+ """
900
+
901
+ session_table_options: NotRequired[str]
902
+ """Adapter-specific table OPTIONS/clauses for the sessions table.
903
+
904
+ Passed verbatim when supported (e.g., Spanner columnar/tiered storage). Ignored by
905
+ adapters without table OPTIONS support.
906
+ """
907
+
908
+ events_table_options: NotRequired[str]
909
+ """Adapter-specific table OPTIONS/clauses for the events table."""
910
+
911
+ memory_table_options: NotRequired[str]
912
+ """Adapter-specific table OPTIONS/clauses for the memory table."""
913
+
914
+ expires_index_options: NotRequired[str]
915
+ """Adapter-specific options for the expires/index used in ADK stores."""
916
+
917
+ # --- Capability-based configuration (Chapter 2: schema-capability-config) ---
918
+
919
+ fts_language: NotRequired[str]
920
+ """Language configuration for full-text search indexing. Default: 'english'.
921
+
922
+ Controls the language dictionary/stemmer used by FTS implementations:
923
+ - PostgreSQL: to_tsvector/to_tsquery language parameter
924
+ - SQLite FTS5: tokenizer language for unicode61/porter
925
+ - MySQL: FULLTEXT parser language (with ngram for CJK on 5.7.6+)
926
+ - Oracle: CTXSYS.CONTEXT lexer language
927
+ - Spanner: TOKENIZE_FULLTEXT language parameter
928
+ - DuckDB: FTS stemmer language
929
+
930
+ Only takes effect when ``memory_use_fts`` is True.
931
+
932
+ Common values: 'english', 'simple', 'german', 'french', 'spanish',
933
+ 'portuguese', 'italian', 'dutch', 'russian', 'chinese', 'japanese', 'korean'.
934
+
935
+ Notes:
936
+ Available languages vary by backend. Backends that do not support the
937
+ specified language will fall back to 'simple' or 'english'.
938
+ """
939
+
940
+ schema_version: NotRequired[int]
941
+ """Explicit schema version for ADK tables. Default: None (auto-detect).
942
+
943
+ When set, locks the ADK schema to a specific version. This is useful for:
944
+ - Preventing automatic schema upgrades in production
945
+ - Pinning to a known-good schema during testing
946
+ - Coordinating schema changes across multiple application instances
947
+
948
+ When None, the ADK extension auto-detects the current schema version
949
+ and applies any pending upgrades during initialization.
950
+
951
+ Notes:
952
+ Schema versions are monotonically increasing integers managed by
953
+ the ADK extension migration system. Setting this to a version
954
+ lower than the current database schema will raise a configuration
955
+ error at startup.
956
+ """
957
+
958
+ partitioning: NotRequired[ADKPartitionConfig]
959
+ """Table partitioning configuration. Default: None (no partitioning).
960
+
961
+ Controls how ADK tables are partitioned for improved query performance
962
+ and data management at scale. See ``ADKPartitionConfig`` for options.
963
+
964
+ Supported by: PostgreSQL, MySQL 8+, Oracle, Spanner.
965
+ Ignored by: SQLite, DuckDB.
966
+ """
967
+
968
+ retention: NotRequired[ADKRetentionConfig]
969
+ """Data retention and TTL configuration. Default: None (no automatic cleanup).
970
+
971
+ Controls automatic expiry and cleanup of old session, event, and memory data.
972
+ See ``ADKRetentionConfig`` for options.
973
+
974
+ Backends with native TTL (CockroachDB, Spanner) use database-level enforcement.
975
+ Others fall back to application-level sweep queries.
976
+ """
977
+
978
+ compression: NotRequired[ADKCompressionConfig]
979
+ """Table compression configuration. Default: None (no compression).
980
+
981
+ Controls table-level compression for ADK tables.
982
+ See ``ADKCompressionConfig`` for options.
983
+ """
984
+
985
+ sqlite_optimization: NotRequired[ADKSqliteOptimizationConfig]
986
+ """SQLite-specific PRAGMA optimization settings. Default: None (SQLite defaults).
987
+
988
+ Controls SQLite performance tuning parameters. Ignored by non-SQLite adapters.
989
+ See ``ADKSqliteOptimizationConfig`` for options.
990
+ """
991
+
992
+
993
+ class EventsConfig(TypedDict):
994
+ """Configuration options for the events extension.
995
+
996
+ Use in ``extension_config["events"]``.
997
+ """
998
+
999
+ backend: NotRequired[Literal["listen_notify", "table_queue", "listen_notify_durable", "advanced_queue"]]
1000
+ """Backend implementation. PostgreSQL adapters default to 'listen_notify', others to 'table_queue'.
1001
+
1002
+ - listen_notify: Real-time PostgreSQL LISTEN/NOTIFY (ephemeral)
1003
+ - table_queue: Durable table-backed queue with retries (all adapters)
1004
+ - listen_notify_durable: Hybrid combining both (PostgreSQL only)
1005
+ - advanced_queue: Oracle Advanced Queueing
1006
+ """
1007
+
1008
+ queue_table: NotRequired[str]
1009
+ """Name of the fallback queue table. Defaults to 'sqlspec_event_queue'."""
1010
+
1011
+ lease_seconds: NotRequired[int]
1012
+ """Lease duration for claimed events before they can be retried. Defaults to 30 seconds."""
1013
+
1014
+ retention_seconds: NotRequired[int]
1015
+ """Retention window for acknowledged events before cleanup. Defaults to 86400 (24 hours)."""
1016
+
1017
+ poll_interval: NotRequired[float]
1018
+ """Default poll interval in seconds for event consumers. Defaults to 1.0."""
1019
+
1020
+ select_for_update: NotRequired[bool]
1021
+ """Use SELECT FOR UPDATE locking when claiming events. Defaults to False."""
1022
+
1023
+ skip_locked: NotRequired[bool]
1024
+ """Use SKIP LOCKED for non-blocking event claims. Defaults to False."""
1025
+
1026
+ json_passthrough: NotRequired[bool]
1027
+ """Skip JSON encoding/decoding for payloads. Defaults to False."""
1028
+
1029
+ in_memory: NotRequired[bool]
1030
+ """Enable Oracle INMEMORY clause for the queue table. Ignored by other adapters. Defaults to False.
1031
+
1032
+ Note: To skip events migrations (e.g., when using ephemeral 'listen_notify' backend),
1033
+ use ``migration_config={"exclude_extensions": ["events"]}``.
1034
+ """
1035
+
1036
+
1037
+ class OpenTelemetryConfig(TypedDict):
1038
+ """Configuration options for OpenTelemetry integration.
1039
+
1040
+ Use in ``extension_config["otel"]``.
1041
+ """
1042
+
1043
+ enabled: NotRequired[bool]
1044
+ """Enable the extension. Default: True."""
1045
+
1046
+ enable_spans: NotRequired[bool]
1047
+ """Enable span emission (set False to disable while keeping other settings)."""
1048
+
1049
+ resource_attributes: NotRequired[dict[str, Any]]
1050
+ """Additional resource attributes passed to the tracer provider factory."""
1051
+
1052
+ tracer_provider: NotRequired[Any]
1053
+ """Tracer provider instance to reuse. Mutually exclusive with ``tracer_provider_factory``."""
1054
+
1055
+ tracer_provider_factory: NotRequired[Callable[[], Any]]
1056
+ """Factory returning a tracer provider. Invoked lazily when spans are needed."""
1057
+
1058
+
1059
+ class PrometheusConfig(TypedDict):
1060
+ """Configuration options for Prometheus metrics.
1061
+
1062
+ Use in ``extension_config["prometheus"]``.
1063
+ """
1064
+
1065
+ enabled: NotRequired[bool]
1066
+ """Enable the extension. Default: True."""
1067
+
1068
+ namespace: NotRequired[str]
1069
+ """Prometheus metric namespace. Default: ``"sqlspec"``."""
1070
+
1071
+ subsystem: NotRequired[str]
1072
+ """Prometheus metric subsystem. Default: ``"driver"``."""
1073
+
1074
+ registry: NotRequired[Any]
1075
+ """Custom Prometheus registry (defaults to the global registry)."""
1076
+
1077
+ label_names: NotRequired[tuple[str, ...]]
1078
+ """Labels applied to metrics. Default: ("driver", "operation")."""
1079
+
1080
+ duration_buckets: NotRequired[tuple[float, ...]]
1081
+ """Histogram buckets for query duration (seconds)."""
1082
+
1083
+
1084
+ ExtensionConfigs: TypeAlias = dict[
1085
+ str,
1086
+ dict[str, Any]
1087
+ | LitestarConfig
1088
+ | FastAPIConfig
1089
+ | StarletteConfig
1090
+ | SanicConfig
1091
+ | FlaskConfig
1092
+ | ADKConfig
1093
+ | EventsConfig
1094
+ | OpenTelemetryConfig
1095
+ | PrometheusConfig,
1096
+ ]
1097
+
1098
+
1099
+ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
1100
+ """Protocol defining the stability-critical config contract.
1101
+
1102
+ Compiled callers rely on these attributes and methods remaining
1103
+ runtime-visible while ``sqlspec.config`` stays interpreted. Changes to
1104
+ migration setup, pool/session provider behavior, storage capabilities, or
1105
+ observability bootstrap must preserve this contract or move behind a
1106
+ separately verified compiled helper boundary.
1107
+ """
1108
+
1109
+ __slots__ = (
1110
+ "_migration_commands",
1111
+ "_migration_config",
1112
+ "_migration_loader",
1113
+ "_observability_runtime",
1114
+ "_storage_capabilities",
1115
+ "bind_key",
1116
+ "connection_instance",
1117
+ "driver_features",
1118
+ "extension_config",
1119
+ "observability_config",
1120
+ "statement_config",
1121
+ )
1122
+
1123
+ _migration_loader: "SQLFileLoader"
1124
+ _migration_commands: "SyncMigrationCommands[Any] | AsyncMigrationCommands[Any]"
1125
+ _migration_config: "dict[str, Any] | MigrationConfig"
1126
+ driver_type: "ClassVar[type[Any]]"
1127
+ connection_type: "ClassVar[type[Any]]"
1128
+ is_async: "ClassVar[bool]" = False
1129
+ supports_connection_pooling: "ClassVar[bool]" = False
1130
+ supports_transactional_ddl: "ClassVar[bool]" = False
1131
+ supports_native_arrow_import: "ClassVar[bool]" = False
1132
+ supports_native_arrow_export: "ClassVar[bool]" = False
1133
+ supports_native_parquet_import: "ClassVar[bool]" = False
1134
+ supports_native_parquet_export: "ClassVar[bool]" = False
1135
+ requires_staging_for_load: "ClassVar[bool]" = False
1136
+ staging_protocols: "ClassVar[tuple[str, ...]]" = ()
1137
+ default_storage_profile: "ClassVar[str | None]" = None
1138
+ storage_partition_strategies: "ClassVar[tuple[str, ...]]" = ("fixed",)
1139
+ bind_key: "str | None"
1140
+ statement_config: "StatementConfig"
1141
+ connection_instance: "PoolT | None"
1142
+ extension_config: "ExtensionConfigs"
1143
+ driver_features: "dict[str, Any]"
1144
+ _storage_capabilities: "StorageCapabilities | None"
1145
+ observability_config: "ObservabilityConfig | None"
1146
+ _observability_runtime: "ObservabilityRuntime | None"
1147
+
1148
+ def __hash__(self) -> int:
1149
+ return id(self)
1150
+
1151
+ def __eq__(self, other: object) -> bool:
1152
+ if not isinstance(other, type(self)):
1153
+ return False
1154
+ return bool(
1155
+ self.connection_instance == other.connection_instance and self.migration_config == other.migration_config
1156
+ )
1157
+
1158
+ def __repr__(self) -> str:
1159
+ parts = ", ".join([
1160
+ f"connection_instance={self.connection_instance!r}",
1161
+ f"migration_config={self.migration_config!r}",
1162
+ ])
1163
+ return f"{type(self).__name__}({parts})"
1164
+
1165
+ @property
1166
+ def migration_config(self) -> "dict[str, Any] | MigrationConfig":
1167
+ """Return the current migration configuration."""
1168
+ return self._migration_config
1169
+
1170
+ @migration_config.setter
1171
+ def migration_config(self, value: "dict[str, Any] | MigrationConfig | None") -> None:
1172
+ """Store migration configuration and refresh derived migration helpers."""
1173
+ object.__setattr__(self, "_migration_config", dict(cast("dict[str, Any]", value) or {}))
1174
+ if self._has_initialized_attribute("extension_config"):
1175
+ self._ensure_extension_migrations()
1176
+ if self._migration_components_ready():
1177
+ self._initialize_migration_components()
1178
+
1179
+ def set_migration_config(self, config: "dict[str, Any] | MigrationConfig") -> None:
1180
+ """Attach migration configuration after initial config creation.
1181
+
1182
+ This is equivalent to setting ``migration_config`` directly but provides
1183
+ a discoverable method for post-construction configuration.
1184
+
1185
+ Args:
1186
+ config: Migration configuration dictionary.
1187
+ """
1188
+ self.migration_config = config
1189
+
1190
+ def storage_capabilities(self) -> "StorageCapabilities":
1191
+ """Return cached storage capabilities for this configuration."""
1192
+
1193
+ if self._storage_capabilities is None:
1194
+ self._storage_capabilities = self._build_storage_capabilities()
1195
+ return cast("StorageCapabilities", dict(self._storage_capabilities))
1196
+
1197
+ def reset_storage_capabilities_cache(self) -> None:
1198
+ """Clear the cached capability snapshot."""
1199
+
1200
+ self._storage_capabilities = None
1201
+
1202
+ def _has_initialized_attribute(self, attribute_name: str) -> bool:
1203
+ """Return whether a slot-backed attribute has been initialized."""
1204
+ try:
1205
+ object.__getattribute__(self, attribute_name)
1206
+ except AttributeError:
1207
+ return False
1208
+ return True
1209
+
1210
+ def _migration_components_ready(self) -> bool:
1211
+ """Return whether migration helpers have already been initialized."""
1212
+ return self._has_initialized_attribute("_migration_loader") and self._has_initialized_attribute(
1213
+ "_migration_commands"
1214
+ )
1215
+
1216
+ def _ensure_extension_migrations(self) -> None:
1217
+ """Auto-include extension migrations when extension_config has them configured.
1218
+
1219
+ Extensions with migration support are automatically included in
1220
+ ``migration_config["include_extensions"]`` based on their settings:
1221
+
1222
+ - **litestar**: Only when ``session_table`` is set (for session storage)
1223
+ - **adk**: When any adk settings are present
1224
+ - **events**: When any events settings are present
1225
+
1226
+ Use ``exclude_extensions`` to opt out of auto-inclusion.
1227
+ """
1228
+ extension_settings = cast("dict[str, Any]", self.extension_config)
1229
+ migration_config = cast("dict[str, Any]", self.migration_config)
1230
+
1231
+ exclude_extensions = migration_config.get("exclude_extensions", [])
1232
+ if isinstance(exclude_extensions, tuple):
1233
+ exclude_extensions = list(exclude_extensions) # pyright: ignore
1234
+
1235
+ extensions_to_add: list[str] = []
1236
+
1237
+ litestar_settings = extension_settings.get("litestar")
1238
+ if (
1239
+ litestar_settings is not None
1240
+ and "session_table" in litestar_settings
1241
+ and "litestar" not in exclude_extensions
1242
+ ):
1243
+ extensions_to_add.append("litestar")
1244
+
1245
+ adk_settings = extension_settings.get("adk")
1246
+ if adk_settings is not None and "adk" not in exclude_extensions:
1247
+ from sqlspec.extensions.adk._config_utils import _validate_adk_store_registration
1248
+
1249
+ _validate_adk_store_registration(self)
1250
+ extensions_to_add.append("adk")
1251
+
1252
+ events_settings = extension_settings.get("events")
1253
+ if events_settings is not None and "events" not in exclude_extensions:
1254
+ extensions_to_add.append("events")
1255
+
1256
+ if not extensions_to_add:
1257
+ return
1258
+
1259
+ include_extensions = migration_config.get("include_extensions")
1260
+ if include_extensions is None:
1261
+ include_list: list[str] = []
1262
+ migration_config["include_extensions"] = include_list
1263
+ elif isinstance(include_extensions, tuple):
1264
+ include_list = list(include_extensions) # pyright: ignore
1265
+ migration_config["include_extensions"] = include_list
1266
+ else:
1267
+ include_list = cast("list[str]", include_extensions)
1268
+
1269
+ for ext in extensions_to_add:
1270
+ if ext not in include_list:
1271
+ include_list.append(ext)
1272
+
1273
+ def get_event_runtime_hints(self) -> "EventRuntimeHints":
1274
+ """Return default event runtime hints for this configuration."""
1275
+
1276
+ return EventRuntimeHints()
1277
+
1278
+ def _build_storage_capabilities(self) -> "StorageCapabilities":
1279
+ arrow_dependency_needed = self.supports_native_arrow_export or self.supports_native_arrow_import
1280
+ parquet_dependency_needed = self.supports_native_parquet_export or self.supports_native_parquet_import
1281
+
1282
+ arrow_dependency_ready = self._dependency_available(ensure_pyarrow) if arrow_dependency_needed else False
1283
+ parquet_dependency_ready = self._dependency_available(ensure_pyarrow) if parquet_dependency_needed else False
1284
+
1285
+ capabilities: StorageCapabilities = {
1286
+ "arrow_export_enabled": bool(self.supports_native_arrow_export and arrow_dependency_ready),
1287
+ "arrow_import_enabled": bool(self.supports_native_arrow_import and arrow_dependency_ready),
1288
+ "parquet_export_enabled": bool(self.supports_native_parquet_export and parquet_dependency_ready),
1289
+ "parquet_import_enabled": bool(self.supports_native_parquet_import and parquet_dependency_ready),
1290
+ "requires_staging_for_load": self.requires_staging_for_load,
1291
+ "staging_protocols": list(self.staging_protocols),
1292
+ "partition_strategies": list(self.storage_partition_strategies),
1293
+ }
1294
+ if self.default_storage_profile is not None:
1295
+ capabilities["default_storage_profile"] = self.default_storage_profile
1296
+ return capabilities
1297
+
1298
+ def _init_observability(self, observability_config: "ObservabilityConfig | None" = None) -> None:
1299
+ """Initialize observability attributes for the configuration."""
1300
+
1301
+ self.observability_config = observability_config
1302
+ self._observability_runtime = None
1303
+
1304
+ def _configure_observability_extensions(self) -> None:
1305
+ """Apply extension_config hooks (otel/prometheus) to ObservabilityConfig."""
1306
+
1307
+ config_map = cast("dict[str, Any]", self.extension_config)
1308
+ if not config_map:
1309
+ return
1310
+ updated = self.observability_config
1311
+
1312
+ otel_config = cast("OpenTelemetryConfig | None", config_map.get("otel"))
1313
+ if otel_config and otel_config.get("enabled", True):
1314
+ from sqlspec.extensions import otel as otel_extension
1315
+
1316
+ updated = otel_extension.enable_tracing(
1317
+ base_config=updated,
1318
+ resource_attributes=otel_config.get("resource_attributes"),
1319
+ tracer_provider=otel_config.get("tracer_provider"),
1320
+ tracer_provider_factory=otel_config.get("tracer_provider_factory"),
1321
+ enable_spans=otel_config.get("enable_spans", True),
1322
+ )
1323
+
1324
+ prom_config = cast("PrometheusConfig | None", config_map.get("prometheus"))
1325
+ if prom_config and prom_config.get("enabled", True):
1326
+ from sqlspec.extensions import prometheus as prometheus_extension
1327
+
1328
+ label_names = tuple(prom_config.get("label_names", ("driver", "operation")))
1329
+ duration_buckets = prom_config.get("duration_buckets")
1330
+ if duration_buckets is not None:
1331
+ duration_buckets = tuple(duration_buckets)
1332
+
1333
+ updated = prometheus_extension.enable_metrics(
1334
+ base_config=updated,
1335
+ namespace=prom_config.get("namespace", "sqlspec"),
1336
+ subsystem=prom_config.get("subsystem", "driver"),
1337
+ registry=prom_config.get("registry"),
1338
+ label_names=label_names,
1339
+ duration_buckets=duration_buckets,
1340
+ )
1341
+
1342
+ if updated is not self.observability_config:
1343
+ self.observability_config = updated
1344
+
1345
+ def _promote_driver_feature_hooks(self) -> None:
1346
+ lifecycle_hooks: dict[str, list[Callable[[dict[str, Any]], None]]] = {}
1347
+
1348
+ for hook_name, context_key in DRIVER_FEATURE_LIFECYCLE_HOOKS.items():
1349
+ callback = self.driver_features.pop(hook_name, None)
1350
+ if callback is None:
1351
+ continue
1352
+ callbacks = callback if isinstance(callback, (list, tuple)) else (callback,) # pyright: ignore
1353
+ wrapped_callbacks = [self._wrap_driver_feature_hook(cb, context_key) for cb in callbacks] # pyright: ignore
1354
+ lifecycle_hooks.setdefault(hook_name, []).extend(wrapped_callbacks)
1355
+
1356
+ if not lifecycle_hooks:
1357
+ return
1358
+
1359
+ lifecycle_config = cast("LifecycleConfig", lifecycle_hooks)
1360
+ override = ObservabilityConfig(lifecycle=lifecycle_config)
1361
+ if self.observability_config is None:
1362
+ self.observability_config = override
1363
+ else:
1364
+ self.observability_config = ObservabilityConfig.merge(self.observability_config, override)
1365
+
1366
+ @staticmethod
1367
+ def _wrap_driver_feature_hook(
1368
+ callback: Callable[..., Any], context_key: str | None
1369
+ ) -> Callable[[dict[str, Any]], None]:
1370
+ try:
1371
+ hook_signature: Signature = signature(callback)
1372
+ except (TypeError, ValueError): # pragma: no cover - builtins without signatures
1373
+ hook_signature = Signature()
1374
+
1375
+ positional_params = [
1376
+ param
1377
+ for param in hook_signature.parameters.values()
1378
+ if param.kind in {param.POSITIONAL_ONLY, param.POSITIONAL_OR_KEYWORD} and param.default is param.empty
1379
+ ]
1380
+ expects_argument = bool(positional_params)
1381
+
1382
+ return _DriverFeatureHookWrapper(callback, context_key, expects_argument)
1383
+
1384
+ def attach_observability(self, registry_config: "ObservabilityConfig | None") -> None:
1385
+ """Attach merged observability runtime composed from registry and adapter overrides."""
1386
+ merged = ObservabilityConfig.merge(registry_config, self.observability_config)
1387
+ self._observability_runtime = ObservabilityRuntime(
1388
+ merged, bind_key=self.bind_key, config_name=type(self).__name__
1389
+ )
1390
+
1391
+ def get_observability_runtime(self) -> "ObservabilityRuntime":
1392
+ """Return the attached runtime, creating a disabled instance when missing."""
1393
+
1394
+ if self._observability_runtime is None:
1395
+ self.attach_observability(None)
1396
+ assert self._observability_runtime is not None
1397
+ return self._observability_runtime
1398
+
1399
+ def _prepare_driver(self, driver: DriverT) -> DriverT:
1400
+ """Attach observability runtime to driver instances before returning them."""
1401
+
1402
+ driver.attach_observability(self.get_observability_runtime())
1403
+ return driver
1404
+
1405
+ @staticmethod
1406
+ def _dependency_available(checker: "Callable[[], None]") -> bool:
1407
+ try:
1408
+ checker()
1409
+ except MissingDependencyError:
1410
+ return False
1411
+ return True
1412
+
1413
+ @abstractmethod
1414
+ def create_connection(self) -> "ConnectionT | Awaitable[ConnectionT]":
1415
+ """Create and return a new database connection."""
1416
+ raise NotImplementedError
1417
+
1418
+ @abstractmethod
1419
+ def provide_connection(
1420
+ self, *args: Any, **kwargs: Any
1421
+ ) -> "AbstractContextManager[ConnectionT] | AbstractAsyncContextManager[ConnectionT]":
1422
+ """Provide a database connection context manager."""
1423
+ raise NotImplementedError
1424
+
1425
+ @abstractmethod
1426
+ def provide_session(
1427
+ self, *args: Any, **kwargs: Any
1428
+ ) -> "AbstractContextManager[DriverT] | AbstractAsyncContextManager[DriverT]":
1429
+ """Provide a database session context manager."""
1430
+ raise NotImplementedError
1431
+
1432
+ @abstractmethod
1433
+ def create_pool(self) -> "PoolT | Awaitable[PoolT]":
1434
+ """Create and return connection pool."""
1435
+ raise NotImplementedError
1436
+
1437
+ @abstractmethod
1438
+ def close_pool(self) -> "Awaitable[None] | None":
1439
+ """Terminate the connection pool."""
1440
+ raise NotImplementedError
1441
+
1442
+ @abstractmethod
1443
+ def provide_pool(
1444
+ self, *args: Any, **kwargs: Any
1445
+ ) -> "PoolT | Awaitable[PoolT] | AbstractContextManager[PoolT] | AbstractAsyncContextManager[PoolT]":
1446
+ """Provide pool instance."""
1447
+ raise NotImplementedError
1448
+
1449
+ def get_signature_namespace(self) -> "dict[str, Any]":
1450
+ """Get the signature namespace for this database configuration.
1451
+
1452
+ Returns a dictionary of type names to objects (classes, functions, or
1453
+ other callables) that should be registered with Litestar's signature
1454
+ namespace to prevent serialization attempts on database-specific
1455
+ structures.
1456
+
1457
+ Returns:
1458
+ Dictionary mapping type names to objects.
1459
+ """
1460
+ return {}
1461
+
1462
+ def _initialize_migration_components(self) -> None:
1463
+ """Initialize migration loader and migration command helpers."""
1464
+ runtime = self.get_observability_runtime()
1465
+ self._migration_loader = SQLFileLoader(runtime=runtime)
1466
+ self._migration_commands = create_migration_commands(self) # pyright: ignore
1467
+
1468
+ def _ensure_migration_loader(self) -> "SQLFileLoader":
1469
+ """Get the migration SQL loader and auto-load files if needed.
1470
+
1471
+ Returns:
1472
+ SQLFileLoader instance for migration files.
1473
+ """
1474
+ migration_config = self.migration_config or {}
1475
+ script_location = migration_config.get("script_location", "migrations")
1476
+
1477
+ migration_path = Path(script_location)
1478
+ if migration_path.exists() and not self._migration_loader.list_files():
1479
+ self._migration_loader.load_sql(migration_path)
1480
+ logger.debug("Auto-loaded migration SQL files from %s", migration_path)
1481
+
1482
+ return self._migration_loader
1483
+
1484
+ def _ensure_migration_commands(self) -> "SyncMigrationCommands[Any] | AsyncMigrationCommands[Any]":
1485
+ """Get the migration commands instance.
1486
+
1487
+ Returns:
1488
+ MigrationCommands instance for this config.
1489
+ """
1490
+ return self._migration_commands
1491
+
1492
+ def get_migration_loader(self) -> "SQLFileLoader":
1493
+ """Get the SQL loader for migration files.
1494
+
1495
+ Provides access to migration SQL files loaded from the configured
1496
+ script_location directory. Files are loaded lazily on first access.
1497
+
1498
+ Returns:
1499
+ SQLFileLoader instance with migration files loaded.
1500
+ """
1501
+ return self._ensure_migration_loader()
1502
+
1503
+ def load_migration_sql_files(self, *paths: "str | Path") -> None:
1504
+ """Load additional migration SQL files from specified paths.
1505
+
1506
+ Args:
1507
+ *paths: One or more file paths or directory paths to load migration SQL files from.
1508
+ """
1509
+
1510
+ loader = self._ensure_migration_loader()
1511
+ for path in paths:
1512
+ path_obj = Path(path)
1513
+ if path_obj.exists():
1514
+ loader.load_sql(path_obj)
1515
+ logger.debug("Loaded migration SQL files from %s", path_obj)
1516
+ else:
1517
+ logger.warning("Migration path does not exist: %s", path_obj)
1518
+
1519
+ def get_migration_commands(self) -> "SyncMigrationCommands[Any] | AsyncMigrationCommands[Any]":
1520
+ """Get migration commands for this configuration.
1521
+
1522
+ Returns:
1523
+ MigrationCommands instance configured for this database.
1524
+ """
1525
+ return self._ensure_migration_commands()
1526
+
1527
+ @abstractmethod
1528
+ def migrate_up(
1529
+ self,
1530
+ revision: str = "head",
1531
+ allow_missing: bool = False,
1532
+ auto_sync: bool = True,
1533
+ dry_run: bool = False,
1534
+ *,
1535
+ use_logger: bool = False,
1536
+ echo: bool | None = None,
1537
+ summary_only: bool | None = None,
1538
+ ) -> "Awaitable[None] | None":
1539
+ """Apply database migrations up to specified revision.
1540
+
1541
+ Args:
1542
+ revision: Target revision or "head" for latest. Defaults to "head".
1543
+ allow_missing: Allow out-of-order migrations. Defaults to False.
1544
+ auto_sync: Auto-reconcile renamed migrations. Defaults to True.
1545
+ dry_run: Show what would be done without applying. Defaults to False.
1546
+ use_logger: Use Python logger instead of Rich console for output.
1547
+ Defaults to False. Can be set via MigrationConfig for persistent default.
1548
+ echo: Echo output to the console. Defaults to True when unset.
1549
+ summary_only: Emit a single summary log entry when logger output is enabled.
1550
+ """
1551
+ raise NotImplementedError
1552
+
1553
+ @abstractmethod
1554
+ def migrate_down(
1555
+ self,
1556
+ revision: str = "-1",
1557
+ *,
1558
+ dry_run: bool = False,
1559
+ use_logger: bool = False,
1560
+ echo: bool | None = None,
1561
+ summary_only: bool | None = None,
1562
+ ) -> "Awaitable[None] | None":
1563
+ """Apply database migrations down to specified revision.
1564
+
1565
+ Args:
1566
+ revision: Target revision, "-1" for one step back, or "base" for all migrations. Defaults to "-1".
1567
+ dry_run: Show what would be done without applying. Defaults to False.
1568
+ use_logger: Use Python logger instead of Rich console for output.
1569
+ Defaults to False. Can be set via MigrationConfig for persistent default.
1570
+ echo: Echo output to the console. Defaults to True when unset.
1571
+ summary_only: Emit a single summary log entry when logger output is enabled.
1572
+ """
1573
+ raise NotImplementedError
1574
+
1575
+ @abstractmethod
1576
+ def get_current_migration(self, verbose: bool = False) -> "Awaitable[str | None] | str | None":
1577
+ """Get the current migration version.
1578
+
1579
+ Args:
1580
+ verbose: Whether to show detailed migration history. Defaults to False.
1581
+
1582
+ Returns:
1583
+ Current migration version or None if no migrations applied.
1584
+ """
1585
+ raise NotImplementedError
1586
+
1587
+ @abstractmethod
1588
+ def create_migration(self, message: str, file_type: str = "sql") -> "Awaitable[None] | None":
1589
+ """Create a new migration file.
1590
+
1591
+ Args:
1592
+ message: Description for the migration.
1593
+ file_type: Type of migration file to create ('sql' or 'py'). Defaults to 'sql'.
1594
+ """
1595
+ raise NotImplementedError
1596
+
1597
+ @abstractmethod
1598
+ def init_migrations(self, directory: "str | None" = None, package: bool = True) -> "Awaitable[None] | None":
1599
+ """Initialize migration directory structure.
1600
+
1601
+ Args:
1602
+ directory: Directory to initialize migrations in. Uses script_location from migration_config if not provided.
1603
+ package: Whether to create __init__.py file. Defaults to True.
1604
+ """
1605
+ raise NotImplementedError
1606
+
1607
+ @abstractmethod
1608
+ def stamp_migration(self, revision: str) -> "Awaitable[None] | None":
1609
+ """Mark database as being at a specific revision without running migrations.
1610
+
1611
+ Args:
1612
+ revision: The revision to stamp.
1613
+ """
1614
+ raise NotImplementedError
1615
+
1616
+ @abstractmethod
1617
+ def fix_migrations(
1618
+ self, dry_run: bool = False, update_database: bool = True, yes: bool = False
1619
+ ) -> "Awaitable[None] | None":
1620
+ """Convert timestamp migrations to sequential format.
1621
+
1622
+ Implements hybrid versioning workflow where development uses timestamps
1623
+ and production uses sequential numbers. Creates backup before changes
1624
+ and provides rollback on errors.
1625
+
1626
+ Args:
1627
+ dry_run: Preview changes without applying. Defaults to False.
1628
+ update_database: Update migration records in database. Defaults to True.
1629
+ yes: Skip confirmation prompt. Defaults to False.
1630
+ """
1631
+ raise NotImplementedError
1632
+
1633
+
1634
+ class NoPoolSyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
1635
+ """Base class for sync database configurations that do not implement a pool."""
1636
+
1637
+ __slots__ = ("connection_config",)
1638
+ is_async: "ClassVar[bool]" = False
1639
+ supports_connection_pooling: "ClassVar[bool]" = False
1640
+ migration_tracker_type: "ClassVar[type[Any]]" = SyncMigrationTracker
1641
+
1642
+ def __init__(
1643
+ self,
1644
+ *,
1645
+ connection_config: dict[str, Any] | None = None,
1646
+ connection_instance: "Any" = None,
1647
+ migration_config: "dict[str, Any] | MigrationConfig | None" = None,
1648
+ statement_config: "StatementConfig | None" = None,
1649
+ driver_features: "dict[str, Any] | None" = None,
1650
+ bind_key: "str | None" = None,
1651
+ extension_config: "ExtensionConfigs | None" = None,
1652
+ observability_config: "ObservabilityConfig | None" = None,
1653
+ ) -> None:
1654
+ self.bind_key = bind_key
1655
+ self.connection_instance = connection_instance
1656
+ self.connection_config = connection_config or {}
1657
+ self.extension_config = extension_config or {}
1658
+ self.migration_config = migration_config or {}
1659
+ self._init_observability(observability_config)
1660
+ self._initialize_migration_components()
1661
+
1662
+ self._storage_capabilities = None
1663
+ self.statement_config = statement_config or build_default_statement_config("sqlite")
1664
+
1665
+ self.driver_features = seed_runtime_driver_features(driver_features, self.storage_capabilities())
1666
+ self._promote_driver_feature_hooks()
1667
+ self._configure_observability_extensions()
1668
+
1669
+ def create_connection(self) -> ConnectionT:
1670
+ """Create a database connection."""
1671
+ raise NotImplementedError
1672
+
1673
+ def provide_connection(self, *args: Any, **kwargs: Any) -> "AbstractContextManager[ConnectionT]":
1674
+ """Provide a database connection context manager."""
1675
+ raise NotImplementedError
1676
+
1677
+ def provide_session(
1678
+ self, *args: Any, statement_config: "StatementConfig | None" = None, **kwargs: Any
1679
+ ) -> "AbstractContextManager[DriverT]":
1680
+ """Provide a database session context manager."""
1681
+ raise NotImplementedError
1682
+
1683
+ def create_pool(self) -> None:
1684
+ return None
1685
+
1686
+ def close_pool(self) -> None:
1687
+ return None
1688
+
1689
+ def provide_pool(self, *args: Any, **kwargs: Any) -> None:
1690
+ return None
1691
+
1692
+ def migrate_up(
1693
+ self,
1694
+ revision: str = "head",
1695
+ allow_missing: bool = False,
1696
+ auto_sync: bool = True,
1697
+ dry_run: bool = False,
1698
+ *,
1699
+ use_logger: bool = False,
1700
+ echo: bool | None = None,
1701
+ summary_only: bool | None = None,
1702
+ ) -> None:
1703
+ """Apply database migrations up to specified revision.
1704
+
1705
+ Args:
1706
+ revision: Target revision or "head" for latest.
1707
+ allow_missing: Allow out-of-order migrations.
1708
+ auto_sync: Auto-reconcile renamed migrations.
1709
+ dry_run: Show what would be done without applying.
1710
+ use_logger: Use Python logger instead of Rich console for output.
1711
+ echo: Echo output to the console. Defaults to True when unset.
1712
+ summary_only: Emit a single summary log entry when logger output is enabled.
1713
+ """
1714
+ commands = self._ensure_migration_commands()
1715
+ commands.upgrade(
1716
+ revision, allow_missing, auto_sync, dry_run, use_logger=use_logger, echo=echo, summary_only=summary_only
1717
+ )
1718
+
1719
+ def migrate_down(
1720
+ self,
1721
+ revision: str = "-1",
1722
+ *,
1723
+ dry_run: bool = False,
1724
+ use_logger: bool = False,
1725
+ echo: bool | None = None,
1726
+ summary_only: bool | None = None,
1727
+ ) -> None:
1728
+ """Apply database migrations down to specified revision.
1729
+
1730
+ Args:
1731
+ revision: Target revision, "-1" for one step back, or "base" for all migrations.
1732
+ dry_run: Show what would be done without applying.
1733
+ use_logger: Use Python logger instead of Rich console for output.
1734
+ echo: Echo output to the console. Defaults to True when unset.
1735
+ summary_only: Emit a single summary log entry when logger output is enabled.
1736
+ """
1737
+ commands = self._ensure_migration_commands()
1738
+ commands.downgrade(revision, dry_run=dry_run, use_logger=use_logger, echo=echo, summary_only=summary_only)
1739
+
1740
+ def get_current_migration(self, verbose: bool = False) -> "str | None":
1741
+ """Get the current migration version.
1742
+
1743
+ Args:
1744
+ verbose: Whether to show detailed migration history.
1745
+
1746
+ Returns:
1747
+ Current migration version or None if no migrations applied.
1748
+ """
1749
+ commands = cast("SyncMigrationCommands[Any]", self._ensure_migration_commands())
1750
+ return commands.current(verbose=verbose)
1751
+
1752
+ def create_migration(self, message: str, file_type: str = "sql") -> None:
1753
+ """Create a new migration file.
1754
+
1755
+ Args:
1756
+ message: Description for the migration.
1757
+ file_type: Type of migration file to create ('sql' or 'py').
1758
+ """
1759
+ commands = self._ensure_migration_commands()
1760
+ commands.revision(message, file_type)
1761
+
1762
+ def init_migrations(self, directory: "str | None" = None, package: bool = True) -> None:
1763
+ """Initialize migration directory structure.
1764
+
1765
+ Args:
1766
+ directory: Directory to initialize migrations in.
1767
+ package: Whether to create __init__.py file.
1768
+ """
1769
+ if directory is None:
1770
+ migration_config = self.migration_config or {}
1771
+ directory = str(migration_config.get("script_location") or "migrations")
1772
+
1773
+ commands = self._ensure_migration_commands()
1774
+ assert directory is not None
1775
+ commands.init(directory, package)
1776
+
1777
+ def stamp_migration(self, revision: str) -> None:
1778
+ """Mark database as being at a specific revision without running migrations.
1779
+
1780
+ Args:
1781
+ revision: The revision to stamp.
1782
+ """
1783
+ commands = self._ensure_migration_commands()
1784
+ commands.stamp(revision)
1785
+
1786
+ def fix_migrations(self, dry_run: bool = False, update_database: bool = True, yes: bool = False) -> None:
1787
+ """Convert timestamp migrations to sequential format.
1788
+
1789
+ Args:
1790
+ dry_run: Preview changes without applying.
1791
+ update_database: Update migration records in database.
1792
+ yes: Skip confirmation prompt.
1793
+ """
1794
+ commands = self._ensure_migration_commands()
1795
+ commands.fix(dry_run, update_database, yes)
1796
+
1797
+
1798
+ class NoPoolAsyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
1799
+ """Base class for async database configurations that do not implement a pool."""
1800
+
1801
+ __slots__ = ("connection_config",)
1802
+ is_async: "ClassVar[bool]" = True
1803
+ supports_connection_pooling: "ClassVar[bool]" = False
1804
+ migration_tracker_type: "ClassVar[type[Any]]" = AsyncMigrationTracker
1805
+
1806
+ def __init__(
1807
+ self,
1808
+ *,
1809
+ connection_config: "dict[str, Any] | None" = None,
1810
+ connection_instance: "Any" = None,
1811
+ migration_config: "dict[str, Any] | MigrationConfig | None" = None,
1812
+ statement_config: "StatementConfig | None" = None,
1813
+ driver_features: "dict[str, Any] | None" = None,
1814
+ bind_key: "str | None" = None,
1815
+ extension_config: "ExtensionConfigs | None" = None,
1816
+ observability_config: "ObservabilityConfig | None" = None,
1817
+ ) -> None:
1818
+ self.bind_key = bind_key
1819
+ self.connection_instance = connection_instance
1820
+ self.connection_config = connection_config or {}
1821
+ self.extension_config = extension_config or {}
1822
+ self.migration_config = migration_config or {}
1823
+ self._init_observability(observability_config)
1824
+ self._initialize_migration_components()
1825
+
1826
+ self.statement_config = statement_config or build_default_statement_config("sqlite")
1827
+
1828
+ self._storage_capabilities = None
1829
+ self.driver_features = seed_runtime_driver_features(driver_features, self.storage_capabilities())
1830
+ self._promote_driver_feature_hooks()
1831
+ self._configure_observability_extensions()
1832
+
1833
+ async def create_connection(self) -> ConnectionT:
1834
+ """Create a database connection."""
1835
+ raise NotImplementedError
1836
+
1837
+ def provide_connection(self, *args: Any, **kwargs: Any) -> "AbstractAsyncContextManager[ConnectionT]":
1838
+ """Provide a database connection context manager."""
1839
+ raise NotImplementedError
1840
+
1841
+ def provide_session(
1842
+ self, *args: Any, statement_config: "StatementConfig | None" = None, **kwargs: Any
1843
+ ) -> "AbstractAsyncContextManager[DriverT]":
1844
+ """Provide a database session context manager."""
1845
+ raise NotImplementedError
1846
+
1847
+ async def create_pool(self) -> None:
1848
+ return None
1849
+
1850
+ async def close_pool(self) -> None:
1851
+ return None
1852
+
1853
+ def provide_pool(self, *args: Any, **kwargs: Any) -> None:
1854
+ return None
1855
+
1856
+ async def migrate_up(
1857
+ self,
1858
+ revision: str = "head",
1859
+ allow_missing: bool = False,
1860
+ auto_sync: bool = True,
1861
+ dry_run: bool = False,
1862
+ *,
1863
+ use_logger: bool = False,
1864
+ echo: bool | None = None,
1865
+ summary_only: bool | None = None,
1866
+ ) -> None:
1867
+ """Apply database migrations up to specified revision.
1868
+
1869
+ Args:
1870
+ revision: Target revision or "head" for latest.
1871
+ allow_missing: Allow out-of-order migrations.
1872
+ auto_sync: Auto-reconcile renamed migrations.
1873
+ dry_run: Show what would be done without applying.
1874
+ use_logger: Use Python logger instead of Rich console for output.
1875
+ echo: Echo output to the console. Defaults to True when unset.
1876
+ summary_only: Emit a single summary log entry when logger output is enabled.
1877
+ """
1878
+ commands = cast("AsyncMigrationCommands[Any]", self._ensure_migration_commands())
1879
+ await commands.upgrade(
1880
+ revision, allow_missing, auto_sync, dry_run, use_logger=use_logger, echo=echo, summary_only=summary_only
1881
+ )
1882
+
1883
+ async def migrate_down(
1884
+ self,
1885
+ revision: str = "-1",
1886
+ *,
1887
+ dry_run: bool = False,
1888
+ use_logger: bool = False,
1889
+ echo: bool | None = None,
1890
+ summary_only: bool | None = None,
1891
+ ) -> None:
1892
+ """Apply database migrations down to specified revision.
1893
+
1894
+ Args:
1895
+ revision: Target revision, "-1" for one step back, or "base" for all migrations.
1896
+ dry_run: Show what would be done without applying.
1897
+ use_logger: Use Python logger instead of Rich console for output.
1898
+ echo: Echo output to the console. Defaults to True when unset.
1899
+ summary_only: Emit a single summary log entry when logger output is enabled.
1900
+ """
1901
+ commands = cast("AsyncMigrationCommands[Any]", self._ensure_migration_commands())
1902
+ await commands.downgrade(revision, dry_run=dry_run, use_logger=use_logger, echo=echo, summary_only=summary_only)
1903
+
1904
+ async def get_current_migration(self, verbose: bool = False) -> "str | None":
1905
+ """Get the current migration version.
1906
+
1907
+ Args:
1908
+ verbose: Whether to show detailed migration history.
1909
+
1910
+ Returns:
1911
+ Current migration version or None if no migrations applied.
1912
+ """
1913
+ commands = cast("AsyncMigrationCommands[Any]", self._ensure_migration_commands())
1914
+ return await commands.current(verbose=verbose)
1915
+
1916
+ async def create_migration(self, message: str, file_type: str = "sql") -> None:
1917
+ """Create a new migration file.
1918
+
1919
+ Args:
1920
+ message: Description for the migration.
1921
+ file_type: Type of migration file to create ('sql' or 'py').
1922
+ """
1923
+ commands = cast("AsyncMigrationCommands[Any]", self._ensure_migration_commands())
1924
+ await commands.revision(message, file_type)
1925
+
1926
+ async def init_migrations(self, directory: "str | None" = None, package: bool = True) -> None:
1927
+ """Initialize migration directory structure.
1928
+
1929
+ Args:
1930
+ directory: Directory to initialize migrations in.
1931
+ package: Whether to create __init__.py file.
1932
+ """
1933
+ if directory is None:
1934
+ migration_config = self.migration_config or {}
1935
+ directory = str(migration_config.get("script_location") or "migrations")
1936
+
1937
+ commands = cast("AsyncMigrationCommands[Any]", self._ensure_migration_commands())
1938
+ assert directory is not None
1939
+ await commands.init(directory, package)
1940
+
1941
+ async def stamp_migration(self, revision: str) -> None:
1942
+ """Mark database as being at a specific revision without running migrations.
1943
+
1944
+ Args:
1945
+ revision: The revision to stamp.
1946
+ """
1947
+ commands = cast("AsyncMigrationCommands[Any]", self._ensure_migration_commands())
1948
+ await commands.stamp(revision)
1949
+
1950
+ async def fix_migrations(self, dry_run: bool = False, update_database: bool = True, yes: bool = False) -> None:
1951
+ """Convert timestamp migrations to sequential format.
1952
+
1953
+ Args:
1954
+ dry_run: Preview changes without applying.
1955
+ update_database: Update migration records in database.
1956
+ yes: Skip confirmation prompt.
1957
+ """
1958
+ commands = cast("AsyncMigrationCommands[Any]", self._ensure_migration_commands())
1959
+ await commands.fix(dry_run, update_database, yes)
1960
+
1961
+
1962
+ class SyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
1963
+ """Base class for sync database configurations with connection pooling."""
1964
+
1965
+ __slots__ = ("_pool_lock", "connection_config")
1966
+ is_async: "ClassVar[bool]" = False
1967
+ supports_connection_pooling: "ClassVar[bool]" = True
1968
+ migration_tracker_type: "ClassVar[type[Any]]" = SyncMigrationTracker
1969
+ _connection_context_class: "ClassVar[type[Any]]"
1970
+ _session_factory_class: "ClassVar[type[Any]]"
1971
+ _session_context_class: "ClassVar[type[Any]]"
1972
+ _default_statement_config: "ClassVar[StatementConfig]"
1973
+
1974
+ def __init__(
1975
+ self,
1976
+ *,
1977
+ connection_config: "dict[str, Any] | None" = None,
1978
+ connection_instance: "PoolT | None" = None,
1979
+ migration_config: "dict[str, Any] | MigrationConfig | None" = None,
1980
+ statement_config: "StatementConfig | None" = None,
1981
+ driver_features: "dict[str, Any] | None" = None,
1982
+ bind_key: "str | None" = None,
1983
+ extension_config: "ExtensionConfigs | None" = None,
1984
+ observability_config: "ObservabilityConfig | None" = None,
1985
+ **kwargs: Any,
1986
+ ) -> None:
1987
+ self.bind_key = bind_key
1988
+ self.connection_instance = connection_instance
1989
+ self.connection_config = connection_config or {}
1990
+ self.extension_config = extension_config or {}
1991
+ self.migration_config = migration_config or {}
1992
+ self._init_observability(observability_config)
1993
+ self._initialize_migration_components()
1994
+
1995
+ self.statement_config = statement_config or build_default_statement_config("postgres")
1996
+
1997
+ self._storage_capabilities = None
1998
+ self.driver_features = seed_runtime_driver_features(driver_features, self.storage_capabilities())
1999
+ self._promote_driver_feature_hooks()
2000
+ self._configure_observability_extensions()
2001
+ self._pool_lock = threading.Lock()
2002
+
2003
+ def create_pool(self) -> PoolT:
2004
+ """Create and return the connection pool.
2005
+
2006
+ Returns:
2007
+ The created pool.
2008
+ """
2009
+ existing_pool = self.connection_instance
2010
+ if existing_pool is not None:
2011
+ return existing_pool
2012
+
2013
+ created_pool = create_sync_pool(
2014
+ None,
2015
+ self._pool_lock,
2016
+ lambda: self.connection_instance,
2017
+ self._create_pool,
2018
+ self.get_observability_runtime().emit_pool_create,
2019
+ )
2020
+ self.connection_instance = created_pool
2021
+ return cast("PoolT", created_pool)
2022
+
2023
+ def close_pool(self) -> None:
2024
+ """Close the connection pool."""
2025
+ pool = self.connection_instance
2026
+ runtime = self.get_observability_runtime()
2027
+ close_sync_pool(pool, self._close_pool, runtime.emit_pool_destroy, runtime.emit_pool_destroying_sync)
2028
+ self.connection_instance = None
2029
+
2030
+ def provide_pool(self, *args: Any, **kwargs: Any) -> PoolT:
2031
+ """Provide pool instance."""
2032
+ return self.create_pool()
2033
+
2034
+ def create_connection(self) -> ConnectionT:
2035
+ """Create a database connection."""
2036
+ raise NotImplementedError
2037
+
2038
+ def provide_connection(self, *args: Any, **kwargs: Any) -> "AbstractContextManager[ConnectionT]":
2039
+ """Provide a database connection context manager."""
2040
+ return cast("AbstractContextManager[ConnectionT]", self._connection_context_class(self))
2041
+
2042
+ def provide_session(
2043
+ self, *args: Any, statement_config: "StatementConfig | None" = None, **kwargs: Any
2044
+ ) -> "AbstractContextManager[DriverT]":
2045
+ """Provide a database session context manager."""
2046
+ handler = self._session_factory_class(self)
2047
+ return cast(
2048
+ "AbstractContextManager[DriverT]",
2049
+ self._session_context_class(
2050
+ acquire_connection=handler.acquire_connection,
2051
+ release_connection=handler.release_connection,
2052
+ statement_config=statement_config or self.statement_config or self._default_statement_config,
2053
+ driver_features=self.driver_features,
2054
+ prepare_driver=self._prepare_driver,
2055
+ ),
2056
+ )
2057
+
2058
+ @abstractmethod
2059
+ def _create_pool(self) -> PoolT:
2060
+ """Actual pool creation implementation."""
2061
+ raise NotImplementedError
2062
+
2063
+ @abstractmethod
2064
+ def _close_pool(self) -> None:
2065
+ """Actual pool destruction implementation."""
2066
+ raise NotImplementedError
2067
+
2068
+ def migrate_up(
2069
+ self,
2070
+ revision: str = "head",
2071
+ allow_missing: bool = False,
2072
+ auto_sync: bool = True,
2073
+ dry_run: bool = False,
2074
+ *,
2075
+ use_logger: bool = False,
2076
+ echo: bool | None = None,
2077
+ summary_only: bool | None = None,
2078
+ ) -> None:
2079
+ """Apply database migrations up to specified revision.
2080
+
2081
+ Args:
2082
+ revision: Target revision or "head" for latest.
2083
+ allow_missing: Allow out-of-order migrations.
2084
+ auto_sync: Auto-reconcile renamed migrations.
2085
+ dry_run: Show what would be done without applying.
2086
+ use_logger: Use Python logger instead of Rich console for output.
2087
+ echo: Echo output to the console. Defaults to True when unset.
2088
+ summary_only: Emit a single summary log entry when logger output is enabled.
2089
+ """
2090
+ commands = self._ensure_migration_commands()
2091
+ commands.upgrade(
2092
+ revision, allow_missing, auto_sync, dry_run, use_logger=use_logger, echo=echo, summary_only=summary_only
2093
+ )
2094
+
2095
+ def migrate_down(
2096
+ self,
2097
+ revision: str = "-1",
2098
+ *,
2099
+ dry_run: bool = False,
2100
+ use_logger: bool = False,
2101
+ echo: bool | None = None,
2102
+ summary_only: bool | None = None,
2103
+ ) -> None:
2104
+ """Apply database migrations down to specified revision.
2105
+
2106
+ Args:
2107
+ revision: Target revision, "-1" for one step back, or "base" for all migrations.
2108
+ dry_run: Show what would be done without applying.
2109
+ use_logger: Use Python logger instead of Rich console for output.
2110
+ echo: Echo output to the console. Defaults to True when unset.
2111
+ summary_only: Emit a single summary log entry when logger output is enabled.
2112
+ """
2113
+ commands = self._ensure_migration_commands()
2114
+ commands.downgrade(revision, dry_run=dry_run, use_logger=use_logger, echo=echo, summary_only=summary_only)
2115
+
2116
+ def get_current_migration(self, verbose: bool = False) -> "str | None":
2117
+ """Get the current migration version.
2118
+
2119
+ Args:
2120
+ verbose: Whether to show detailed migration history.
2121
+
2122
+ Returns:
2123
+ Current migration version or None if no migrations applied.
2124
+ """
2125
+ commands = cast("SyncMigrationCommands[Any]", self._ensure_migration_commands())
2126
+ return commands.current(verbose=verbose)
2127
+
2128
+ def create_migration(self, message: str, file_type: str = "sql") -> None:
2129
+ """Create a new migration file.
2130
+
2131
+ Args:
2132
+ message: Description for the migration.
2133
+ file_type: Type of migration file to create ('sql' or 'py').
2134
+ """
2135
+ commands = self._ensure_migration_commands()
2136
+ commands.revision(message, file_type)
2137
+
2138
+ def init_migrations(self, directory: "str | None" = None, package: bool = True) -> None:
2139
+ """Initialize migration directory structure.
2140
+
2141
+ Args:
2142
+ directory: Directory to initialize migrations in.
2143
+ package: Whether to create __init__.py file.
2144
+ """
2145
+ if directory is None:
2146
+ migration_config = self.migration_config or {}
2147
+ directory = str(migration_config.get("script_location") or "migrations")
2148
+
2149
+ commands = self._ensure_migration_commands()
2150
+ assert directory is not None
2151
+ commands.init(directory, package)
2152
+
2153
+ def stamp_migration(self, revision: str) -> None:
2154
+ """Mark database as being at a specific revision without running migrations.
2155
+
2156
+ Args:
2157
+ revision: The revision to stamp.
2158
+ """
2159
+ commands = self._ensure_migration_commands()
2160
+ commands.stamp(revision)
2161
+
2162
+ def fix_migrations(self, dry_run: bool = False, update_database: bool = True, yes: bool = False) -> None:
2163
+ """Convert timestamp migrations to sequential format.
2164
+
2165
+ Args:
2166
+ dry_run: Preview changes without applying.
2167
+ update_database: Update migration records in database.
2168
+ yes: Skip confirmation prompt.
2169
+ """
2170
+ commands = self._ensure_migration_commands()
2171
+ commands.fix(dry_run, update_database, yes)
2172
+
2173
+
2174
+ class AsyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
2175
+ """Base class for async database configurations with connection pooling."""
2176
+
2177
+ __slots__ = ("_pool_lock", "connection_config")
2178
+ is_async: "ClassVar[bool]" = True
2179
+ supports_connection_pooling: "ClassVar[bool]" = True
2180
+ migration_tracker_type: "ClassVar[type[Any]]" = AsyncMigrationTracker
2181
+ _connection_context_class: "ClassVar[type[Any]]"
2182
+ _session_factory_class: "ClassVar[type[Any]]"
2183
+ _session_context_class: "ClassVar[type[Any]]"
2184
+ _default_statement_config: "ClassVar[StatementConfig]"
2185
+
2186
+ def __init__(
2187
+ self,
2188
+ *,
2189
+ connection_config: "dict[str, Any] | None" = None,
2190
+ connection_instance: "PoolT | None" = None,
2191
+ migration_config: "dict[str, Any] | MigrationConfig | None" = None,
2192
+ statement_config: "StatementConfig | None" = None,
2193
+ driver_features: "dict[str, Any] | None" = None,
2194
+ bind_key: "str | None" = None,
2195
+ extension_config: "ExtensionConfigs | None" = None,
2196
+ observability_config: "ObservabilityConfig | None" = None,
2197
+ **kwargs: Any,
2198
+ ) -> None:
2199
+ self.bind_key = bind_key
2200
+ self.connection_instance = connection_instance
2201
+ self.connection_config = connection_config or {}
2202
+ self.extension_config = extension_config or {}
2203
+ self.migration_config = migration_config or {}
2204
+ self._init_observability(observability_config)
2205
+ self._initialize_migration_components()
2206
+
2207
+ self.statement_config = statement_config or build_default_statement_config("postgres")
2208
+
2209
+ self._storage_capabilities = None
2210
+ self.driver_features = seed_runtime_driver_features(driver_features, self.storage_capabilities())
2211
+ self._promote_driver_feature_hooks()
2212
+ self._configure_observability_extensions()
2213
+ self._pool_lock = asyncio.Lock()
2214
+
2215
+ async def create_pool(self) -> PoolT:
2216
+ """Create and return the connection pool.
2217
+
2218
+ Returns:
2219
+ The created pool.
2220
+ """
2221
+ existing_pool = self.connection_instance
2222
+ if existing_pool is not None:
2223
+ return existing_pool
2224
+
2225
+ created_pool = await create_async_pool(
2226
+ None,
2227
+ self._pool_lock,
2228
+ lambda: self.connection_instance,
2229
+ self._create_pool,
2230
+ self.get_observability_runtime().emit_pool_create,
2231
+ )
2232
+ self.connection_instance = created_pool
2233
+ return cast("PoolT", created_pool)
2234
+
2235
+ async def close_pool(self) -> None:
2236
+ """Close the connection pool."""
2237
+ pool = self.connection_instance
2238
+ runtime = self.get_observability_runtime()
2239
+ await close_async_pool(pool, self._close_pool, runtime.emit_pool_destroy, runtime.emit_pool_destroying_async)
2240
+ self.connection_instance = None
2241
+
2242
+ async def provide_pool(self, *args: Any, **kwargs: Any) -> PoolT:
2243
+ """Provide pool instance."""
2244
+ return await self.create_pool()
2245
+
2246
+ async def create_connection(self) -> ConnectionT:
2247
+ """Create a database connection."""
2248
+ raise NotImplementedError
2249
+
2250
+ def provide_connection(self, *args: Any, **kwargs: Any) -> "AbstractAsyncContextManager[ConnectionT]":
2251
+ """Provide a database connection context manager."""
2252
+ return cast("AbstractAsyncContextManager[ConnectionT]", self._connection_context_class(self))
2253
+
2254
+ def provide_session(
2255
+ self, *args: Any, statement_config: "StatementConfig | None" = None, **kwargs: Any
2256
+ ) -> "AbstractAsyncContextManager[DriverT]":
2257
+ """Provide a database session context manager."""
2258
+ handler = self._session_factory_class(self)
2259
+ return cast(
2260
+ "AbstractAsyncContextManager[DriverT]",
2261
+ self._session_context_class(
2262
+ acquire_connection=handler.acquire_connection,
2263
+ release_connection=handler.release_connection,
2264
+ statement_config=statement_config or self.statement_config or self._default_statement_config,
2265
+ driver_features=self.driver_features,
2266
+ prepare_driver=self._prepare_driver,
2267
+ ),
2268
+ )
2269
+
2270
+ @abstractmethod
2271
+ async def _create_pool(self) -> PoolT:
2272
+ """Actual async pool creation implementation."""
2273
+ raise NotImplementedError
2274
+
2275
+ @abstractmethod
2276
+ async def _close_pool(self) -> None:
2277
+ """Actual async pool destruction implementation."""
2278
+ raise NotImplementedError
2279
+
2280
+ async def migrate_up(
2281
+ self,
2282
+ revision: str = "head",
2283
+ allow_missing: bool = False,
2284
+ auto_sync: bool = True,
2285
+ dry_run: bool = False,
2286
+ *,
2287
+ use_logger: bool = False,
2288
+ echo: bool | None = None,
2289
+ summary_only: bool | None = None,
2290
+ ) -> None:
2291
+ """Apply database migrations up to specified revision.
2292
+
2293
+ Args:
2294
+ revision: Target revision or "head" for latest.
2295
+ allow_missing: Allow out-of-order migrations.
2296
+ auto_sync: Auto-reconcile renamed migrations.
2297
+ dry_run: Show what would be done without applying.
2298
+ use_logger: Use Python logger instead of Rich console for output.
2299
+ echo: Echo output to the console. Defaults to True when unset.
2300
+ summary_only: Emit a single summary log entry when logger output is enabled.
2301
+ """
2302
+ commands = cast("AsyncMigrationCommands[Any]", self._ensure_migration_commands())
2303
+ await commands.upgrade(
2304
+ revision, allow_missing, auto_sync, dry_run, use_logger=use_logger, echo=echo, summary_only=summary_only
2305
+ )
2306
+
2307
+ async def migrate_down(
2308
+ self,
2309
+ revision: str = "-1",
2310
+ *,
2311
+ dry_run: bool = False,
2312
+ use_logger: bool = False,
2313
+ echo: bool | None = None,
2314
+ summary_only: bool | None = None,
2315
+ ) -> None:
2316
+ """Apply database migrations down to specified revision.
2317
+
2318
+ Args:
2319
+ revision: Target revision, "-1" for one step back, or "base" for all migrations.
2320
+ dry_run: Show what would be done without applying.
2321
+ use_logger: Use Python logger instead of Rich console for output.
2322
+ echo: Echo output to the console. Defaults to True when unset.
2323
+ summary_only: Emit a single summary log entry when logger output is enabled.
2324
+ """
2325
+ commands = cast("AsyncMigrationCommands[Any]", self._ensure_migration_commands())
2326
+ await commands.downgrade(revision, dry_run=dry_run, use_logger=use_logger, echo=echo, summary_only=summary_only)
2327
+
2328
+ async def get_current_migration(self, verbose: bool = False) -> "str | None":
2329
+ """Get the current migration version.
2330
+
2331
+ Args:
2332
+ verbose: Whether to show detailed migration history.
2333
+
2334
+ Returns:
2335
+ Current migration version or None if no migrations applied.
2336
+ """
2337
+ commands = cast("AsyncMigrationCommands[Any]", self._ensure_migration_commands())
2338
+ return await commands.current(verbose=verbose)
2339
+
2340
+ async def create_migration(self, message: str, file_type: str = "sql") -> None:
2341
+ """Create a new migration file.
2342
+
2343
+ Args:
2344
+ message: Description for the migration.
2345
+ file_type: Type of migration file to create ('sql' or 'py').
2346
+ """
2347
+ commands = cast("AsyncMigrationCommands[Any]", self._ensure_migration_commands())
2348
+ await commands.revision(message, file_type)
2349
+
2350
+ async def init_migrations(self, directory: "str | None" = None, package: bool = True) -> None:
2351
+ """Initialize migration directory structure.
2352
+
2353
+ Args:
2354
+ directory: Directory to initialize migrations in.
2355
+ package: Whether to create __init__.py file.
2356
+ """
2357
+ if directory is None:
2358
+ migration_config = self.migration_config or {}
2359
+ directory = str(migration_config.get("script_location") or "migrations")
2360
+
2361
+ commands = cast("AsyncMigrationCommands[Any]", self._ensure_migration_commands())
2362
+ assert directory is not None
2363
+ await commands.init(directory, package)
2364
+
2365
+ async def stamp_migration(self, revision: str) -> None:
2366
+ """Mark database as being at a specific revision without running migrations.
2367
+
2368
+ Args:
2369
+ revision: The revision to stamp.
2370
+ """
2371
+ commands = cast("AsyncMigrationCommands[Any]", self._ensure_migration_commands())
2372
+ await commands.stamp(revision)
2373
+
2374
+ async def fix_migrations(self, dry_run: bool = False, update_database: bool = True, yes: bool = False) -> None:
2375
+ """Convert timestamp migrations to sequential format.
2376
+
2377
+ Args:
2378
+ dry_run: Preview changes without applying.
2379
+ update_database: Update migration records in database.
2380
+ yes: Skip confirmation prompt.
2381
+ """
2382
+ commands = cast("AsyncMigrationCommands[Any]", self._ensure_migration_commands())
2383
+ await commands.fix(dry_run, update_database, yes)