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.
- f68e0789eb443ecb1c2c__mypyc.cp314-win_amd64.pyd +0 -0
- sqlspec/__init__.py +167 -0
- sqlspec/__main__.py +12 -0
- sqlspec/__metadata__.py +14 -0
- sqlspec/_typing.py +714 -0
- sqlspec/adapters/__init__.py +0 -0
- sqlspec/adapters/adbc/__init__.py +13 -0
- sqlspec/adapters/adbc/_typing.py +106 -0
- sqlspec/adapters/adbc/adk/__init__.py +5 -0
- sqlspec/adapters/adbc/adk/store.py +1280 -0
- sqlspec/adapters/adbc/config.py +378 -0
- sqlspec/adapters/adbc/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/adbc/core.py +922 -0
- sqlspec/adapters/adbc/data_dictionary.py +339 -0
- sqlspec/adapters/adbc/driver.py +534 -0
- sqlspec/adapters/adbc/events/__init__.py +5 -0
- sqlspec/adapters/adbc/events/store.py +285 -0
- sqlspec/adapters/adbc/litestar/__init__.py +5 -0
- sqlspec/adapters/adbc/litestar/store.py +534 -0
- sqlspec/adapters/adbc/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/adbc/type_converter.py +142 -0
- sqlspec/adapters/aiomysql/__init__.py +21 -0
- sqlspec/adapters/aiomysql/_typing.py +137 -0
- sqlspec/adapters/aiomysql/adk/__init__.py +5 -0
- sqlspec/adapters/aiomysql/adk/store.py +678 -0
- sqlspec/adapters/aiomysql/config.py +305 -0
- sqlspec/adapters/aiomysql/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/aiomysql/core.py +536 -0
- sqlspec/adapters/aiomysql/data_dictionary.py +121 -0
- sqlspec/adapters/aiomysql/driver.py +386 -0
- sqlspec/adapters/aiomysql/events/__init__.py +5 -0
- sqlspec/adapters/aiomysql/events/store.py +104 -0
- sqlspec/adapters/aiomysql/litestar/__init__.py +5 -0
- sqlspec/adapters/aiomysql/litestar/store.py +314 -0
- sqlspec/adapters/aiosqlite/__init__.py +26 -0
- sqlspec/adapters/aiosqlite/_typing.py +109 -0
- sqlspec/adapters/aiosqlite/adk/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/adk/store.py +829 -0
- sqlspec/adapters/aiosqlite/config.py +315 -0
- sqlspec/adapters/aiosqlite/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/aiosqlite/core.py +315 -0
- sqlspec/adapters/aiosqlite/data_dictionary.py +202 -0
- sqlspec/adapters/aiosqlite/driver.py +311 -0
- sqlspec/adapters/aiosqlite/events/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/events/store.py +20 -0
- sqlspec/adapters/aiosqlite/litestar/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/litestar/store.py +279 -0
- sqlspec/adapters/aiosqlite/pool.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/aiosqlite/pool.py +734 -0
- sqlspec/adapters/asyncmy/__init__.py +21 -0
- sqlspec/adapters/asyncmy/_typing.py +113 -0
- sqlspec/adapters/asyncmy/adk/__init__.py +5 -0
- sqlspec/adapters/asyncmy/adk/store.py +644 -0
- sqlspec/adapters/asyncmy/config.py +307 -0
- sqlspec/adapters/asyncmy/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/asyncmy/core.py +538 -0
- sqlspec/adapters/asyncmy/data_dictionary.py +122 -0
- sqlspec/adapters/asyncmy/driver.py +391 -0
- sqlspec/adapters/asyncmy/events/__init__.py +5 -0
- sqlspec/adapters/asyncmy/events/store.py +104 -0
- sqlspec/adapters/asyncmy/litestar/__init__.py +5 -0
- sqlspec/adapters/asyncmy/litestar/store.py +296 -0
- sqlspec/adapters/asyncpg/__init__.py +26 -0
- sqlspec/adapters/asyncpg/_typing.py +103 -0
- sqlspec/adapters/asyncpg/adk/__init__.py +5 -0
- sqlspec/adapters/asyncpg/adk/store.py +483 -0
- sqlspec/adapters/asyncpg/config.py +575 -0
- sqlspec/adapters/asyncpg/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/asyncpg/core.py +480 -0
- sqlspec/adapters/asyncpg/data_dictionary.py +157 -0
- sqlspec/adapters/asyncpg/driver.py +487 -0
- sqlspec/adapters/asyncpg/events/__init__.py +6 -0
- sqlspec/adapters/asyncpg/events/_hub.py +181 -0
- sqlspec/adapters/asyncpg/events/backend.py +210 -0
- sqlspec/adapters/asyncpg/events/store.py +40 -0
- sqlspec/adapters/asyncpg/litestar/__init__.py +5 -0
- sqlspec/adapters/asyncpg/litestar/store.py +251 -0
- sqlspec/adapters/bigquery/__init__.py +15 -0
- sqlspec/adapters/bigquery/_typing.py +108 -0
- sqlspec/adapters/bigquery/config.py +362 -0
- sqlspec/adapters/bigquery/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/bigquery/core.py +768 -0
- sqlspec/adapters/bigquery/data_dictionary.py +120 -0
- sqlspec/adapters/bigquery/driver.py +542 -0
- sqlspec/adapters/bigquery/events/__init__.py +5 -0
- sqlspec/adapters/bigquery/events/store.py +139 -0
- sqlspec/adapters/bigquery/litestar/__init__.py +5 -0
- sqlspec/adapters/bigquery/litestar/store.py +325 -0
- sqlspec/adapters/bigquery/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/bigquery/type_converter.py +107 -0
- sqlspec/adapters/cockroach_asyncpg/__init__.py +26 -0
- sqlspec/adapters/cockroach_asyncpg/_typing.py +73 -0
- sqlspec/adapters/cockroach_asyncpg/adk/__init__.py +3 -0
- sqlspec/adapters/cockroach_asyncpg/adk/store.py +465 -0
- sqlspec/adapters/cockroach_asyncpg/config.py +248 -0
- sqlspec/adapters/cockroach_asyncpg/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/cockroach_asyncpg/core.py +55 -0
- sqlspec/adapters/cockroach_asyncpg/data_dictionary.py +110 -0
- sqlspec/adapters/cockroach_asyncpg/driver.py +142 -0
- sqlspec/adapters/cockroach_asyncpg/events/__init__.py +3 -0
- sqlspec/adapters/cockroach_asyncpg/events/store.py +20 -0
- sqlspec/adapters/cockroach_asyncpg/litestar/__init__.py +3 -0
- sqlspec/adapters/cockroach_asyncpg/litestar/store.py +142 -0
- sqlspec/adapters/cockroach_psycopg/__init__.py +39 -0
- sqlspec/adapters/cockroach_psycopg/_typing.py +137 -0
- sqlspec/adapters/cockroach_psycopg/adk/__init__.py +13 -0
- sqlspec/adapters/cockroach_psycopg/adk/store.py +1039 -0
- sqlspec/adapters/cockroach_psycopg/config.py +511 -0
- sqlspec/adapters/cockroach_psycopg/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/cockroach_psycopg/core.py +63 -0
- sqlspec/adapters/cockroach_psycopg/data_dictionary.py +220 -0
- sqlspec/adapters/cockroach_psycopg/driver.py +273 -0
- sqlspec/adapters/cockroach_psycopg/events/__init__.py +6 -0
- sqlspec/adapters/cockroach_psycopg/events/store.py +34 -0
- sqlspec/adapters/cockroach_psycopg/litestar/__init__.py +3 -0
- sqlspec/adapters/cockroach_psycopg/litestar/store.py +327 -0
- sqlspec/adapters/duckdb/__init__.py +29 -0
- sqlspec/adapters/duckdb/_typing.py +104 -0
- sqlspec/adapters/duckdb/adk/__init__.py +14 -0
- sqlspec/adapters/duckdb/adk/store.py +935 -0
- sqlspec/adapters/duckdb/config.py +386 -0
- sqlspec/adapters/duckdb/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/duckdb/core.py +332 -0
- sqlspec/adapters/duckdb/data_dictionary.py +140 -0
- sqlspec/adapters/duckdb/driver.py +426 -0
- sqlspec/adapters/duckdb/events/__init__.py +5 -0
- sqlspec/adapters/duckdb/events/store.py +57 -0
- sqlspec/adapters/duckdb/litestar/__init__.py +5 -0
- sqlspec/adapters/duckdb/litestar/store.py +330 -0
- sqlspec/adapters/duckdb/pool.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/duckdb/pool.py +350 -0
- sqlspec/adapters/duckdb/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/duckdb/type_converter.py +118 -0
- sqlspec/adapters/mysqlconnector/__init__.py +39 -0
- sqlspec/adapters/mysqlconnector/_typing.py +186 -0
- sqlspec/adapters/mysqlconnector/adk/__init__.py +15 -0
- sqlspec/adapters/mysqlconnector/adk/store.py +1183 -0
- sqlspec/adapters/mysqlconnector/config.py +421 -0
- sqlspec/adapters/mysqlconnector/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/mysqlconnector/core.py +472 -0
- sqlspec/adapters/mysqlconnector/data_dictionary.py +230 -0
- sqlspec/adapters/mysqlconnector/driver.py +516 -0
- sqlspec/adapters/mysqlconnector/events/__init__.py +8 -0
- sqlspec/adapters/mysqlconnector/events/store.py +98 -0
- sqlspec/adapters/mysqlconnector/litestar/__init__.py +5 -0
- sqlspec/adapters/mysqlconnector/litestar/store.py +426 -0
- sqlspec/adapters/oracledb/__init__.py +39 -0
- sqlspec/adapters/oracledb/_json_handlers.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/oracledb/_json_handlers.py +196 -0
- sqlspec/adapters/oracledb/_param_types.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/oracledb/_param_types.py +46 -0
- sqlspec/adapters/oracledb/_typing.py +258 -0
- sqlspec/adapters/oracledb/_uuid_handlers.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/oracledb/_uuid_handlers.py +163 -0
- sqlspec/adapters/oracledb/_vector_handlers.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/oracledb/_vector_handlers.py +228 -0
- sqlspec/adapters/oracledb/adk/__init__.py +21 -0
- sqlspec/adapters/oracledb/adk/store.py +2453 -0
- sqlspec/adapters/oracledb/config.py +575 -0
- sqlspec/adapters/oracledb/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/oracledb/core.py +820 -0
- sqlspec/adapters/oracledb/data_dictionary.py +404 -0
- sqlspec/adapters/oracledb/driver.py +1277 -0
- sqlspec/adapters/oracledb/events/__init__.py +16 -0
- sqlspec/adapters/oracledb/events/_hub.py +345 -0
- sqlspec/adapters/oracledb/events/backend.py +300 -0
- sqlspec/adapters/oracledb/events/store.py +420 -0
- sqlspec/adapters/oracledb/litestar/__init__.py +5 -0
- sqlspec/adapters/oracledb/litestar/store.py +781 -0
- sqlspec/adapters/oracledb/migrations.py +539 -0
- sqlspec/adapters/oracledb/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/oracledb/type_converter.py +211 -0
- sqlspec/adapters/psqlpy/__init__.py +18 -0
- sqlspec/adapters/psqlpy/_typing.py +121 -0
- sqlspec/adapters/psqlpy/adk/__init__.py +5 -0
- sqlspec/adapters/psqlpy/adk/store.py +591 -0
- sqlspec/adapters/psqlpy/config.py +376 -0
- sqlspec/adapters/psqlpy/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/psqlpy/core.py +694 -0
- sqlspec/adapters/psqlpy/data_dictionary.py +121 -0
- sqlspec/adapters/psqlpy/driver.py +411 -0
- sqlspec/adapters/psqlpy/events/__init__.py +6 -0
- sqlspec/adapters/psqlpy/events/_hub.py +204 -0
- sqlspec/adapters/psqlpy/events/backend.py +210 -0
- sqlspec/adapters/psqlpy/events/store.py +20 -0
- sqlspec/adapters/psqlpy/litestar/__init__.py +5 -0
- sqlspec/adapters/psqlpy/litestar/store.py +270 -0
- sqlspec/adapters/psqlpy/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/psqlpy/type_converter.py +113 -0
- sqlspec/adapters/psycopg/__init__.py +38 -0
- sqlspec/adapters/psycopg/_typing.py +218 -0
- sqlspec/adapters/psycopg/adk/__init__.py +10 -0
- sqlspec/adapters/psycopg/adk/store.py +1106 -0
- sqlspec/adapters/psycopg/config.py +695 -0
- sqlspec/adapters/psycopg/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/psycopg/core.py +520 -0
- sqlspec/adapters/psycopg/data_dictionary.py +278 -0
- sqlspec/adapters/psycopg/driver.py +1033 -0
- sqlspec/adapters/psycopg/events/__init__.py +20 -0
- sqlspec/adapters/psycopg/events/_hub.py +388 -0
- sqlspec/adapters/psycopg/events/backend.py +398 -0
- sqlspec/adapters/psycopg/events/store.py +42 -0
- sqlspec/adapters/psycopg/litestar/__init__.py +5 -0
- sqlspec/adapters/psycopg/litestar/store.py +554 -0
- sqlspec/adapters/psycopg/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/psycopg/type_converter.py +93 -0
- sqlspec/adapters/pymysql/__init__.py +21 -0
- sqlspec/adapters/pymysql/_typing.py +92 -0
- sqlspec/adapters/pymysql/adk/__init__.py +5 -0
- sqlspec/adapters/pymysql/adk/store.py +657 -0
- sqlspec/adapters/pymysql/config.py +176 -0
- sqlspec/adapters/pymysql/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/pymysql/core.py +469 -0
- sqlspec/adapters/pymysql/data_dictionary.py +120 -0
- sqlspec/adapters/pymysql/driver.py +271 -0
- sqlspec/adapters/pymysql/events/__init__.py +5 -0
- sqlspec/adapters/pymysql/events/store.py +50 -0
- sqlspec/adapters/pymysql/litestar/__init__.py +5 -0
- sqlspec/adapters/pymysql/litestar/store.py +232 -0
- sqlspec/adapters/pymysql/pool.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/pymysql/pool.py +184 -0
- sqlspec/adapters/spanner/__init__.py +33 -0
- sqlspec/adapters/spanner/_typing.py +102 -0
- sqlspec/adapters/spanner/adk/__init__.py +5 -0
- sqlspec/adapters/spanner/adk/store.py +758 -0
- sqlspec/adapters/spanner/config.py +355 -0
- sqlspec/adapters/spanner/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/spanner/core.py +263 -0
- sqlspec/adapters/spanner/data_dictionary.py +120 -0
- sqlspec/adapters/spanner/driver.py +407 -0
- sqlspec/adapters/spanner/events/__init__.py +5 -0
- sqlspec/adapters/spanner/events/store.py +187 -0
- sqlspec/adapters/spanner/litestar/__init__.py +5 -0
- sqlspec/adapters/spanner/litestar/store.py +291 -0
- sqlspec/adapters/spanner/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/spanner/type_converter.py +342 -0
- sqlspec/adapters/sqlite/__init__.py +19 -0
- sqlspec/adapters/sqlite/_typing.py +123 -0
- sqlspec/adapters/sqlite/adk/__init__.py +5 -0
- sqlspec/adapters/sqlite/adk/store.py +992 -0
- sqlspec/adapters/sqlite/config.py +240 -0
- sqlspec/adapters/sqlite/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/sqlite/core.py +357 -0
- sqlspec/adapters/sqlite/data_dictionary.py +198 -0
- sqlspec/adapters/sqlite/driver.py +527 -0
- sqlspec/adapters/sqlite/events/__init__.py +5 -0
- sqlspec/adapters/sqlite/events/store.py +20 -0
- sqlspec/adapters/sqlite/litestar/__init__.py +5 -0
- sqlspec/adapters/sqlite/litestar/store.py +316 -0
- sqlspec/adapters/sqlite/pool.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/sqlite/pool.py +237 -0
- sqlspec/adapters/sqlite/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/sqlite/type_converter.py +114 -0
- sqlspec/base.py +832 -0
- sqlspec/builder/__init__.py +181 -0
- sqlspec/builder/_base.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_base.py +1071 -0
- sqlspec/builder/_column.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_column.py +521 -0
- sqlspec/builder/_ddl.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_ddl.py +1691 -0
- sqlspec/builder/_delete.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_delete.py +95 -0
- sqlspec/builder/_dml.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_dml.py +386 -0
- sqlspec/builder/_explain.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_explain.py +579 -0
- sqlspec/builder/_expression_wrappers.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_expression_wrappers.py +46 -0
- sqlspec/builder/_factory.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_factory.py +1884 -0
- sqlspec/builder/_insert.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_insert.py +405 -0
- sqlspec/builder/_join.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_join.py +489 -0
- sqlspec/builder/_merge.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_merge.py +823 -0
- sqlspec/builder/_parsing_utils.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_parsing_utils.py +295 -0
- sqlspec/builder/_select.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_select.py +1666 -0
- sqlspec/builder/_temporal.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_temporal.py +167 -0
- sqlspec/builder/_update.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_update.py +173 -0
- sqlspec/builder/_vector_distance.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_vector_distance.py +330 -0
- sqlspec/cli.py +1095 -0
- sqlspec/config.py +2383 -0
- sqlspec/core/__init__.py +372 -0
- sqlspec/core/_correlation.cp314-win_amd64.pyd +0 -0
- sqlspec/core/_correlation.py +176 -0
- sqlspec/core/_pagination.py +42 -0
- sqlspec/core/_pool.cp314-win_amd64.pyd +0 -0
- sqlspec/core/_pool.py +76 -0
- sqlspec/core/cache.cp314-win_amd64.pyd +0 -0
- sqlspec/core/cache.py +1085 -0
- sqlspec/core/compiler.cp314-win_amd64.pyd +0 -0
- sqlspec/core/compiler.py +1090 -0
- sqlspec/core/config_runtime.cp314-win_amd64.pyd +0 -0
- sqlspec/core/config_runtime.py +174 -0
- sqlspec/core/explain.cp314-win_amd64.pyd +0 -0
- sqlspec/core/explain.py +275 -0
- sqlspec/core/filters.cp314-win_amd64.pyd +0 -0
- sqlspec/core/filters.py +969 -0
- sqlspec/core/hashing.cp314-win_amd64.pyd +0 -0
- sqlspec/core/hashing.py +266 -0
- sqlspec/core/metrics.cp314-win_amd64.pyd +0 -0
- sqlspec/core/metrics.py +83 -0
- sqlspec/core/parameters/__init__.py +72 -0
- sqlspec/core/parameters/_alignment.cp314-win_amd64.pyd +0 -0
- sqlspec/core/parameters/_alignment.py +283 -0
- sqlspec/core/parameters/_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/core/parameters/_converter.py +554 -0
- sqlspec/core/parameters/_processor.cp314-win_amd64.pyd +0 -0
- sqlspec/core/parameters/_processor.py +1182 -0
- sqlspec/core/parameters/_registry.cp314-win_amd64.pyd +0 -0
- sqlspec/core/parameters/_registry.py +206 -0
- sqlspec/core/parameters/_transformers.cp314-win_amd64.pyd +0 -0
- sqlspec/core/parameters/_transformers.py +324 -0
- sqlspec/core/parameters/_types.cp314-win_amd64.pyd +0 -0
- sqlspec/core/parameters/_types.py +536 -0
- sqlspec/core/parameters/_validator.cp314-win_amd64.pyd +0 -0
- sqlspec/core/parameters/_validator.py +171 -0
- sqlspec/core/pipeline.cp314-win_amd64.pyd +0 -0
- sqlspec/core/pipeline.py +333 -0
- sqlspec/core/query_modifiers.cp314-win_amd64.pyd +0 -0
- sqlspec/core/query_modifiers.py +508 -0
- sqlspec/core/result/__init__.py +25 -0
- sqlspec/core/result/_base.cp314-win_amd64.pyd +0 -0
- sqlspec/core/result/_base.py +1232 -0
- sqlspec/core/result/_io.cp314-win_amd64.pyd +0 -0
- sqlspec/core/result/_io.py +28 -0
- sqlspec/core/splitter.cp314-win_amd64.pyd +0 -0
- sqlspec/core/splitter.py +1021 -0
- sqlspec/core/sqlcommenter.cp314-win_amd64.pyd +0 -0
- sqlspec/core/sqlcommenter.py +249 -0
- sqlspec/core/stack.cp314-win_amd64.pyd +0 -0
- sqlspec/core/stack.py +163 -0
- sqlspec/core/statement.cp314-win_amd64.pyd +0 -0
- sqlspec/core/statement.py +1865 -0
- sqlspec/core/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/core/type_converter.py +340 -0
- sqlspec/data_dictionary/__init__.py +22 -0
- sqlspec/data_dictionary/_loader.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/_loader.py +138 -0
- sqlspec/data_dictionary/_registry.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/_registry.py +74 -0
- sqlspec/data_dictionary/_types.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/_types.py +121 -0
- sqlspec/data_dictionary/dialects/__init__.py +21 -0
- sqlspec/data_dictionary/dialects/bigquery.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/bigquery.py +81 -0
- sqlspec/data_dictionary/dialects/cockroachdb.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/cockroachdb.py +54 -0
- sqlspec/data_dictionary/dialects/duckdb.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/duckdb.py +47 -0
- sqlspec/data_dictionary/dialects/mysql.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/mysql.py +53 -0
- sqlspec/data_dictionary/dialects/oracle.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/oracle.py +197 -0
- sqlspec/data_dictionary/dialects/postgres.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/postgres.py +69 -0
- sqlspec/data_dictionary/dialects/spanner.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/spanner.py +37 -0
- sqlspec/data_dictionary/dialects/sqlite.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/sqlite.py +59 -0
- sqlspec/data_dictionary/sql/.gitkeep +0 -0
- sqlspec/data_dictionary/sql/bigquery/columns.sql +23 -0
- sqlspec/data_dictionary/sql/bigquery/foreign_keys.sql +34 -0
- sqlspec/data_dictionary/sql/bigquery/indexes.sql +19 -0
- sqlspec/data_dictionary/sql/bigquery/tables.sql +33 -0
- sqlspec/data_dictionary/sql/bigquery/version.sql +3 -0
- sqlspec/data_dictionary/sql/cockroachdb/columns.sql +34 -0
- sqlspec/data_dictionary/sql/cockroachdb/foreign_keys.sql +40 -0
- sqlspec/data_dictionary/sql/cockroachdb/indexes.sql +32 -0
- sqlspec/data_dictionary/sql/cockroachdb/tables.sql +44 -0
- sqlspec/data_dictionary/sql/cockroachdb/version.sql +3 -0
- sqlspec/data_dictionary/sql/duckdb/columns.sql +23 -0
- sqlspec/data_dictionary/sql/duckdb/foreign_keys.sql +36 -0
- sqlspec/data_dictionary/sql/duckdb/indexes.sql +19 -0
- sqlspec/data_dictionary/sql/duckdb/tables.sql +38 -0
- sqlspec/data_dictionary/sql/duckdb/version.sql +3 -0
- sqlspec/data_dictionary/sql/mysql/columns.sql +23 -0
- sqlspec/data_dictionary/sql/mysql/foreign_keys.sql +28 -0
- sqlspec/data_dictionary/sql/mysql/indexes.sql +26 -0
- sqlspec/data_dictionary/sql/mysql/tables.sql +33 -0
- sqlspec/data_dictionary/sql/mysql/version.sql +3 -0
- sqlspec/data_dictionary/sql/oracle/columns.sql +23 -0
- sqlspec/data_dictionary/sql/oracle/foreign_keys.sql +48 -0
- sqlspec/data_dictionary/sql/oracle/indexes.sql +44 -0
- sqlspec/data_dictionary/sql/oracle/tables.sql +25 -0
- sqlspec/data_dictionary/sql/oracle/version.sql +20 -0
- sqlspec/data_dictionary/sql/postgres/columns.sql +34 -0
- sqlspec/data_dictionary/sql/postgres/foreign_keys.sql +40 -0
- sqlspec/data_dictionary/sql/postgres/indexes.sql +56 -0
- sqlspec/data_dictionary/sql/postgres/tables.sql +44 -0
- sqlspec/data_dictionary/sql/postgres/version.sql +3 -0
- sqlspec/data_dictionary/sql/spanner/columns.sql +23 -0
- sqlspec/data_dictionary/sql/spanner/foreign_keys.sql +70 -0
- sqlspec/data_dictionary/sql/spanner/indexes.sql +30 -0
- sqlspec/data_dictionary/sql/spanner/tables.sql +9 -0
- sqlspec/data_dictionary/sql/spanner/version.sql +3 -0
- sqlspec/data_dictionary/sql/sqlite/columns.sql +23 -0
- sqlspec/data_dictionary/sql/sqlite/foreign_keys.sql +22 -0
- sqlspec/data_dictionary/sql/sqlite/indexes.sql +7 -0
- sqlspec/data_dictionary/sql/sqlite/tables.sql +28 -0
- sqlspec/data_dictionary/sql/sqlite/version.sql +3 -0
- sqlspec/dialects/__init__.py +22 -0
- sqlspec/dialects/_compat.cp314-win_amd64.pyd +0 -0
- sqlspec/dialects/_compat.py +14 -0
- sqlspec/dialects/postgres/__init__.py +9 -0
- sqlspec/dialects/postgres/_generators.cp314-win_amd64.pyd +0 -0
- sqlspec/dialects/postgres/_generators.py +57 -0
- sqlspec/dialects/postgres/_operators.cp314-win_amd64.pyd +0 -0
- sqlspec/dialects/postgres/_operators.py +81 -0
- sqlspec/dialects/postgres/_paradedb.py +50 -0
- sqlspec/dialects/postgres/_pgvector.py +36 -0
- sqlspec/dialects/spanner/__init__.py +6 -0
- sqlspec/dialects/spanner/_generators.cp314-win_amd64.pyd +0 -0
- sqlspec/dialects/spanner/_generators.py +206 -0
- sqlspec/dialects/spanner/_spangres.py +77 -0
- sqlspec/dialects/spanner/_spanner.py +179 -0
- sqlspec/driver/__init__.py +49 -0
- sqlspec/driver/_async.cp314-win_amd64.pyd +0 -0
- sqlspec/driver/_async.py +1830 -0
- sqlspec/driver/_common.cp314-win_amd64.pyd +0 -0
- sqlspec/driver/_common.py +2292 -0
- sqlspec/driver/_exception_handler.cp314-win_amd64.pyd +0 -0
- sqlspec/driver/_exception_handler.py +108 -0
- sqlspec/driver/_query_cache.cp314-win_amd64.pyd +0 -0
- sqlspec/driver/_query_cache.py +96 -0
- sqlspec/driver/_sql_helpers.cp314-win_amd64.pyd +0 -0
- sqlspec/driver/_sql_helpers.py +139 -0
- sqlspec/driver/_storage_helpers.cp314-win_amd64.pyd +0 -0
- sqlspec/driver/_storage_helpers.py +153 -0
- sqlspec/driver/_sync.cp314-win_amd64.pyd +0 -0
- sqlspec/driver/_sync.py +1817 -0
- sqlspec/exceptions.cp314-win_amd64.pyd +0 -0
- sqlspec/exceptions.py +480 -0
- sqlspec/extensions/__init__.py +0 -0
- sqlspec/extensions/adk/__init__.py +84 -0
- sqlspec/extensions/adk/_config_utils.py +199 -0
- sqlspec/extensions/adk/_types.cp314-win_amd64.pyd +0 -0
- sqlspec/extensions/adk/_types.py +41 -0
- sqlspec/extensions/adk/artifact/__init__.py +57 -0
- sqlspec/extensions/adk/artifact/_types.cp314-win_amd64.pyd +0 -0
- sqlspec/extensions/adk/artifact/_types.py +32 -0
- sqlspec/extensions/adk/artifact/service.py +508 -0
- sqlspec/extensions/adk/artifact/store.py +361 -0
- sqlspec/extensions/adk/converters.py +212 -0
- sqlspec/extensions/adk/memory/__init__.py +69 -0
- sqlspec/extensions/adk/memory/_types.cp314-win_amd64.pyd +0 -0
- sqlspec/extensions/adk/memory/_types.py +30 -0
- sqlspec/extensions/adk/memory/converters.py +225 -0
- sqlspec/extensions/adk/memory/service.py +316 -0
- sqlspec/extensions/adk/memory/store.py +525 -0
- sqlspec/extensions/adk/migrations/0001_create_adk_tables.py +184 -0
- sqlspec/extensions/adk/migrations/__init__.py +0 -0
- sqlspec/extensions/adk/service.py +279 -0
- sqlspec/extensions/adk/store.py +590 -0
- sqlspec/extensions/events/__init__.py +51 -0
- sqlspec/extensions/events/_channel.py +703 -0
- sqlspec/extensions/events/_hints.cp314-win_amd64.pyd +0 -0
- sqlspec/extensions/events/_hints.py +45 -0
- sqlspec/extensions/events/_models.py +23 -0
- sqlspec/extensions/events/_payload.cp314-win_amd64.pyd +0 -0
- sqlspec/extensions/events/_payload.py +69 -0
- sqlspec/extensions/events/_protocols.py +134 -0
- sqlspec/extensions/events/_queue.py +462 -0
- sqlspec/extensions/events/_store.py +209 -0
- sqlspec/extensions/events/migrations/0001_create_event_queue.py +59 -0
- sqlspec/extensions/events/migrations/__init__.py +3 -0
- sqlspec/extensions/fastapi/__init__.py +22 -0
- sqlspec/extensions/fastapi/extension.py +391 -0
- sqlspec/extensions/fastapi/providers.cp314-win_amd64.pyd +0 -0
- sqlspec/extensions/fastapi/providers.py +712 -0
- sqlspec/extensions/flask/__init__.py +38 -0
- sqlspec/extensions/flask/_state.py +87 -0
- sqlspec/extensions/flask/_utils.py +71 -0
- sqlspec/extensions/flask/extension.py +539 -0
- sqlspec/extensions/litestar/__init__.py +31 -0
- sqlspec/extensions/litestar/_utils.py +52 -0
- sqlspec/extensions/litestar/channels.py +165 -0
- sqlspec/extensions/litestar/cli.py +102 -0
- sqlspec/extensions/litestar/config.py +90 -0
- sqlspec/extensions/litestar/handlers.py +316 -0
- sqlspec/extensions/litestar/migrations/0001_create_session_table.py +137 -0
- sqlspec/extensions/litestar/migrations/__init__.py +3 -0
- sqlspec/extensions/litestar/plugin.py +1066 -0
- sqlspec/extensions/litestar/providers.cp314-win_amd64.pyd +0 -0
- sqlspec/extensions/litestar/providers.py +784 -0
- sqlspec/extensions/litestar/store.py +298 -0
- sqlspec/extensions/otel/__init__.py +58 -0
- sqlspec/extensions/prometheus/__init__.py +113 -0
- sqlspec/extensions/sanic/__init__.py +19 -0
- sqlspec/extensions/sanic/_state.py +43 -0
- sqlspec/extensions/sanic/_utils.py +127 -0
- sqlspec/extensions/sanic/extension.py +647 -0
- sqlspec/extensions/starlette/__init__.py +22 -0
- sqlspec/extensions/starlette/_state.py +42 -0
- sqlspec/extensions/starlette/_utils.py +96 -0
- sqlspec/extensions/starlette/extension.py +374 -0
- sqlspec/extensions/starlette/middleware.py +281 -0
- sqlspec/loader.cp314-win_amd64.pyd +0 -0
- sqlspec/loader.py +727 -0
- sqlspec/migrations/__init__.py +39 -0
- sqlspec/migrations/base.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/base.py +862 -0
- sqlspec/migrations/commands.py +2151 -0
- sqlspec/migrations/context.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/context.py +157 -0
- sqlspec/migrations/fix.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/fix.py +204 -0
- sqlspec/migrations/loaders.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/loaders.py +443 -0
- sqlspec/migrations/runner.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/runner.py +1195 -0
- sqlspec/migrations/squash.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/squash.py +490 -0
- sqlspec/migrations/templates.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/templates.py +234 -0
- sqlspec/migrations/tracker.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/tracker.py +792 -0
- sqlspec/migrations/utils.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/utils.py +256 -0
- sqlspec/migrations/validation.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/validation.py +359 -0
- sqlspec/migrations/version.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/version.py +446 -0
- sqlspec/observability/__init__.py +57 -0
- sqlspec/observability/_common.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_common.py +77 -0
- sqlspec/observability/_config.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_config.py +364 -0
- sqlspec/observability/_diagnostics.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_diagnostics.py +74 -0
- sqlspec/observability/_dispatcher.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_dispatcher.py +200 -0
- sqlspec/observability/_formatters/__init__.py +13 -0
- sqlspec/observability/_formatters/_aws.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_formatters/_aws.py +102 -0
- sqlspec/observability/_formatters/_azure.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_formatters/_azure.py +96 -0
- sqlspec/observability/_formatters/_base.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_formatters/_base.py +57 -0
- sqlspec/observability/_formatters/_gcp.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_formatters/_gcp.py +131 -0
- sqlspec/observability/_formatting.py +58 -0
- sqlspec/observability/_observer.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_observer.py +361 -0
- sqlspec/observability/_runtime.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_runtime.py +461 -0
- sqlspec/observability/_sampling.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_sampling.py +188 -0
- sqlspec/observability/_spans.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_spans.py +161 -0
- sqlspec/protocols.py +955 -0
- sqlspec/py.typed +0 -0
- sqlspec/service.py +433 -0
- sqlspec/storage/__init__.py +48 -0
- sqlspec/storage/_arrow_payload.py +68 -0
- sqlspec/storage/_paths.cp314-win_amd64.pyd +0 -0
- sqlspec/storage/_paths.py +58 -0
- sqlspec/storage/_utils.py +46 -0
- sqlspec/storage/backends/__init__.py +1 -0
- sqlspec/storage/backends/base.cp314-win_amd64.pyd +0 -0
- sqlspec/storage/backends/base.py +374 -0
- sqlspec/storage/backends/fsspec.py +574 -0
- sqlspec/storage/backends/local.py +468 -0
- sqlspec/storage/backends/obstore.py +956 -0
- sqlspec/storage/errors.cp314-win_amd64.pyd +0 -0
- sqlspec/storage/errors.py +102 -0
- sqlspec/storage/pipeline.cp314-win_amd64.pyd +0 -0
- sqlspec/storage/pipeline.py +628 -0
- sqlspec/storage/registry.cp314-win_amd64.pyd +0 -0
- sqlspec/storage/registry.py +329 -0
- sqlspec/typing.py +405 -0
- sqlspec/utils/__init__.py +7 -0
- sqlspec/utils/arrow_helpers.py +384 -0
- sqlspec/utils/config_tools.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/config_tools.py +314 -0
- sqlspec/utils/correlation.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/correlation.py +134 -0
- sqlspec/utils/deprecation.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/deprecation.py +157 -0
- sqlspec/utils/dispatch.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/dispatch.py +101 -0
- sqlspec/utils/fixtures.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/fixtures.py +260 -0
- sqlspec/utils/logging.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/logging.py +251 -0
- sqlspec/utils/module_loader.py +306 -0
- sqlspec/utils/portal.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/portal.py +377 -0
- sqlspec/utils/schema.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/schema.py +1040 -0
- sqlspec/utils/serializers/__init__.py +30 -0
- sqlspec/utils/serializers/_json.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/serializers/_json.py +415 -0
- sqlspec/utils/serializers/_numpy.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/serializers/_numpy.py +65 -0
- sqlspec/utils/serializers/_schema.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/serializers/_schema.py +285 -0
- sqlspec/utils/singleton.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/singleton.py +41 -0
- sqlspec/utils/sync_tools.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/sync_tools.py +316 -0
- sqlspec/utils/text.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/text.py +109 -0
- sqlspec/utils/type_converters.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/type_converters.py +216 -0
- sqlspec/utils/type_guards.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/type_guards.py +1508 -0
- sqlspec/utils/uuids.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/uuids.py +241 -0
- sqlspec-0.47.0.dist-info/METADATA +202 -0
- sqlspec-0.47.0.dist-info/RECORD +621 -0
- sqlspec-0.47.0.dist-info/WHEEL +4 -0
- sqlspec-0.47.0.dist-info/entry_points.txt +6 -0
- sqlspec-0.47.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
"""Spanner configuration."""
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any, ClassVar, TypedDict, cast
|
|
4
|
+
|
|
5
|
+
from google.cloud.spanner_v1 import Client
|
|
6
|
+
from google.cloud.spanner_v1.pool import AbstractSessionPool, FixedSizePool
|
|
7
|
+
from typing_extensions import NotRequired
|
|
8
|
+
|
|
9
|
+
from sqlspec.adapters.spanner._typing import SpannerConnection
|
|
10
|
+
from sqlspec.adapters.spanner.core import apply_driver_features, default_statement_config
|
|
11
|
+
from sqlspec.adapters.spanner.driver import SpannerSessionContext, SpannerSyncDriver
|
|
12
|
+
from sqlspec.config import SyncDatabaseConfig
|
|
13
|
+
from sqlspec.driver._sync import SyncPoolConnectionContext, SyncPoolSessionFactory
|
|
14
|
+
from sqlspec.exceptions import ImproperConfigurationError
|
|
15
|
+
from sqlspec.extensions.events import EventRuntimeHints
|
|
16
|
+
from sqlspec.utils.config_tools import normalize_connection_config
|
|
17
|
+
from sqlspec.utils.type_guards import supports_close
|
|
18
|
+
|
|
19
|
+
if TYPE_CHECKING:
|
|
20
|
+
from collections.abc import Callable
|
|
21
|
+
from types import TracebackType
|
|
22
|
+
|
|
23
|
+
from google.auth.credentials import Credentials
|
|
24
|
+
from google.cloud.spanner_v1.database import Database
|
|
25
|
+
|
|
26
|
+
from sqlspec.config import ExtensionConfigs
|
|
27
|
+
from sqlspec.core import StatementConfig
|
|
28
|
+
from sqlspec.observability import ObservabilityConfig
|
|
29
|
+
|
|
30
|
+
__all__ = ("SpannerConnectionParams", "SpannerDriverFeatures", "SpannerPoolParams", "SpannerSyncConfig")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class SpannerConnectionParams(TypedDict):
|
|
34
|
+
"""Spanner connection parameters."""
|
|
35
|
+
|
|
36
|
+
project: "NotRequired[str]"
|
|
37
|
+
instance_id: "NotRequired[str]"
|
|
38
|
+
database_id: "NotRequired[str]"
|
|
39
|
+
credentials: "NotRequired[Credentials]"
|
|
40
|
+
client_options: "NotRequired[dict[str, Any]]"
|
|
41
|
+
extra: "NotRequired[dict[str, Any]]"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class SpannerPoolParams(SpannerConnectionParams):
|
|
45
|
+
"""Session pool configuration."""
|
|
46
|
+
|
|
47
|
+
pool_type: "NotRequired[type[AbstractSessionPool]]"
|
|
48
|
+
min_sessions: "NotRequired[int]"
|
|
49
|
+
max_sessions: "NotRequired[int]"
|
|
50
|
+
labels: "NotRequired[dict[str, str]]"
|
|
51
|
+
ping_interval: "NotRequired[int]"
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class SpannerDriverFeatures(TypedDict):
|
|
55
|
+
"""Driver feature flags for Spanner.
|
|
56
|
+
|
|
57
|
+
Attributes:
|
|
58
|
+
enable_uuid_conversion: Enable automatic UUID string conversion.
|
|
59
|
+
json_serializer: Custom JSON serializer for parameter conversion.
|
|
60
|
+
json_deserializer: Custom JSON deserializer for result conversion.
|
|
61
|
+
session_labels: Labels to apply to Spanner sessions.
|
|
62
|
+
enable_events: Enable database event channel support.
|
|
63
|
+
Defaults to True when extension_config["events"] is configured.
|
|
64
|
+
events_backend: Backend type for event handling.
|
|
65
|
+
Spanner only supports "table_queue" (no native pub/sub).
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
enable_uuid_conversion: "NotRequired[bool]"
|
|
69
|
+
json_serializer: "NotRequired[Callable[[Any], str]]"
|
|
70
|
+
json_deserializer: "NotRequired[Callable[[str], Any]]"
|
|
71
|
+
session_labels: "NotRequired[dict[str, str]]"
|
|
72
|
+
enable_events: "NotRequired[bool]"
|
|
73
|
+
events_backend: "NotRequired[str]"
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class SpannerConnectionContext(SyncPoolConnectionContext):
|
|
77
|
+
"""Context manager for Spanner connections."""
|
|
78
|
+
|
|
79
|
+
__slots__ = ("_connection", "_session", "_transaction")
|
|
80
|
+
|
|
81
|
+
def __init__(self, config: "SpannerSyncConfig", transaction: bool = False) -> None:
|
|
82
|
+
super().__init__(config)
|
|
83
|
+
self._transaction = transaction
|
|
84
|
+
self._connection: SpannerConnection | None = None
|
|
85
|
+
self._session: Any = None
|
|
86
|
+
|
|
87
|
+
def __enter__(self) -> SpannerConnection:
|
|
88
|
+
database = self._config.get_database()
|
|
89
|
+
if self._transaction:
|
|
90
|
+
self._session = cast("Any", database).session()
|
|
91
|
+
self._session.create()
|
|
92
|
+
try:
|
|
93
|
+
txn = self._session.transaction()
|
|
94
|
+
txn.__enter__()
|
|
95
|
+
self._connection = cast("SpannerConnection", txn)
|
|
96
|
+
except Exception:
|
|
97
|
+
self._session.delete()
|
|
98
|
+
raise
|
|
99
|
+
else:
|
|
100
|
+
return self._connection
|
|
101
|
+
else:
|
|
102
|
+
self._session = cast("Any", database).snapshot(multi_use=True)
|
|
103
|
+
self._connection = cast("SpannerConnection", self._session.__enter__())
|
|
104
|
+
return self._connection
|
|
105
|
+
|
|
106
|
+
def __exit__(
|
|
107
|
+
self, exc_type: "type[BaseException] | None", exc_val: "BaseException | None", exc_tb: "TracebackType | None"
|
|
108
|
+
) -> bool | None:
|
|
109
|
+
if self._transaction and self._connection:
|
|
110
|
+
txn = cast("Any", self._connection)
|
|
111
|
+
try:
|
|
112
|
+
if exc_type is None:
|
|
113
|
+
try:
|
|
114
|
+
txn_id = txn._transaction_id
|
|
115
|
+
except AttributeError:
|
|
116
|
+
txn_id = None
|
|
117
|
+
try:
|
|
118
|
+
committed = txn.committed
|
|
119
|
+
except AttributeError:
|
|
120
|
+
committed = None
|
|
121
|
+
if txn_id is not None and committed is None:
|
|
122
|
+
txn.commit()
|
|
123
|
+
else:
|
|
124
|
+
try:
|
|
125
|
+
rollback_txn_id = txn._transaction_id
|
|
126
|
+
except AttributeError:
|
|
127
|
+
rollback_txn_id = None
|
|
128
|
+
if rollback_txn_id is not None:
|
|
129
|
+
txn.rollback()
|
|
130
|
+
finally:
|
|
131
|
+
if self._session:
|
|
132
|
+
self._session.delete()
|
|
133
|
+
elif self._session:
|
|
134
|
+
self._session.__exit__(exc_type, exc_val, exc_tb)
|
|
135
|
+
|
|
136
|
+
self._connection = None
|
|
137
|
+
self._session = None
|
|
138
|
+
return None
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class _SpannerSessionConnectionHandler(SyncPoolSessionFactory):
|
|
142
|
+
__slots__ = ("_connection_ctx",)
|
|
143
|
+
|
|
144
|
+
def __init__(self, config: "SpannerSyncConfig", connection_ctx: "SpannerConnectionContext") -> None:
|
|
145
|
+
super().__init__(config)
|
|
146
|
+
self._connection_ctx = connection_ctx
|
|
147
|
+
|
|
148
|
+
def acquire_connection(self) -> "SpannerConnection":
|
|
149
|
+
return self._connection_ctx.__enter__()
|
|
150
|
+
|
|
151
|
+
def release_connection(self, _conn: "SpannerConnection", **kwargs: Any) -> None:
|
|
152
|
+
self._connection_ctx.__exit__(kwargs.get("exc_type"), kwargs.get("exc_val"), kwargs.get("exc_tb"))
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
class SpannerSyncConfig(SyncDatabaseConfig["SpannerConnection", "AbstractSessionPool", SpannerSyncDriver]):
|
|
156
|
+
"""Spanner configuration and session management."""
|
|
157
|
+
|
|
158
|
+
driver_type: ClassVar[type["SpannerSyncDriver"]] = SpannerSyncDriver
|
|
159
|
+
connection_type: ClassVar[type["SpannerConnection"]] = cast("type[SpannerConnection]", SpannerConnection)
|
|
160
|
+
supports_transactional_ddl: ClassVar[bool] = False
|
|
161
|
+
supports_native_arrow_export: ClassVar[bool] = True
|
|
162
|
+
supports_native_arrow_import: ClassVar[bool] = True
|
|
163
|
+
supports_native_parquet_export: ClassVar[bool] = False
|
|
164
|
+
supports_native_parquet_import: ClassVar[bool] = False
|
|
165
|
+
requires_staging_for_load: ClassVar[bool] = False
|
|
166
|
+
_connection_context_class: "ClassVar[type[SpannerConnectionContext]]" = SpannerConnectionContext
|
|
167
|
+
_session_factory_class: "ClassVar[type[_SpannerSessionConnectionHandler]]" = _SpannerSessionConnectionHandler
|
|
168
|
+
_session_context_class: "ClassVar[type[SpannerSessionContext]]" = SpannerSessionContext
|
|
169
|
+
_default_statement_config = default_statement_config
|
|
170
|
+
|
|
171
|
+
def __init__(
|
|
172
|
+
self,
|
|
173
|
+
*,
|
|
174
|
+
connection_config: "SpannerPoolParams | dict[str, Any] | None" = None,
|
|
175
|
+
connection_instance: "AbstractSessionPool | None" = None,
|
|
176
|
+
migration_config: "dict[str, Any] | None" = None,
|
|
177
|
+
statement_config: "StatementConfig | None" = None,
|
|
178
|
+
driver_features: "SpannerDriverFeatures | dict[str, Any] | None" = None,
|
|
179
|
+
bind_key: "str | None" = None,
|
|
180
|
+
extension_config: "ExtensionConfigs | None" = None,
|
|
181
|
+
observability_config: "ObservabilityConfig | None" = None,
|
|
182
|
+
**kwargs: Any,
|
|
183
|
+
) -> None:
|
|
184
|
+
self.connection_config = normalize_connection_config(connection_config)
|
|
185
|
+
|
|
186
|
+
self.connection_config.setdefault("min_sessions", 1)
|
|
187
|
+
self.connection_config.setdefault("max_sessions", 10)
|
|
188
|
+
self.connection_config.setdefault("pool_type", FixedSizePool)
|
|
189
|
+
|
|
190
|
+
driver_features = apply_driver_features(driver_features)
|
|
191
|
+
|
|
192
|
+
statement_config = statement_config or default_statement_config
|
|
193
|
+
|
|
194
|
+
super().__init__(
|
|
195
|
+
connection_config=self.connection_config,
|
|
196
|
+
connection_instance=connection_instance,
|
|
197
|
+
migration_config=migration_config,
|
|
198
|
+
statement_config=statement_config,
|
|
199
|
+
driver_features=driver_features,
|
|
200
|
+
bind_key=bind_key,
|
|
201
|
+
extension_config=extension_config,
|
|
202
|
+
observability_config=observability_config,
|
|
203
|
+
**kwargs,
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
self._client: Client | None = None
|
|
207
|
+
self._database: Database | None = None
|
|
208
|
+
|
|
209
|
+
def _get_client(self) -> Client:
|
|
210
|
+
if self._client is None:
|
|
211
|
+
self._client = Client(
|
|
212
|
+
project=self.connection_config.get("project"),
|
|
213
|
+
credentials=self.connection_config.get("credentials"),
|
|
214
|
+
client_options=self.connection_config.get("client_options"),
|
|
215
|
+
)
|
|
216
|
+
return self._client
|
|
217
|
+
|
|
218
|
+
def get_database(self) -> "Database":
|
|
219
|
+
instance_id = self.connection_config.get("instance_id")
|
|
220
|
+
database_id = self.connection_config.get("database_id")
|
|
221
|
+
if not instance_id or not database_id:
|
|
222
|
+
msg = "instance_id and database_id are required."
|
|
223
|
+
raise ImproperConfigurationError(msg)
|
|
224
|
+
|
|
225
|
+
if self.connection_instance is None:
|
|
226
|
+
self.connection_instance = self.provide_pool()
|
|
227
|
+
|
|
228
|
+
if self._database is None:
|
|
229
|
+
client = self._get_client()
|
|
230
|
+
self._database = client.instance(instance_id).database(database_id, pool=self.connection_instance) # type: ignore[no-untyped-call]
|
|
231
|
+
return self._database
|
|
232
|
+
|
|
233
|
+
def create_connection(self) -> SpannerConnection:
|
|
234
|
+
instance_id = self.connection_config.get("instance_id")
|
|
235
|
+
database_id = self.connection_config.get("database_id")
|
|
236
|
+
if not instance_id or not database_id:
|
|
237
|
+
msg = "instance_id and database_id are required."
|
|
238
|
+
raise ImproperConfigurationError(msg)
|
|
239
|
+
|
|
240
|
+
if self.connection_instance is None:
|
|
241
|
+
self.connection_instance = self.provide_pool()
|
|
242
|
+
|
|
243
|
+
client = self._get_client()
|
|
244
|
+
database = client.instance(instance_id).database(database_id, pool=self.connection_instance) # type: ignore[no-untyped-call]
|
|
245
|
+
return cast("SpannerConnection", database.snapshot())
|
|
246
|
+
|
|
247
|
+
def _create_pool(self) -> AbstractSessionPool:
|
|
248
|
+
instance_id = self.connection_config.get("instance_id")
|
|
249
|
+
database_id = self.connection_config.get("database_id")
|
|
250
|
+
if not instance_id or not database_id:
|
|
251
|
+
msg = "instance_id and database_id are required."
|
|
252
|
+
raise ImproperConfigurationError(msg)
|
|
253
|
+
|
|
254
|
+
pool_type = cast("type[AbstractSessionPool]", self.connection_config.get("pool_type", FixedSizePool))
|
|
255
|
+
|
|
256
|
+
pool_kwargs: dict[str, Any] = {}
|
|
257
|
+
if pool_type is FixedSizePool:
|
|
258
|
+
if "size" in self.connection_config:
|
|
259
|
+
pool_kwargs["size"] = self.connection_config["size"]
|
|
260
|
+
elif "max_sessions" in self.connection_config:
|
|
261
|
+
pool_kwargs["size"] = self.connection_config["max_sessions"]
|
|
262
|
+
if "labels" in self.connection_config:
|
|
263
|
+
pool_kwargs["labels"] = self.connection_config["labels"]
|
|
264
|
+
else:
|
|
265
|
+
valid_pool_keys = {"size", "labels", "ping_interval"}
|
|
266
|
+
pool_kwargs = {k: v for k, v in self.connection_config.items() if k in valid_pool_keys and v is not None}
|
|
267
|
+
if "size" not in pool_kwargs and "max_sessions" in self.connection_config:
|
|
268
|
+
pool_kwargs["size"] = self.connection_config["max_sessions"]
|
|
269
|
+
|
|
270
|
+
pool_factory = cast("Callable[..., AbstractSessionPool]", pool_type)
|
|
271
|
+
return pool_factory(**pool_kwargs)
|
|
272
|
+
|
|
273
|
+
def _close_pool(self) -> None:
|
|
274
|
+
if self.connection_instance and supports_close(self.connection_instance):
|
|
275
|
+
self.connection_instance.close()
|
|
276
|
+
if self._client and supports_close(self._client):
|
|
277
|
+
self._client.close()
|
|
278
|
+
self._client = None
|
|
279
|
+
self._database = None
|
|
280
|
+
|
|
281
|
+
def provide_connection(self, *args: Any, transaction: "bool" = False, **kwargs: Any) -> "SpannerConnectionContext":
|
|
282
|
+
"""Yield a Snapshot (default) or Transaction context from the configured pool.
|
|
283
|
+
|
|
284
|
+
Args:
|
|
285
|
+
*args: Additional positional arguments (unused, for interface compatibility).
|
|
286
|
+
transaction: If True, yields a Transaction context that supports
|
|
287
|
+
execute_update() for DML statements. If False (default), yields
|
|
288
|
+
a read-only Snapshot context for SELECT queries.
|
|
289
|
+
**kwargs: Additional keyword arguments (unused, for interface compatibility).
|
|
290
|
+
"""
|
|
291
|
+
return SpannerConnectionContext(self, transaction=transaction)
|
|
292
|
+
|
|
293
|
+
def provide_session(
|
|
294
|
+
self, *args: Any, statement_config: "StatementConfig | None" = None, transaction: "bool" = False, **kwargs: Any
|
|
295
|
+
) -> "SpannerSessionContext":
|
|
296
|
+
"""Provide a Spanner driver session context manager.
|
|
297
|
+
|
|
298
|
+
Args:
|
|
299
|
+
*args: Additional arguments.
|
|
300
|
+
statement_config: Optional statement configuration override.
|
|
301
|
+
transaction: Whether to use a transaction.
|
|
302
|
+
**kwargs: Additional keyword arguments.
|
|
303
|
+
|
|
304
|
+
Returns:
|
|
305
|
+
A Spanner driver session context manager.
|
|
306
|
+
"""
|
|
307
|
+
connection_ctx = SpannerConnectionContext(self, transaction=transaction)
|
|
308
|
+
handler = _SpannerSessionConnectionHandler(self, connection_ctx)
|
|
309
|
+
|
|
310
|
+
return SpannerSessionContext(
|
|
311
|
+
acquire_connection=handler.acquire_connection,
|
|
312
|
+
release_connection=handler.release_connection,
|
|
313
|
+
statement_config=statement_config or self.statement_config or default_statement_config,
|
|
314
|
+
driver_features=self.driver_features,
|
|
315
|
+
prepare_driver=self._prepare_driver,
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
def provide_write_session(
|
|
319
|
+
self, *args: Any, statement_config: "StatementConfig | None" = None, **kwargs: Any
|
|
320
|
+
) -> "SpannerSessionContext":
|
|
321
|
+
"""Provide a Spanner driver write session context manager.
|
|
322
|
+
|
|
323
|
+
Args:
|
|
324
|
+
*args: Additional arguments.
|
|
325
|
+
statement_config: Optional statement configuration override.
|
|
326
|
+
**kwargs: Additional keyword arguments.
|
|
327
|
+
|
|
328
|
+
Returns:
|
|
329
|
+
A Spanner driver write session context manager.
|
|
330
|
+
"""
|
|
331
|
+
return self.provide_session(*args, statement_config=statement_config, transaction=True, **kwargs)
|
|
332
|
+
|
|
333
|
+
def get_signature_namespace(self) -> "dict[str, Any]":
|
|
334
|
+
"""Get the signature namespace for SpannerSyncConfig types.
|
|
335
|
+
|
|
336
|
+
Returns:
|
|
337
|
+
Dictionary mapping type names to types.
|
|
338
|
+
"""
|
|
339
|
+
namespace = super().get_signature_namespace()
|
|
340
|
+
namespace.update({
|
|
341
|
+
"SpannerConnectionContext": SpannerConnectionContext,
|
|
342
|
+
"SpannerConnection": SpannerConnection,
|
|
343
|
+
"SpannerConnectionParams": SpannerConnectionParams,
|
|
344
|
+
"SpannerDriverFeatures": SpannerDriverFeatures,
|
|
345
|
+
"SpannerPoolParams": SpannerPoolParams,
|
|
346
|
+
"SpannerSessionContext": SpannerSessionContext,
|
|
347
|
+
"SpannerSyncConfig": SpannerSyncConfig,
|
|
348
|
+
"SpannerSyncDriver": SpannerSyncDriver,
|
|
349
|
+
})
|
|
350
|
+
return namespace
|
|
351
|
+
|
|
352
|
+
def get_event_runtime_hints(self) -> "EventRuntimeHints":
|
|
353
|
+
"""Return queue defaults for Spanner JSON handling."""
|
|
354
|
+
|
|
355
|
+
return EventRuntimeHints(json_passthrough=True)
|
|
Binary file
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
"""Spanner adapter compiled helpers."""
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
4
|
+
|
|
5
|
+
from google.api_core import exceptions as api_exceptions
|
|
6
|
+
|
|
7
|
+
from sqlspec.adapters.spanner.type_converter import coerce_params_for_spanner, infer_spanner_param_types
|
|
8
|
+
from sqlspec.core import DriverParameterProfile, ParameterStyle, StatementConfig, build_statement_config_from_profile
|
|
9
|
+
from sqlspec.exceptions import (
|
|
10
|
+
DeadlockError,
|
|
11
|
+
NotFoundError,
|
|
12
|
+
OperationalError,
|
|
13
|
+
PermissionDeniedError,
|
|
14
|
+
QueryTimeoutError,
|
|
15
|
+
SQLParsingError,
|
|
16
|
+
SQLSpecError,
|
|
17
|
+
UniqueViolationError,
|
|
18
|
+
)
|
|
19
|
+
from sqlspec.utils.arrow_helpers import convert_dict_to_arrow
|
|
20
|
+
from sqlspec.utils.serializers import from_json, to_json
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from collections.abc import Callable, Mapping, Sequence
|
|
24
|
+
|
|
25
|
+
from sqlspec.typing import ArrowRecordBatch, ArrowRecordBatchReader, ArrowReturnFormat, ArrowTable
|
|
26
|
+
|
|
27
|
+
__all__ = (
|
|
28
|
+
"apply_driver_features",
|
|
29
|
+
"build_param_type_signature",
|
|
30
|
+
"build_profile",
|
|
31
|
+
"build_statement_config",
|
|
32
|
+
"coerce_params",
|
|
33
|
+
"collect_rows",
|
|
34
|
+
"create_arrow_data",
|
|
35
|
+
"create_mapped_exception",
|
|
36
|
+
"default_statement_config",
|
|
37
|
+
"driver_profile",
|
|
38
|
+
"infer_param_types",
|
|
39
|
+
"resolve_column_names",
|
|
40
|
+
"supports_batch_update",
|
|
41
|
+
"supports_write",
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
COLUMN_CACHE_MAX_SIZE: int = 128
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def build_profile() -> "DriverParameterProfile":
|
|
48
|
+
"""Create the Spanner driver parameter profile."""
|
|
49
|
+
|
|
50
|
+
return DriverParameterProfile(
|
|
51
|
+
name="Spanner",
|
|
52
|
+
default_style=ParameterStyle.NAMED_AT,
|
|
53
|
+
supported_styles={ParameterStyle.NAMED_AT},
|
|
54
|
+
default_execution_style=ParameterStyle.NAMED_AT,
|
|
55
|
+
supported_execution_styles={ParameterStyle.NAMED_AT},
|
|
56
|
+
has_native_list_expansion=True,
|
|
57
|
+
json_serializer_strategy="none",
|
|
58
|
+
default_dialect="spanner",
|
|
59
|
+
preserve_parameter_format=True,
|
|
60
|
+
needs_static_script_compilation=False,
|
|
61
|
+
allow_mixed_parameter_styles=False,
|
|
62
|
+
preserve_original_params_for_many=True,
|
|
63
|
+
custom_type_coercions=None,
|
|
64
|
+
extras={},
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
driver_profile = build_profile()
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def build_statement_config() -> StatementConfig:
|
|
72
|
+
"""Construct the Spanner statement configuration."""
|
|
73
|
+
profile = driver_profile
|
|
74
|
+
return build_statement_config_from_profile(profile, statement_overrides={"dialect": "spanner"})
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
default_statement_config = build_statement_config()
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def apply_driver_features(driver_features: "Mapping[str, Any] | None") -> "dict[str, Any]":
|
|
81
|
+
"""Apply Spanner driver feature defaults."""
|
|
82
|
+
processed_features: dict[str, Any] = dict(driver_features) if driver_features else {}
|
|
83
|
+
processed_features.setdefault("enable_uuid_conversion", True)
|
|
84
|
+
processed_features.setdefault("json_serializer", to_json)
|
|
85
|
+
processed_features.setdefault("json_deserializer", from_json)
|
|
86
|
+
return processed_features
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def supports_write(cursor: Any) -> bool:
|
|
90
|
+
"""Return True when the cursor supports DML execution."""
|
|
91
|
+
try:
|
|
92
|
+
_ = cursor.execute_update
|
|
93
|
+
except AttributeError:
|
|
94
|
+
return False
|
|
95
|
+
return True
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def supports_batch_update(cursor: Any) -> bool:
|
|
99
|
+
"""Return True when the cursor supports batch updates."""
|
|
100
|
+
try:
|
|
101
|
+
_ = cursor.batch_update
|
|
102
|
+
except AttributeError:
|
|
103
|
+
return False
|
|
104
|
+
return True
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def infer_param_types(params: "dict[str, Any] | list[Any] | tuple[Any, ...] | None") -> "dict[str, Any]":
|
|
108
|
+
"""Infer Spanner param_types from Python values."""
|
|
109
|
+
if not isinstance(params, dict):
|
|
110
|
+
return {}
|
|
111
|
+
return infer_spanner_param_types(params)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def build_param_type_signature(params: "dict[str, Any] | None") -> "tuple[tuple[str, type[Any]], ...]":
|
|
115
|
+
"""Build a hashable signature for Spanner param type inference caching.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
params: Coerced parameter mapping.
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
Tuple signature based on parameter keys and value runtime types.
|
|
122
|
+
"""
|
|
123
|
+
if not params:
|
|
124
|
+
return ()
|
|
125
|
+
return tuple((key, type(value)) for key, value in params.items())
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def resolve_column_names(fields: "Sequence[Any] | None", cache: "dict[int, tuple[Any, list[str]]]") -> list[str]:
|
|
129
|
+
"""Resolve and cache Spanner field names for row materialization."""
|
|
130
|
+
if not fields:
|
|
131
|
+
return []
|
|
132
|
+
|
|
133
|
+
cache_key = id(fields)
|
|
134
|
+
cached = cache.get(cache_key)
|
|
135
|
+
if cached is not None and cached[0] is fields:
|
|
136
|
+
return cached[1]
|
|
137
|
+
|
|
138
|
+
column_names = [field.name for field in fields]
|
|
139
|
+
if len(cache) >= COLUMN_CACHE_MAX_SIZE:
|
|
140
|
+
cache.pop(next(iter(cache)))
|
|
141
|
+
cache[cache_key] = (fields, column_names)
|
|
142
|
+
return column_names
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def coerce_params(
|
|
146
|
+
params: "dict[str, Any] | list[Any] | tuple[Any, ...] | None",
|
|
147
|
+
*,
|
|
148
|
+
json_serializer: "Callable[[Any], str] | None" = None,
|
|
149
|
+
) -> "dict[str, Any] | None":
|
|
150
|
+
"""Coerce Python types to Spanner-compatible formats."""
|
|
151
|
+
if not isinstance(params, dict):
|
|
152
|
+
return None
|
|
153
|
+
return coerce_params_for_spanner(params, json_serializer=json_serializer)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def collect_rows(
|
|
157
|
+
rows: "Sequence[Any]", fields: "Sequence[Any]", converter: Any, *, column_names: "list[str] | None" = None
|
|
158
|
+
) -> "tuple[list[tuple[Any, ...]], list[str]]":
|
|
159
|
+
"""Collect Spanner rows as tuples with type conversion applied.
|
|
160
|
+
|
|
161
|
+
Type conversion is still applied to each row value. The raw converted
|
|
162
|
+
tuples are returned instead of dicts so that ``SQLResult`` can handle
|
|
163
|
+
lazy dict materialization based on ``row_format``.
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
rows: Rows from result set.
|
|
167
|
+
fields: Result set fields metadata.
|
|
168
|
+
converter: Type converter for row values.
|
|
169
|
+
column_names: Optional precomputed column names.
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
Tuple of (rows, column_names).
|
|
173
|
+
"""
|
|
174
|
+
resolved_column_names = column_names if column_names is not None else [field.name for field in fields]
|
|
175
|
+
num_columns = len(resolved_column_names)
|
|
176
|
+
string_converter = converter.convert_if_detected
|
|
177
|
+
data: list[tuple[Any, ...]] = []
|
|
178
|
+
append = data.append
|
|
179
|
+
for row in rows:
|
|
180
|
+
converted_row: list[Any] = []
|
|
181
|
+
append_value = converted_row.append
|
|
182
|
+
for index in range(num_columns):
|
|
183
|
+
value = row[index]
|
|
184
|
+
if isinstance(value, str):
|
|
185
|
+
value = string_converter(value)
|
|
186
|
+
append_value(value)
|
|
187
|
+
append(tuple(converted_row))
|
|
188
|
+
return data, resolved_column_names
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def create_arrow_data(
|
|
192
|
+
data: "list[dict[str, Any]]", return_format: "ArrowReturnFormat"
|
|
193
|
+
) -> "ArrowTable | ArrowRecordBatch | ArrowRecordBatchReader | list[ArrowRecordBatch]":
|
|
194
|
+
"""Create Arrow data from Spanner row dictionaries.
|
|
195
|
+
|
|
196
|
+
Args:
|
|
197
|
+
data: Row dictionaries from Spanner results.
|
|
198
|
+
return_format: Arrow return format.
|
|
199
|
+
|
|
200
|
+
Returns:
|
|
201
|
+
Arrow data in the requested format.
|
|
202
|
+
"""
|
|
203
|
+
return convert_dict_to_arrow(data, return_format=return_format)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def _create_spanner_error(error: Any, error_class: type[SQLSpecError], description: str) -> SQLSpecError:
|
|
207
|
+
"""Create a Spanner error instance without raising it."""
|
|
208
|
+
msg = f"Spanner {description}: {error}"
|
|
209
|
+
exc = error_class(msg)
|
|
210
|
+
exc.__cause__ = error
|
|
211
|
+
return exc
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def create_mapped_exception(error: Any) -> SQLSpecError:
|
|
215
|
+
"""Map Spanner exceptions to SQLSpec exceptions.
|
|
216
|
+
|
|
217
|
+
This is a factory function that returns an exception instance rather than
|
|
218
|
+
raising. This pattern is more robust for use in __exit__ handlers and
|
|
219
|
+
avoids issues with exception control flow in different Python versions.
|
|
220
|
+
|
|
221
|
+
Mapping priority:
|
|
222
|
+
1. Native google.api_core exception types (isinstance checks)
|
|
223
|
+
2. Default SQLSpecError fallback
|
|
224
|
+
|
|
225
|
+
Args:
|
|
226
|
+
error: The Spanner exception to map
|
|
227
|
+
|
|
228
|
+
Returns:
|
|
229
|
+
A SQLSpec exception that wraps the original error
|
|
230
|
+
"""
|
|
231
|
+
# Integrity errors
|
|
232
|
+
if isinstance(error, api_exceptions.AlreadyExists):
|
|
233
|
+
return _create_spanner_error(error, UniqueViolationError, "resource already exists")
|
|
234
|
+
|
|
235
|
+
# Resource not found
|
|
236
|
+
if isinstance(error, api_exceptions.NotFound):
|
|
237
|
+
return _create_spanner_error(error, NotFoundError, "resource not found")
|
|
238
|
+
|
|
239
|
+
# SQL/argument errors
|
|
240
|
+
if isinstance(error, api_exceptions.InvalidArgument):
|
|
241
|
+
return _create_spanner_error(error, SQLParsingError, "invalid query or argument")
|
|
242
|
+
|
|
243
|
+
# Permission/authentication errors
|
|
244
|
+
if isinstance(error, api_exceptions.PermissionDenied):
|
|
245
|
+
return _create_spanner_error(error, PermissionDeniedError, "permission denied")
|
|
246
|
+
if isinstance(error, api_exceptions.Unauthenticated):
|
|
247
|
+
return _create_spanner_error(error, PermissionDeniedError, "authentication failed")
|
|
248
|
+
|
|
249
|
+
# Transaction errors (deadlock/abort)
|
|
250
|
+
if isinstance(error, api_exceptions.Aborted):
|
|
251
|
+
return _create_spanner_error(error, DeadlockError, "transaction aborted")
|
|
252
|
+
|
|
253
|
+
# Query timeout/cancellation
|
|
254
|
+
if isinstance(error, api_exceptions.Cancelled):
|
|
255
|
+
return _create_spanner_error(error, QueryTimeoutError, "operation cancelled")
|
|
256
|
+
if isinstance(error, api_exceptions.DeadlineExceeded):
|
|
257
|
+
return _create_spanner_error(error, QueryTimeoutError, "deadline exceeded")
|
|
258
|
+
|
|
259
|
+
# Service/operational errors
|
|
260
|
+
if isinstance(error, (api_exceptions.ServiceUnavailable, api_exceptions.TooManyRequests)):
|
|
261
|
+
return _create_spanner_error(error, OperationalError, "service unavailable or rate limited")
|
|
262
|
+
|
|
263
|
+
return _create_spanner_error(error, SQLSpecError, "error")
|