sqlspec 0.13.1__py3-none-any.whl → 0.16.2__py3-none-any.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.
Potentially problematic release.
This version of sqlspec might be problematic. Click here for more details.
- sqlspec/__init__.py +71 -8
- sqlspec/__main__.py +12 -0
- sqlspec/__metadata__.py +1 -3
- sqlspec/_serialization.py +1 -2
- sqlspec/_sql.py +930 -136
- sqlspec/_typing.py +278 -142
- sqlspec/adapters/adbc/__init__.py +4 -3
- sqlspec/adapters/adbc/_types.py +12 -0
- sqlspec/adapters/adbc/config.py +116 -285
- sqlspec/adapters/adbc/driver.py +462 -340
- sqlspec/adapters/aiosqlite/__init__.py +18 -3
- sqlspec/adapters/aiosqlite/_types.py +13 -0
- sqlspec/adapters/aiosqlite/config.py +202 -150
- sqlspec/adapters/aiosqlite/driver.py +226 -247
- sqlspec/adapters/asyncmy/__init__.py +18 -3
- sqlspec/adapters/asyncmy/_types.py +12 -0
- sqlspec/adapters/asyncmy/config.py +80 -199
- sqlspec/adapters/asyncmy/driver.py +257 -215
- sqlspec/adapters/asyncpg/__init__.py +19 -4
- sqlspec/adapters/asyncpg/_types.py +17 -0
- sqlspec/adapters/asyncpg/config.py +81 -214
- sqlspec/adapters/asyncpg/driver.py +284 -359
- sqlspec/adapters/bigquery/__init__.py +17 -3
- sqlspec/adapters/bigquery/_types.py +12 -0
- sqlspec/adapters/bigquery/config.py +191 -299
- sqlspec/adapters/bigquery/driver.py +474 -634
- sqlspec/adapters/duckdb/__init__.py +14 -3
- sqlspec/adapters/duckdb/_types.py +12 -0
- sqlspec/adapters/duckdb/config.py +414 -397
- sqlspec/adapters/duckdb/driver.py +342 -393
- sqlspec/adapters/oracledb/__init__.py +19 -5
- sqlspec/adapters/oracledb/_types.py +14 -0
- sqlspec/adapters/oracledb/config.py +123 -458
- sqlspec/adapters/oracledb/driver.py +505 -531
- sqlspec/adapters/psqlpy/__init__.py +13 -3
- sqlspec/adapters/psqlpy/_types.py +11 -0
- sqlspec/adapters/psqlpy/config.py +93 -307
- sqlspec/adapters/psqlpy/driver.py +504 -213
- sqlspec/adapters/psycopg/__init__.py +19 -5
- sqlspec/adapters/psycopg/_types.py +17 -0
- sqlspec/adapters/psycopg/config.py +143 -472
- sqlspec/adapters/psycopg/driver.py +704 -825
- sqlspec/adapters/sqlite/__init__.py +14 -3
- sqlspec/adapters/sqlite/_types.py +11 -0
- sqlspec/adapters/sqlite/config.py +208 -142
- sqlspec/adapters/sqlite/driver.py +263 -278
- sqlspec/base.py +105 -9
- sqlspec/{statement/builder → builder}/__init__.py +12 -14
- sqlspec/{statement/builder/base.py → builder/_base.py} +184 -86
- sqlspec/{statement/builder/column.py → builder/_column.py} +97 -60
- sqlspec/{statement/builder/ddl.py → builder/_ddl.py} +61 -131
- sqlspec/{statement/builder → builder}/_ddl_utils.py +4 -10
- sqlspec/{statement/builder/delete.py → builder/_delete.py} +10 -30
- sqlspec/builder/_insert.py +421 -0
- sqlspec/builder/_merge.py +71 -0
- sqlspec/{statement/builder → builder}/_parsing_utils.py +49 -26
- sqlspec/builder/_select.py +170 -0
- sqlspec/{statement/builder/update.py → builder/_update.py} +16 -20
- sqlspec/builder/mixins/__init__.py +55 -0
- sqlspec/builder/mixins/_cte_and_set_ops.py +222 -0
- sqlspec/{statement/builder/mixins/_delete_from.py → builder/mixins/_delete_operations.py} +8 -1
- sqlspec/builder/mixins/_insert_operations.py +244 -0
- sqlspec/{statement/builder/mixins/_join.py → builder/mixins/_join_operations.py} +45 -13
- sqlspec/{statement/builder/mixins/_merge_clauses.py → builder/mixins/_merge_operations.py} +188 -30
- sqlspec/builder/mixins/_order_limit_operations.py +135 -0
- sqlspec/builder/mixins/_pivot_operations.py +153 -0
- sqlspec/builder/mixins/_select_operations.py +604 -0
- sqlspec/builder/mixins/_update_operations.py +202 -0
- sqlspec/builder/mixins/_where_clause.py +644 -0
- sqlspec/cli.py +247 -0
- sqlspec/config.py +183 -138
- sqlspec/core/__init__.py +63 -0
- sqlspec/core/cache.py +871 -0
- sqlspec/core/compiler.py +417 -0
- sqlspec/core/filters.py +830 -0
- sqlspec/core/hashing.py +310 -0
- sqlspec/core/parameters.py +1237 -0
- sqlspec/core/result.py +677 -0
- sqlspec/{statement → core}/splitter.py +321 -191
- sqlspec/core/statement.py +676 -0
- sqlspec/driver/__init__.py +7 -10
- sqlspec/driver/_async.py +422 -163
- sqlspec/driver/_common.py +545 -287
- sqlspec/driver/_sync.py +426 -160
- sqlspec/driver/mixins/__init__.py +2 -13
- sqlspec/driver/mixins/_result_tools.py +193 -0
- sqlspec/driver/mixins/_sql_translator.py +65 -14
- sqlspec/exceptions.py +5 -252
- sqlspec/extensions/aiosql/adapter.py +93 -96
- sqlspec/extensions/litestar/__init__.py +2 -1
- sqlspec/extensions/litestar/cli.py +48 -0
- sqlspec/extensions/litestar/config.py +0 -1
- sqlspec/extensions/litestar/handlers.py +15 -26
- sqlspec/extensions/litestar/plugin.py +21 -16
- sqlspec/extensions/litestar/providers.py +17 -52
- sqlspec/loader.py +423 -104
- sqlspec/migrations/__init__.py +35 -0
- sqlspec/migrations/base.py +414 -0
- sqlspec/migrations/commands.py +443 -0
- sqlspec/migrations/loaders.py +402 -0
- sqlspec/migrations/runner.py +213 -0
- sqlspec/migrations/tracker.py +140 -0
- sqlspec/migrations/utils.py +129 -0
- sqlspec/protocols.py +51 -186
- sqlspec/storage/__init__.py +1 -1
- sqlspec/storage/backends/base.py +37 -40
- sqlspec/storage/backends/fsspec.py +136 -112
- sqlspec/storage/backends/obstore.py +138 -160
- sqlspec/storage/capabilities.py +5 -4
- sqlspec/storage/registry.py +57 -106
- sqlspec/typing.py +136 -115
- sqlspec/utils/__init__.py +2 -2
- sqlspec/utils/correlation.py +0 -3
- sqlspec/utils/deprecation.py +6 -6
- sqlspec/utils/fixtures.py +6 -6
- sqlspec/utils/logging.py +0 -2
- sqlspec/utils/module_loader.py +7 -12
- sqlspec/utils/singleton.py +0 -1
- sqlspec/utils/sync_tools.py +17 -38
- sqlspec/utils/text.py +12 -51
- sqlspec/utils/type_guards.py +482 -235
- {sqlspec-0.13.1.dist-info → sqlspec-0.16.2.dist-info}/METADATA +7 -2
- sqlspec-0.16.2.dist-info/RECORD +134 -0
- sqlspec-0.16.2.dist-info/entry_points.txt +2 -0
- sqlspec/driver/connection.py +0 -207
- sqlspec/driver/mixins/_csv_writer.py +0 -91
- sqlspec/driver/mixins/_pipeline.py +0 -512
- sqlspec/driver/mixins/_result_utils.py +0 -140
- sqlspec/driver/mixins/_storage.py +0 -926
- sqlspec/driver/mixins/_type_coercion.py +0 -130
- sqlspec/driver/parameters.py +0 -138
- sqlspec/service/__init__.py +0 -4
- sqlspec/service/_util.py +0 -147
- sqlspec/service/base.py +0 -1131
- sqlspec/service/pagination.py +0 -26
- sqlspec/statement/__init__.py +0 -21
- sqlspec/statement/builder/insert.py +0 -288
- sqlspec/statement/builder/merge.py +0 -95
- sqlspec/statement/builder/mixins/__init__.py +0 -65
- sqlspec/statement/builder/mixins/_aggregate_functions.py +0 -250
- sqlspec/statement/builder/mixins/_case_builder.py +0 -91
- sqlspec/statement/builder/mixins/_common_table_expr.py +0 -90
- sqlspec/statement/builder/mixins/_from.py +0 -63
- sqlspec/statement/builder/mixins/_group_by.py +0 -118
- sqlspec/statement/builder/mixins/_having.py +0 -35
- sqlspec/statement/builder/mixins/_insert_from_select.py +0 -47
- sqlspec/statement/builder/mixins/_insert_into.py +0 -36
- sqlspec/statement/builder/mixins/_insert_values.py +0 -67
- sqlspec/statement/builder/mixins/_limit_offset.py +0 -53
- sqlspec/statement/builder/mixins/_order_by.py +0 -46
- sqlspec/statement/builder/mixins/_pivot.py +0 -79
- sqlspec/statement/builder/mixins/_returning.py +0 -37
- sqlspec/statement/builder/mixins/_select_columns.py +0 -61
- sqlspec/statement/builder/mixins/_set_ops.py +0 -122
- sqlspec/statement/builder/mixins/_unpivot.py +0 -77
- sqlspec/statement/builder/mixins/_update_from.py +0 -55
- sqlspec/statement/builder/mixins/_update_set.py +0 -94
- sqlspec/statement/builder/mixins/_update_table.py +0 -29
- sqlspec/statement/builder/mixins/_where.py +0 -401
- sqlspec/statement/builder/mixins/_window_functions.py +0 -86
- sqlspec/statement/builder/select.py +0 -221
- sqlspec/statement/filters.py +0 -596
- sqlspec/statement/parameter_manager.py +0 -220
- sqlspec/statement/parameters.py +0 -867
- sqlspec/statement/pipelines/__init__.py +0 -210
- sqlspec/statement/pipelines/analyzers/__init__.py +0 -9
- sqlspec/statement/pipelines/analyzers/_analyzer.py +0 -646
- sqlspec/statement/pipelines/context.py +0 -115
- sqlspec/statement/pipelines/transformers/__init__.py +0 -7
- sqlspec/statement/pipelines/transformers/_expression_simplifier.py +0 -88
- sqlspec/statement/pipelines/transformers/_literal_parameterizer.py +0 -1247
- sqlspec/statement/pipelines/transformers/_remove_comments_and_hints.py +0 -76
- sqlspec/statement/pipelines/validators/__init__.py +0 -23
- sqlspec/statement/pipelines/validators/_dml_safety.py +0 -290
- sqlspec/statement/pipelines/validators/_parameter_style.py +0 -370
- sqlspec/statement/pipelines/validators/_performance.py +0 -718
- sqlspec/statement/pipelines/validators/_security.py +0 -967
- sqlspec/statement/result.py +0 -435
- sqlspec/statement/sql.py +0 -1704
- sqlspec/statement/sql_compiler.py +0 -140
- sqlspec/utils/cached_property.py +0 -25
- sqlspec-0.13.1.dist-info/RECORD +0 -150
- {sqlspec-0.13.1.dist-info → sqlspec-0.16.2.dist-info}/WHEEL +0 -0
- {sqlspec-0.13.1.dist-info → sqlspec-0.16.2.dist-info}/licenses/LICENSE +0 -0
- {sqlspec-0.13.1.dist-info → sqlspec-0.16.2.dist-info}/licenses/NOTICE +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sqlspec
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.16.2
|
|
4
4
|
Summary: SQL Experiments in Python
|
|
5
5
|
Project-URL: Discord, https://discord.gg/litestar
|
|
6
6
|
Project-URL: Issue, https://github.com/litestar-org/sqlspec/issues/
|
|
@@ -11,8 +11,9 @@ License-Expression: MIT
|
|
|
11
11
|
License-File: LICENSE
|
|
12
12
|
License-File: NOTICE
|
|
13
13
|
Requires-Python: <4.0,>=3.9
|
|
14
|
-
Requires-Dist: click
|
|
15
14
|
Requires-Dist: eval-type-backport; python_version < '3.10'
|
|
15
|
+
Requires-Dist: mypy-extensions
|
|
16
|
+
Requires-Dist: rich-click
|
|
16
17
|
Requires-Dist: sqlglot>=19.9.0
|
|
17
18
|
Requires-Dist: typing-extensions
|
|
18
19
|
Provides-Extra: adbc
|
|
@@ -28,6 +29,9 @@ Provides-Extra: asyncmy
|
|
|
28
29
|
Requires-Dist: asyncmy; extra == 'asyncmy'
|
|
29
30
|
Provides-Extra: asyncpg
|
|
30
31
|
Requires-Dist: asyncpg; extra == 'asyncpg'
|
|
32
|
+
Provides-Extra: attrs
|
|
33
|
+
Requires-Dist: attrs; extra == 'attrs'
|
|
34
|
+
Requires-Dist: cattrs; extra == 'attrs'
|
|
31
35
|
Provides-Extra: bigquery
|
|
32
36
|
Requires-Dist: google-cloud-bigquery; extra == 'bigquery'
|
|
33
37
|
Provides-Extra: cli
|
|
@@ -44,6 +48,7 @@ Provides-Extra: litestar
|
|
|
44
48
|
Requires-Dist: litestar; extra == 'litestar'
|
|
45
49
|
Provides-Extra: msgspec
|
|
46
50
|
Requires-Dist: msgspec; extra == 'msgspec'
|
|
51
|
+
Provides-Extra: mypyc
|
|
47
52
|
Provides-Extra: nanoid
|
|
48
53
|
Requires-Dist: fastnanoid>=0.4.1; extra == 'nanoid'
|
|
49
54
|
Provides-Extra: obstore
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
sqlspec/__init__.py,sha256=8_TR9bXd7bkA4qBGCzTHNawH7KXaJ4YlnCJzJwvgud8,2066
|
|
2
|
+
sqlspec/__main__.py,sha256=lXBKZMOXA1uY735Rnsb-GS7aXy0nt22tYmd2X9FcxrY,253
|
|
3
|
+
sqlspec/__metadata__.py,sha256=IUw6MCTy1oeUJ1jAVYbuJLkOWbiAWorZ5W-E-SAD9N4,395
|
|
4
|
+
sqlspec/_serialization.py,sha256=6U5-smk2h2yl0i6am2prtOLJTdu4NJQdcLlSfSUMaUQ,2590
|
|
5
|
+
sqlspec/_sql.py,sha256=FIYp2u5NgIBc375Jkt2ZfA81Xs7ABcKY92A5rwWXuFE,60340
|
|
6
|
+
sqlspec/_typing.py,sha256=jv-7QHGLrJLfnP86bR-Xcmj3PDoddNZEKDz_vYRBiAU,22684
|
|
7
|
+
sqlspec/base.py,sha256=lVLzFD-nzEU6QnwnU0kRWh3XWjbvXWX0XnnUViYBoQk,21767
|
|
8
|
+
sqlspec/cli.py,sha256=3ZxPwl4neNWyrAkM9J9ccC_gaFigDJbhuZfx15JVE7E,9903
|
|
9
|
+
sqlspec/config.py,sha256=s7csxGK0SlTvB9jOvHlKKm4Y272RInQrUd6hGXwy31Q,14974
|
|
10
|
+
sqlspec/exceptions.py,sha256=mCqNJ0JSPA-TUPpAfdctwwqJWbiNsWap5ATNNRdczwU,6159
|
|
11
|
+
sqlspec/loader.py,sha256=sIK4I8L1Qe6hyoi6OHuaaAUUTdj4UrsRca16fuMs8HM,27259
|
|
12
|
+
sqlspec/protocols.py,sha256=iwwy7zdIBV7TcoxIYpKuTvN5fGiULQac2f4a-saxyKU,12937
|
|
13
|
+
sqlspec/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
+
sqlspec/typing.py,sha256=JEq2VsTaLdNZ1HAqj3n_HgQgdwlQQOCcZx3VBiPs0UA,7393
|
|
15
|
+
sqlspec/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
+
sqlspec/adapters/adbc/__init__.py,sha256=CqBaEahvHbQ5NxmBJuuCtZ8v5wuaPgbqSSe9WUhglWY,336
|
|
17
|
+
sqlspec/adapters/adbc/_types.py,sha256=htTZ20qVo6Iod_ooUTLGd0xAL8AUYA4qeOexTaLQG3Q,351
|
|
18
|
+
sqlspec/adapters/adbc/config.py,sha256=UdS_4q5tsXKPEilD2dLtk9H1BI02CTSvhIWEDChrPEs,13871
|
|
19
|
+
sqlspec/adapters/adbc/driver.py,sha256=nYS6e6DXxZ8lHzUFvXvC8qtcGSBTvK8IF_NlBbw56pg,20217
|
|
20
|
+
sqlspec/adapters/aiosqlite/__init__.py,sha256=q2YXU9WCL2RSYFvd0DiXz5PeCaezCRmrqmQVd86V2so,577
|
|
21
|
+
sqlspec/adapters/aiosqlite/_types.py,sha256=M8VqaW6iCigfExhdJM2yPAN09Ue2yBoBL59-QXGBObo,355
|
|
22
|
+
sqlspec/adapters/aiosqlite/config.py,sha256=F_trn-H2KcB1sH1fXdGKYNLcDFwu28WszTBoESK8D0c,9036
|
|
23
|
+
sqlspec/adapters/aiosqlite/driver.py,sha256=pU6uyvZSDrUsgkLkBW1guq6wno5FOyqt9Tg8dg6L7HM,9644
|
|
24
|
+
sqlspec/adapters/asyncmy/__init__.py,sha256=wBgak4MA3ySaGQHUxrnv3HdSVQKKRWf1_DmENL0LkWs,531
|
|
25
|
+
sqlspec/adapters/asyncmy/_types.py,sha256=WbwREzJkLYmqd4c7A7cu04WaD5g7-n35ZETHZvbP1Z8,250
|
|
26
|
+
sqlspec/adapters/asyncmy/config.py,sha256=8fGiiFjIaT_y6OcVj_7dTK9sSuLqucMRsGcRPoYigy8,6557
|
|
27
|
+
sqlspec/adapters/asyncmy/driver.py,sha256=W_RLuGrGlqLl5aZBfMu4ZxBcgKZDPOmoJuAD-wpZeKM,11215
|
|
28
|
+
sqlspec/adapters/asyncpg/__init__.py,sha256=h3lg3pLBLrS9ABBt5yKFKhGL69RpOlASYSqVCuAuURY,567
|
|
29
|
+
sqlspec/adapters/asyncpg/_types.py,sha256=p65WrqfUl2cx5Md759_aV8m_gHP-PyCzNk48bLhDQkc,425
|
|
30
|
+
sqlspec/adapters/asyncpg/config.py,sha256=KdJ2BEtkIA3X3BY4C86zCOUH1-U3AT8ZPNYOpbN0e3A,8752
|
|
31
|
+
sqlspec/adapters/asyncpg/driver.py,sha256=jKDnh5Cz-LTCQvSGaYPgDysl7aocVZ9Wfxy_ERz0RUw,14286
|
|
32
|
+
sqlspec/adapters/bigquery/__init__.py,sha256=1nzkWubO4ZObuK27QoeGfS05ed5v02NU4GaXrvqjlw0,504
|
|
33
|
+
sqlspec/adapters/bigquery/_types.py,sha256=gECmbiSmZmnR-xJpmznhnva4SbhhdcYQ09jBdqMAmOs,255
|
|
34
|
+
sqlspec/adapters/bigquery/config.py,sha256=KYVvhcd4MyU2ak0t1mX3bd3EXlVMEciO7YPaDtZsPc8,11975
|
|
35
|
+
sqlspec/adapters/bigquery/driver.py,sha256=3y8gwrYTt6ktPKE0ihGk5Dj7yvL52Gc8uT1b1ynaCuA,24016
|
|
36
|
+
sqlspec/adapters/duckdb/__init__.py,sha256=iovQlYGfizYpIZpbc1YymK2xt6pZ4ApQj6I0Q0lHc3I,603
|
|
37
|
+
sqlspec/adapters/duckdb/_types.py,sha256=4p5nuD1yNs0fmQ5sGxKFx2ru6jUCPrpsYgqfh-uZHM8,270
|
|
38
|
+
sqlspec/adapters/duckdb/config.py,sha256=krVy5BsS7f2Uv4vmZrwpxlXzbe-MweS6JbHm809NJqE,18610
|
|
39
|
+
sqlspec/adapters/duckdb/driver.py,sha256=HDRPYh1k0JnnnaPpyv8oONn7UAYDCQyTK4fsgFDv6uk,15003
|
|
40
|
+
sqlspec/adapters/oracledb/__init__.py,sha256=AUsZ8m9tDgNwxv9m4LtkIs9Ib6hOtBrGNm-Ee4HWNq0,843
|
|
41
|
+
sqlspec/adapters/oracledb/_types.py,sha256=yPJTQE37HYVgvxI3USonWvFJ2VcfaNnXqfgKNVphmcQ,400
|
|
42
|
+
sqlspec/adapters/oracledb/config.py,sha256=yZITXSWuHKwrjVcuaTLyR9RtVb3WtzmWlBQTjvyUtPo,11383
|
|
43
|
+
sqlspec/adapters/oracledb/driver.py,sha256=mckrpid-XI-3juWbTXfy0JuYuZl3NS-ZB9P2VcJMSTI,22534
|
|
44
|
+
sqlspec/adapters/psqlpy/__init__.py,sha256=ABve2Oj-G-fxMO8WRJ0XzxEw2cs5H3INDnmUI99l8gc,526
|
|
45
|
+
sqlspec/adapters/psqlpy/_types.py,sha256=tG4jwQtBB6mCX5KU5x3hAhxsQUQlQEzbCsYhU3IouVc,269
|
|
46
|
+
sqlspec/adapters/psqlpy/config.py,sha256=h9IZr0vv6-rS7RLHSVsaIdCGgLsTdXQJSSgw4HI99d4,7866
|
|
47
|
+
sqlspec/adapters/psqlpy/driver.py,sha256=e9gHrmjXj7QGE_DxCTA3DhjvckSuFGO7pcdm3kqNv1c,20346
|
|
48
|
+
sqlspec/adapters/psycopg/__init__.py,sha256=swmTz8xlj6LvB-i78tBSE_T-sez2e6lFJW2cMzNJEVE,862
|
|
49
|
+
sqlspec/adapters/psycopg/_types.py,sha256=UJBKDWgARoSR6UxSy8zcIP7HSHTpXU5moJTsjDj0M4M,563
|
|
50
|
+
sqlspec/adapters/psycopg/config.py,sha256=tyxP1WbLQlwvdWdykG_iluIaQg0O6GLUwMLtfaRQ3sE,16268
|
|
51
|
+
sqlspec/adapters/psycopg/driver.py,sha256=qMRaoUI1RF0JLGEEIWzZJTyPd5jEaRFq6ZY0dkukrCQ,33434
|
|
52
|
+
sqlspec/adapters/sqlite/__init__.py,sha256=wDN0StuJxCy0VX1fVYDngTFUP5Cx8d0-foeJeJaEVOw,484
|
|
53
|
+
sqlspec/adapters/sqlite/_types.py,sha256=4Nqolhk8s4mwLw13BwUjuyhAbM9BsKwJCvcmjMWkhaY,246
|
|
54
|
+
sqlspec/adapters/sqlite/config.py,sha256=jTomeuHahwMN9huOnQclAuJyiFL1m8hoexQxWCn0Ckg,9166
|
|
55
|
+
sqlspec/adapters/sqlite/driver.py,sha256=uAhasoCNOV30gTvl1EUpofRcm8YiEW5RnVy07XyypzI,12103
|
|
56
|
+
sqlspec/builder/__init__.py,sha256=E3UGimdSOUK_ZGxFEOsCduwWWwTxcqoLe3Rvh4KbGNY,1429
|
|
57
|
+
sqlspec/builder/_base.py,sha256=yz-6e-x66vrNne6z5zq4Ae0C3p0mHEEIe1Y8er-A0pg,17812
|
|
58
|
+
sqlspec/builder/_column.py,sha256=46baZj403BKfGjZcMc9LtQfMLeMQ7ROPyFL64V7dDM0,13124
|
|
59
|
+
sqlspec/builder/_ddl.py,sha256=A_fV4d92o2ZOhX150YMSsQDm3veQTQrwlxgLdFMBBfg,48184
|
|
60
|
+
sqlspec/builder/_ddl_utils.py,sha256=1mFSNe9w5rZXA1Ud4CTuca7eibi0XayHrIPcnEgRB7s,4034
|
|
61
|
+
sqlspec/builder/_delete.py,sha256=xWA5nQB3UB8kpEGXN2k5ynt4cGZ7blkNoURpI0bKoeg,2264
|
|
62
|
+
sqlspec/builder/_insert.py,sha256=rARWh5olbur6oPP_3FoAuJp8irj5cRLW0mKdWEx2cqU,16896
|
|
63
|
+
sqlspec/builder/_merge.py,sha256=95PLQSKA3zjk0wTZG3m817fTZpsS95PrS2qF34iLAP8,2004
|
|
64
|
+
sqlspec/builder/_parsing_utils.py,sha256=LyvFJ6nCU7b-h8QFyg4cYtcc0RKVzI_sHTeOVrU1_s8,7102
|
|
65
|
+
sqlspec/builder/_select.py,sha256=m5sfyuAssjlNimLLNBAeFooVIfM2FgKN1boPfdsOkaA,5785
|
|
66
|
+
sqlspec/builder/_update.py,sha256=UFHM_uWVY5RnZQ6winiyjKNtBryKRAXJlXtCVQdifyw,6015
|
|
67
|
+
sqlspec/builder/mixins/__init__.py,sha256=YXhAzKmQbQtne5j26SKWY8PUxwosl0RhlhLoahAdkj0,1885
|
|
68
|
+
sqlspec/builder/mixins/_cte_and_set_ops.py,sha256=p5O9m_jvpaWxv1XP9Ys2DRI-qOTq30rr2EwYjAbIT8o,9088
|
|
69
|
+
sqlspec/builder/mixins/_delete_operations.py,sha256=l0liajnoAfRgtWtyStuAIfxreEFRkNO4DtBwyGqAfic,1198
|
|
70
|
+
sqlspec/builder/mixins/_insert_operations.py,sha256=3ZuVNAPgJG0fzOPaprwUPa0Un3NP7erHwtCg8AGZWD8,9500
|
|
71
|
+
sqlspec/builder/mixins/_join_operations.py,sha256=hZKuKCGjPRX379g0DblADRXdU8mtEiEOEerxCRHuo28,7280
|
|
72
|
+
sqlspec/builder/mixins/_merge_operations.py,sha256=e9QDv1s84-2F2ZAZrr7UJtKXhy3X0NDN7AZ--8mOTKw,24193
|
|
73
|
+
sqlspec/builder/mixins/_order_limit_operations.py,sha256=ABPuFSqHRv7XaS9-3HNZO3Jn0QovhJrkYT158xxduns,4835
|
|
74
|
+
sqlspec/builder/mixins/_pivot_operations.py,sha256=j5vdzXuEqB1Jn3Ie_QjVwSH2_OEi65oZ64bQJHd3jXo,6108
|
|
75
|
+
sqlspec/builder/mixins/_select_operations.py,sha256=ArFWrEGk6ZDiwfi5gUseGTBHCzsSKWfF2EjJlJWL2Ek,25021
|
|
76
|
+
sqlspec/builder/mixins/_update_operations.py,sha256=lk9VRM0KGmYhofbWChemJxSZF6I0LhrRgqMXVmXZMeU,8650
|
|
77
|
+
sqlspec/builder/mixins/_where_clause.py,sha256=jqz58H9X2ZDsiQH9DeBrrQJf-Am7-x1ApJH47U2DFfo,33789
|
|
78
|
+
sqlspec/core/__init__.py,sha256=rU_xGsXhqIOnBbyB2InhJknYePm5NQ2DSWdBigror4g,1775
|
|
79
|
+
sqlspec/core/cache.py,sha256=cLL9bd5wn1oeMzn5E5Ym0sAemA8U4QP6B55x4L9-26I,27044
|
|
80
|
+
sqlspec/core/compiler.py,sha256=pfBRrMFvrNuCwQgzKNljNTYH3imARlek3Ja5mJkHI88,14652
|
|
81
|
+
sqlspec/core/filters.py,sha256=X0wRd0vNOFgeOK98ReeTyKt408GCnnmE9p45Bvur3kw,31351
|
|
82
|
+
sqlspec/core/hashing.py,sha256=4KyAFWtFDMYreoBGGPQppEuMWO6_NrRYlw9Lm-qeJqo,10429
|
|
83
|
+
sqlspec/core/parameters.py,sha256=yLnGt_tqqpb28xrgnq3oQ-1mcf45Pjf6uE3c0ag5JJ4,54265
|
|
84
|
+
sqlspec/core/result.py,sha256=VnxiTW7m6QfQkKRA8U_WtX198HelX2TCHd4aKPmKHHo,21340
|
|
85
|
+
sqlspec/core/splitter.py,sha256=cb2P1B0q5vvALHi3SEJ7VdbRHH2GWsftrmJi9PYMbeE,28089
|
|
86
|
+
sqlspec/core/statement.py,sha256=HsbSu0qnfJzpL_s1kwfxtWnyuCfAq8WjYRc3YQqxkDw,25700
|
|
87
|
+
sqlspec/driver/__init__.py,sha256=QVpDRQGd1GreIP199en6qDbq-cZJcEF5go68DINagUk,569
|
|
88
|
+
sqlspec/driver/_async.py,sha256=29XYWjeIuIwElO3QFUtEqQZq1ss2Ulueh0UD-aX2x-E,19636
|
|
89
|
+
sqlspec/driver/_common.py,sha256=bjJCBfM5YaU-98vEnEc5qFcjWvaUVEcQS6v3gGC0UKw,26313
|
|
90
|
+
sqlspec/driver/_sync.py,sha256=pCKNHj46HcZYn9292FWyoWkNc6gj4ArUT8ttik4YyRQ,19408
|
|
91
|
+
sqlspec/driver/mixins/__init__.py,sha256=gN4pQyJXxNy0xi91dcMJGA7DQ7TbjGjQI24SSpZc6Go,248
|
|
92
|
+
sqlspec/driver/mixins/_result_tools.py,sha256=8z-W4py3BOtn3WB7ElpsVAEjGRozgHsfymTE_oXqcnw,7576
|
|
93
|
+
sqlspec/driver/mixins/_sql_translator.py,sha256=jmwlocjSqj-ZMfssMva6GR8t-CRlDVwU3ec2ve0l3JE,3322
|
|
94
|
+
sqlspec/extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
95
|
+
sqlspec/extensions/aiosql/__init__.py,sha256=-9cefc9pYPf9vCgALoB-y1DtmcgRjKe2azfl6RIarAA,414
|
|
96
|
+
sqlspec/extensions/aiosql/adapter.py,sha256=CXkNZaZq86ZhfYFGx4IFbkHmbIFQKMd9CS6Q2jkMCok,16009
|
|
97
|
+
sqlspec/extensions/litestar/__init__.py,sha256=tOmQ7RHSWOot7p30gk0efxxuP0OCq1opyyZqNmQY7FE,320
|
|
98
|
+
sqlspec/extensions/litestar/_utils.py,sha256=o-FuUj1_WkDrLxQxiP6hXDak66XfyRP3QLyEVKrIRjI,1954
|
|
99
|
+
sqlspec/extensions/litestar/cli.py,sha256=X4DlAx3Ry-ccOjAQSxe8SMtyJKCFJVLTbENPU_efKuU,1356
|
|
100
|
+
sqlspec/extensions/litestar/config.py,sha256=3UI_vhtbupCLsf1nhUgUpRlCoUS5c0GsAjWvegT0c3c,4462
|
|
101
|
+
sqlspec/extensions/litestar/handlers.py,sha256=3LreU8rZvuHaJnKlN09ttu4wSorWJedsuKgeLT-cOEc,9993
|
|
102
|
+
sqlspec/extensions/litestar/plugin.py,sha256=I0aRnL4oZPUYk7pYhZSL3yikl7ViM0kr33kVmH4W-MU,5637
|
|
103
|
+
sqlspec/extensions/litestar/providers.py,sha256=5LRb5JvRV_XZdNOKkdaIy3j5x-dFCcAi1ea1pgwuapI,18882
|
|
104
|
+
sqlspec/migrations/__init__.py,sha256=n9y2yLQb02zMz36bPXnrInsSIMLunwHvO7e8UvCYBJc,1061
|
|
105
|
+
sqlspec/migrations/base.py,sha256=D5-k0m4SnmVU0QRRPcMCvMAyEoAaceYYmD8JprSozDA,13251
|
|
106
|
+
sqlspec/migrations/commands.py,sha256=LUAOOJcfolv75ZRV33zjdZ9kocyJSJet5hEZhUVIemU,18490
|
|
107
|
+
sqlspec/migrations/loaders.py,sha256=wz-VUd1fEtOg-b1yWnLTTNtHkZkrjw-4o5hEqwUxbS0,12952
|
|
108
|
+
sqlspec/migrations/runner.py,sha256=OxzindA2EzjCAVqI59LxfWC02Ful-aPsOYY9yUV7ypA,7330
|
|
109
|
+
sqlspec/migrations/tracker.py,sha256=-gfHgvcYo1uBdr9FKrIxaU_0v734K5gpdLMuoaX29nQ,5013
|
|
110
|
+
sqlspec/migrations/utils.py,sha256=gWnCOdr8pwfkgG-FSUJgRz4q9TlCgOXY_B7n59NrgVA,3746
|
|
111
|
+
sqlspec/storage/__init__.py,sha256=bLrUfW_E41HH-Pi5kqFTPVYZiSsxlG7OZO1xP23nDSI,691
|
|
112
|
+
sqlspec/storage/capabilities.py,sha256=vyousxls9jISsykgoybpNHlGWN6Hq_pKcsZ5DmKGWvU,3045
|
|
113
|
+
sqlspec/storage/registry.py,sha256=NV-NdAcMdGqU5bHbXbkMuU_HRYuEgii7B4ldXnVSIo4,9529
|
|
114
|
+
sqlspec/storage/backends/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
115
|
+
sqlspec/storage/backends/base.py,sha256=KS2JRZILoH_R_xsfKtYkqQ5a1r5OOBDSE5KbibTmhGY,5730
|
|
116
|
+
sqlspec/storage/backends/fsspec.py,sha256=YVr8X_q5F4Xrr9SyfUDve1dZ9E6KppuM8w6tvLwPKpc,16050
|
|
117
|
+
sqlspec/storage/backends/obstore.py,sha256=8DEpiF3SCfbWx-NxoQXZ8piJOr-9f1WURYK69hCDhnQ,19864
|
|
118
|
+
sqlspec/utils/__init__.py,sha256=DJiG2RGFaL9C0lLZStByzgR_GiPHfdkypAkTEGjTakw,211
|
|
119
|
+
sqlspec/utils/correlation.py,sha256=2jvkAY3nkU3UxNU_9pbBR6cz3A1Q1cGG9IaWSSOIb1Q,4195
|
|
120
|
+
sqlspec/utils/deprecation.py,sha256=L5ylPlkrWahXZ3q2Yta2ReFh4pA8rZapLNw9u_mOOEE,3794
|
|
121
|
+
sqlspec/utils/fixtures.py,sha256=Qm2uNMaL_6l6tlij-Pm3tLwD906iFK_OXhwZqOx3WgY,1807
|
|
122
|
+
sqlspec/utils/logging.py,sha256=ZEaj7J8oALrs_-p535vSUFo2tfrHkOEcL5pK2JGGFgM,3708
|
|
123
|
+
sqlspec/utils/module_loader.py,sha256=m5PSN9NwOLd0ZJBuqMVYVi-vaIQMBCVd25vnM3-rv3k,2823
|
|
124
|
+
sqlspec/utils/serializers.py,sha256=TKsRryRcYMnb8Z8MGkYGClIxcYvC8CW7MsrPQTJqEcY,154
|
|
125
|
+
sqlspec/utils/singleton.py,sha256=SKnszJi1NPeERgX7IjVIGYAYx4XqR1E_rph3bU6olAU,1047
|
|
126
|
+
sqlspec/utils/sync_tools.py,sha256=WRuk1ZEhb_0CRrumAdnmi-i-dV6qVd3cgJyZw8RY9QQ,7390
|
|
127
|
+
sqlspec/utils/text.py,sha256=n5K0gvXvyCc8jNteNKsBOymwf_JnQ65f3lu0YaYq4Ys,2898
|
|
128
|
+
sqlspec/utils/type_guards.py,sha256=9C4SRebO4JiQrMzcJZFUA0KjSU48G26RmX6lbijyjBg,30476
|
|
129
|
+
sqlspec-0.16.2.dist-info/METADATA,sha256=uxIDZpVGDc5LNmEdLfdULbelze5R5WSAxXwRYXZ42ZQ,16822
|
|
130
|
+
sqlspec-0.16.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
131
|
+
sqlspec-0.16.2.dist-info/entry_points.txt,sha256=G-ZqY1Nuuw3Iys7nXw23f6ILenk_Lt47VdK2mhJCWHg,53
|
|
132
|
+
sqlspec-0.16.2.dist-info/licenses/LICENSE,sha256=MdujfZ6l5HuLz4mElxlu049itenOR3gnhN1_Nd3nVcM,1078
|
|
133
|
+
sqlspec-0.16.2.dist-info/licenses/NOTICE,sha256=Lyir8ozXWov7CyYS4huVaOCNrtgL17P-bNV-5daLntQ,1634
|
|
134
|
+
sqlspec-0.16.2.dist-info/RECORD,,
|
sqlspec/driver/connection.py
DELETED
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
"""Consolidated connection management utilities for database drivers.
|
|
2
|
-
|
|
3
|
-
This module provides centralized connection handling to avoid duplication
|
|
4
|
-
across database adapter implementations.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from contextlib import asynccontextmanager, contextmanager
|
|
8
|
-
from typing import TYPE_CHECKING, Any, Optional, TypeVar, cast
|
|
9
|
-
|
|
10
|
-
if TYPE_CHECKING:
|
|
11
|
-
from collections.abc import AsyncIterator, Iterator
|
|
12
|
-
|
|
13
|
-
from sqlspec.utils.type_guards import is_async_transaction_capable, is_sync_transaction_capable
|
|
14
|
-
|
|
15
|
-
__all__ = (
|
|
16
|
-
"get_connection_info",
|
|
17
|
-
"managed_connection_async",
|
|
18
|
-
"managed_connection_sync",
|
|
19
|
-
"managed_transaction_async",
|
|
20
|
-
"managed_transaction_sync",
|
|
21
|
-
"validate_pool_config",
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
ConnectionT = TypeVar("ConnectionT")
|
|
26
|
-
PoolT = TypeVar("PoolT")
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@contextmanager
|
|
30
|
-
def managed_connection_sync(config: Any, provided_connection: Optional[ConnectionT] = None) -> "Iterator[ConnectionT]":
|
|
31
|
-
"""Context manager for database connections.
|
|
32
|
-
|
|
33
|
-
Args:
|
|
34
|
-
config: Database configuration with provide_connection method
|
|
35
|
-
provided_connection: Optional existing connection to use
|
|
36
|
-
|
|
37
|
-
Yields:
|
|
38
|
-
Database connection
|
|
39
|
-
"""
|
|
40
|
-
if provided_connection is not None:
|
|
41
|
-
yield provided_connection
|
|
42
|
-
return
|
|
43
|
-
|
|
44
|
-
# Get connection from config
|
|
45
|
-
with config.provide_connection() as connection:
|
|
46
|
-
yield connection
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
@contextmanager
|
|
50
|
-
def managed_transaction_sync(connection: ConnectionT, auto_commit: bool = True) -> "Iterator[ConnectionT]":
|
|
51
|
-
"""Context manager for database transactions.
|
|
52
|
-
|
|
53
|
-
Args:
|
|
54
|
-
connection: Database connection
|
|
55
|
-
auto_commit: Whether to auto-commit on success
|
|
56
|
-
|
|
57
|
-
Yields:
|
|
58
|
-
Database connection
|
|
59
|
-
"""
|
|
60
|
-
# Check if connection already has autocommit enabled
|
|
61
|
-
has_autocommit = getattr(connection, "autocommit", False)
|
|
62
|
-
|
|
63
|
-
if not auto_commit or not is_sync_transaction_capable(connection) or has_autocommit:
|
|
64
|
-
yield connection
|
|
65
|
-
return
|
|
66
|
-
|
|
67
|
-
try:
|
|
68
|
-
yield cast("ConnectionT", connection)
|
|
69
|
-
cast("Any", connection).commit()
|
|
70
|
-
except Exception:
|
|
71
|
-
# Some databases (like DuckDB) throw an error if rollback is called
|
|
72
|
-
# when no transaction is active. Catch and ignore these specific errors.
|
|
73
|
-
try:
|
|
74
|
-
cast("Any", connection).rollback()
|
|
75
|
-
except Exception as rollback_error:
|
|
76
|
-
# Check if this is a "no transaction active" type error
|
|
77
|
-
error_msg = str(rollback_error).lower()
|
|
78
|
-
if "no transaction" in error_msg or "transaction context error" in error_msg:
|
|
79
|
-
# Ignore rollback errors when no transaction is active
|
|
80
|
-
pass
|
|
81
|
-
else:
|
|
82
|
-
# Re-raise other rollback errors
|
|
83
|
-
raise
|
|
84
|
-
raise
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
@asynccontextmanager
|
|
88
|
-
async def managed_connection_async(
|
|
89
|
-
config: Any, provided_connection: Optional[ConnectionT] = None
|
|
90
|
-
) -> "AsyncIterator[ConnectionT]":
|
|
91
|
-
"""Async context manager for database connections.
|
|
92
|
-
|
|
93
|
-
Args:
|
|
94
|
-
config: Database configuration with provide_connection method
|
|
95
|
-
provided_connection: Optional existing connection to use
|
|
96
|
-
|
|
97
|
-
Yields:
|
|
98
|
-
Database connection
|
|
99
|
-
"""
|
|
100
|
-
if provided_connection is not None:
|
|
101
|
-
yield provided_connection
|
|
102
|
-
return
|
|
103
|
-
|
|
104
|
-
# Get connection from config
|
|
105
|
-
async with config.provide_connection() as connection:
|
|
106
|
-
yield connection
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
@asynccontextmanager
|
|
110
|
-
async def managed_transaction_async(connection: ConnectionT, auto_commit: bool = True) -> "AsyncIterator[ConnectionT]":
|
|
111
|
-
"""Async context manager for database transactions.
|
|
112
|
-
|
|
113
|
-
Args:
|
|
114
|
-
connection: Database connection
|
|
115
|
-
auto_commit: Whether to auto-commit on success
|
|
116
|
-
|
|
117
|
-
Yields:
|
|
118
|
-
Database connection
|
|
119
|
-
"""
|
|
120
|
-
# Check if connection already has autocommit enabled
|
|
121
|
-
has_autocommit = getattr(connection, "autocommit", False)
|
|
122
|
-
|
|
123
|
-
if not auto_commit or not is_async_transaction_capable(connection) or has_autocommit:
|
|
124
|
-
yield connection
|
|
125
|
-
return
|
|
126
|
-
|
|
127
|
-
try:
|
|
128
|
-
yield cast("ConnectionT", connection)
|
|
129
|
-
await cast("Any", connection).commit()
|
|
130
|
-
except Exception:
|
|
131
|
-
# Some databases (like DuckDB) throw an error if rollback is called
|
|
132
|
-
# when no transaction is active. Catch and ignore these specific errors.
|
|
133
|
-
try:
|
|
134
|
-
await cast("Any", connection).rollback()
|
|
135
|
-
except Exception as rollback_error:
|
|
136
|
-
# Check if this is a "no transaction active" type error
|
|
137
|
-
error_msg = str(rollback_error).lower()
|
|
138
|
-
if "no transaction" in error_msg or "transaction context error" in error_msg:
|
|
139
|
-
# Ignore rollback errors when no transaction is active
|
|
140
|
-
pass
|
|
141
|
-
else:
|
|
142
|
-
# Re-raise other rollback errors
|
|
143
|
-
raise
|
|
144
|
-
raise
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
def get_connection_info(connection: Any) -> dict[str, Any]:
|
|
148
|
-
"""Extract connection information for logging/debugging.
|
|
149
|
-
|
|
150
|
-
Args:
|
|
151
|
-
connection: Database connection object
|
|
152
|
-
|
|
153
|
-
Returns:
|
|
154
|
-
Dictionary of connection information
|
|
155
|
-
"""
|
|
156
|
-
info = {"type": type(connection).__name__, "module": type(connection).__module__}
|
|
157
|
-
|
|
158
|
-
# Try to get database name
|
|
159
|
-
for attr in ("database", "dbname", "db", "catalog"):
|
|
160
|
-
value = getattr(connection, attr, None)
|
|
161
|
-
if value is not None:
|
|
162
|
-
info["database"] = value
|
|
163
|
-
break
|
|
164
|
-
|
|
165
|
-
# Try to get host information
|
|
166
|
-
for attr in ("host", "hostname", "server"):
|
|
167
|
-
value = getattr(connection, attr, None)
|
|
168
|
-
if value is not None:
|
|
169
|
-
info["host"] = value
|
|
170
|
-
break
|
|
171
|
-
|
|
172
|
-
return info
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
def validate_pool_config(
|
|
176
|
-
min_size: int, max_size: int, max_idle_time: Optional[int] = None, max_lifetime: Optional[int] = None
|
|
177
|
-
) -> None:
|
|
178
|
-
"""Validate connection pool configuration.
|
|
179
|
-
|
|
180
|
-
Args:
|
|
181
|
-
min_size: Minimum pool size
|
|
182
|
-
max_size: Maximum pool size
|
|
183
|
-
max_idle_time: Maximum idle time in seconds
|
|
184
|
-
max_lifetime: Maximum connection lifetime in seconds
|
|
185
|
-
|
|
186
|
-
Raises:
|
|
187
|
-
ValueError: If configuration is invalid
|
|
188
|
-
"""
|
|
189
|
-
if min_size < 0:
|
|
190
|
-
msg = f"min_size must be >= 0, got {min_size}"
|
|
191
|
-
raise ValueError(msg)
|
|
192
|
-
|
|
193
|
-
if max_size < 1:
|
|
194
|
-
msg = f"max_size must be >= 1, got {max_size}"
|
|
195
|
-
raise ValueError(msg)
|
|
196
|
-
|
|
197
|
-
if min_size > max_size:
|
|
198
|
-
msg = f"min_size ({min_size}) cannot be greater than max_size ({max_size})"
|
|
199
|
-
raise ValueError(msg)
|
|
200
|
-
|
|
201
|
-
if max_idle_time is not None and max_idle_time < 0:
|
|
202
|
-
msg = f"max_idle_time must be >= 0, got {max_idle_time}"
|
|
203
|
-
raise ValueError(msg)
|
|
204
|
-
|
|
205
|
-
if max_lifetime is not None and max_lifetime < 0:
|
|
206
|
-
msg = f"max_lifetime must be >= 0, got {max_lifetime}"
|
|
207
|
-
raise ValueError(msg)
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
"""Optimized CSV writing utilities."""
|
|
2
|
-
|
|
3
|
-
import csv
|
|
4
|
-
from typing import TYPE_CHECKING, Any
|
|
5
|
-
|
|
6
|
-
from sqlspec.typing import PYARROW_INSTALLED
|
|
7
|
-
|
|
8
|
-
if TYPE_CHECKING:
|
|
9
|
-
from sqlspec.statement.result import SQLResult
|
|
10
|
-
|
|
11
|
-
__all__ = ("write_csv", "write_csv_default", "write_csv_optimized")
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def _raise_no_column_names_error() -> None:
|
|
15
|
-
"""Raise error when no column names are available."""
|
|
16
|
-
msg = "No column names available"
|
|
17
|
-
raise ValueError(msg)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def write_csv(result: "SQLResult", file: Any, **options: Any) -> None:
|
|
21
|
-
"""Write result to CSV file.
|
|
22
|
-
|
|
23
|
-
Args:
|
|
24
|
-
result: SQL result to write
|
|
25
|
-
file: File-like object to write to
|
|
26
|
-
**options: CSV writer options
|
|
27
|
-
"""
|
|
28
|
-
if PYARROW_INSTALLED:
|
|
29
|
-
try:
|
|
30
|
-
write_csv_optimized(result, file, **options)
|
|
31
|
-
except Exception:
|
|
32
|
-
write_csv_default(result, file, **options)
|
|
33
|
-
else:
|
|
34
|
-
write_csv_default(result, file, **options)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def write_csv_default(result: "SQLResult", file: Any, **options: Any) -> None:
|
|
38
|
-
"""Write result to CSV file using default method.
|
|
39
|
-
|
|
40
|
-
Args:
|
|
41
|
-
result: SQL result to write
|
|
42
|
-
file: File-like object to write to
|
|
43
|
-
**options: CSV writer options
|
|
44
|
-
"""
|
|
45
|
-
csv_options = options.copy()
|
|
46
|
-
csv_options.pop("compression", None)
|
|
47
|
-
csv_options.pop("partition_by", None)
|
|
48
|
-
|
|
49
|
-
writer = csv.writer(file, **csv_options)
|
|
50
|
-
if result.column_names:
|
|
51
|
-
writer.writerow(result.column_names)
|
|
52
|
-
if result.data:
|
|
53
|
-
if result.data and isinstance(result.data[0], dict):
|
|
54
|
-
rows = []
|
|
55
|
-
for row_dict in result.data:
|
|
56
|
-
row_values = [row_dict.get(col) for col in result.column_names or []]
|
|
57
|
-
rows.append(row_values)
|
|
58
|
-
writer.writerows(rows)
|
|
59
|
-
else:
|
|
60
|
-
writer.writerows(result.data)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def write_csv_optimized(result: "SQLResult", file: Any, **options: Any) -> None:
|
|
64
|
-
"""Write result to CSV using PyArrow if available for better performance.
|
|
65
|
-
|
|
66
|
-
Args:
|
|
67
|
-
result: SQL result to write
|
|
68
|
-
file: File-like object to write to
|
|
69
|
-
**options: CSV writer options
|
|
70
|
-
"""
|
|
71
|
-
_ = options
|
|
72
|
-
import pyarrow as pa
|
|
73
|
-
import pyarrow.csv as pa_csv
|
|
74
|
-
|
|
75
|
-
if not result.data:
|
|
76
|
-
return
|
|
77
|
-
|
|
78
|
-
if not hasattr(file, "name"):
|
|
79
|
-
msg = "PyArrow CSV writer requires a file with a 'name' attribute"
|
|
80
|
-
raise ValueError(msg)
|
|
81
|
-
|
|
82
|
-
table: Any
|
|
83
|
-
if isinstance(result.data[0], dict):
|
|
84
|
-
table = pa.Table.from_pylist(result.data)
|
|
85
|
-
elif result.column_names:
|
|
86
|
-
data_dicts = [dict(zip(result.column_names, row)) for row in result.data]
|
|
87
|
-
table = pa.Table.from_pylist(data_dicts)
|
|
88
|
-
else:
|
|
89
|
-
_raise_no_column_names_error()
|
|
90
|
-
|
|
91
|
-
pa_csv.write_csv(table, file.name) # pyright: ignore
|