sqlspec 0.36.0__cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.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.
- ac8f31065839703b4e70__mypyc.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/__init__.py +140 -0
- sqlspec/__main__.py +12 -0
- sqlspec/__metadata__.py +14 -0
- sqlspec/_serialization.py +315 -0
- sqlspec/_typing.py +700 -0
- sqlspec/adapters/__init__.py +0 -0
- sqlspec/adapters/adbc/__init__.py +5 -0
- sqlspec/adapters/adbc/_typing.py +82 -0
- sqlspec/adapters/adbc/adk/__init__.py +5 -0
- sqlspec/adapters/adbc/adk/store.py +1273 -0
- sqlspec/adapters/adbc/config.py +295 -0
- sqlspec/adapters/adbc/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/adbc/core.py +735 -0
- sqlspec/adapters/adbc/data_dictionary.py +334 -0
- sqlspec/adapters/adbc/driver.py +529 -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 +502 -0
- sqlspec/adapters/adbc/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/adbc/type_converter.py +140 -0
- sqlspec/adapters/aiosqlite/__init__.py +25 -0
- sqlspec/adapters/aiosqlite/_typing.py +82 -0
- sqlspec/adapters/aiosqlite/adk/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/adk/store.py +818 -0
- sqlspec/adapters/aiosqlite/config.py +334 -0
- sqlspec/adapters/aiosqlite/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/aiosqlite/core.py +315 -0
- sqlspec/adapters/aiosqlite/data_dictionary.py +208 -0
- sqlspec/adapters/aiosqlite/driver.py +313 -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.py +533 -0
- sqlspec/adapters/asyncmy/__init__.py +21 -0
- sqlspec/adapters/asyncmy/_typing.py +87 -0
- sqlspec/adapters/asyncmy/adk/__init__.py +5 -0
- sqlspec/adapters/asyncmy/adk/store.py +703 -0
- sqlspec/adapters/asyncmy/config.py +302 -0
- sqlspec/adapters/asyncmy/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/asyncmy/core.py +360 -0
- sqlspec/adapters/asyncmy/data_dictionary.py +124 -0
- sqlspec/adapters/asyncmy/driver.py +383 -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 +19 -0
- sqlspec/adapters/asyncpg/_typing.py +88 -0
- sqlspec/adapters/asyncpg/adk/__init__.py +5 -0
- sqlspec/adapters/asyncpg/adk/store.py +748 -0
- sqlspec/adapters/asyncpg/config.py +569 -0
- sqlspec/adapters/asyncpg/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/asyncpg/core.py +367 -0
- sqlspec/adapters/asyncpg/data_dictionary.py +162 -0
- sqlspec/adapters/asyncpg/driver.py +487 -0
- sqlspec/adapters/asyncpg/events/__init__.py +6 -0
- sqlspec/adapters/asyncpg/events/backend.py +286 -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 +14 -0
- sqlspec/adapters/bigquery/_typing.py +86 -0
- sqlspec/adapters/bigquery/adk/__init__.py +5 -0
- sqlspec/adapters/bigquery/adk/store.py +827 -0
- sqlspec/adapters/bigquery/config.py +353 -0
- sqlspec/adapters/bigquery/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/bigquery/core.py +715 -0
- sqlspec/adapters/bigquery/data_dictionary.py +128 -0
- sqlspec/adapters/bigquery/driver.py +548 -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.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/bigquery/type_converter.py +107 -0
- sqlspec/adapters/cockroach_asyncpg/__init__.py +24 -0
- sqlspec/adapters/cockroach_asyncpg/_typing.py +72 -0
- sqlspec/adapters/cockroach_asyncpg/adk/__init__.py +3 -0
- sqlspec/adapters/cockroach_asyncpg/adk/store.py +410 -0
- sqlspec/adapters/cockroach_asyncpg/config.py +238 -0
- sqlspec/adapters/cockroach_asyncpg/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/cockroach_asyncpg/core.py +55 -0
- sqlspec/adapters/cockroach_asyncpg/data_dictionary.py +107 -0
- sqlspec/adapters/cockroach_asyncpg/driver.py +144 -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 +38 -0
- sqlspec/adapters/cockroach_psycopg/_typing.py +129 -0
- sqlspec/adapters/cockroach_psycopg/adk/__init__.py +13 -0
- sqlspec/adapters/cockroach_psycopg/adk/store.py +868 -0
- sqlspec/adapters/cockroach_psycopg/config.py +484 -0
- sqlspec/adapters/cockroach_psycopg/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/cockroach_psycopg/core.py +63 -0
- sqlspec/adapters/cockroach_psycopg/data_dictionary.py +215 -0
- sqlspec/adapters/cockroach_psycopg/driver.py +284 -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 +325 -0
- sqlspec/adapters/duckdb/__init__.py +25 -0
- sqlspec/adapters/duckdb/_typing.py +81 -0
- sqlspec/adapters/duckdb/adk/__init__.py +14 -0
- sqlspec/adapters/duckdb/adk/store.py +850 -0
- sqlspec/adapters/duckdb/config.py +463 -0
- sqlspec/adapters/duckdb/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/duckdb/core.py +257 -0
- sqlspec/adapters/duckdb/data_dictionary.py +140 -0
- sqlspec/adapters/duckdb/driver.py +430 -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.py +293 -0
- sqlspec/adapters/duckdb/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/duckdb/type_converter.py +118 -0
- sqlspec/adapters/mock/__init__.py +72 -0
- sqlspec/adapters/mock/_typing.py +147 -0
- sqlspec/adapters/mock/config.py +483 -0
- sqlspec/adapters/mock/core.py +319 -0
- sqlspec/adapters/mock/data_dictionary.py +366 -0
- sqlspec/adapters/mock/driver.py +721 -0
- sqlspec/adapters/mysqlconnector/__init__.py +36 -0
- sqlspec/adapters/mysqlconnector/_typing.py +141 -0
- sqlspec/adapters/mysqlconnector/adk/__init__.py +15 -0
- sqlspec/adapters/mysqlconnector/adk/store.py +1060 -0
- sqlspec/adapters/mysqlconnector/config.py +394 -0
- sqlspec/adapters/mysqlconnector/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/mysqlconnector/core.py +303 -0
- sqlspec/adapters/mysqlconnector/data_dictionary.py +235 -0
- sqlspec/adapters/mysqlconnector/driver.py +483 -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 +60 -0
- sqlspec/adapters/oracledb/_numpy_handlers.py +141 -0
- sqlspec/adapters/oracledb/_typing.py +182 -0
- sqlspec/adapters/oracledb/_uuid_handlers.py +166 -0
- sqlspec/adapters/oracledb/adk/__init__.py +10 -0
- sqlspec/adapters/oracledb/adk/store.py +2369 -0
- sqlspec/adapters/oracledb/config.py +550 -0
- sqlspec/adapters/oracledb/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/oracledb/core.py +543 -0
- sqlspec/adapters/oracledb/data_dictionary.py +536 -0
- sqlspec/adapters/oracledb/driver.py +1229 -0
- sqlspec/adapters/oracledb/events/__init__.py +16 -0
- sqlspec/adapters/oracledb/events/backend.py +347 -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 +535 -0
- sqlspec/adapters/oracledb/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/oracledb/type_converter.py +211 -0
- sqlspec/adapters/psqlpy/__init__.py +17 -0
- sqlspec/adapters/psqlpy/_typing.py +79 -0
- sqlspec/adapters/psqlpy/adk/__init__.py +5 -0
- sqlspec/adapters/psqlpy/adk/store.py +766 -0
- sqlspec/adapters/psqlpy/config.py +304 -0
- sqlspec/adapters/psqlpy/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/psqlpy/core.py +480 -0
- sqlspec/adapters/psqlpy/data_dictionary.py +126 -0
- sqlspec/adapters/psqlpy/driver.py +438 -0
- sqlspec/adapters/psqlpy/events/__init__.py +6 -0
- sqlspec/adapters/psqlpy/events/backend.py +310 -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.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/psqlpy/type_converter.py +113 -0
- sqlspec/adapters/psycopg/__init__.py +32 -0
- sqlspec/adapters/psycopg/_typing.py +164 -0
- sqlspec/adapters/psycopg/adk/__init__.py +10 -0
- sqlspec/adapters/psycopg/adk/store.py +1387 -0
- sqlspec/adapters/psycopg/config.py +576 -0
- sqlspec/adapters/psycopg/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/psycopg/core.py +450 -0
- sqlspec/adapters/psycopg/data_dictionary.py +289 -0
- sqlspec/adapters/psycopg/driver.py +975 -0
- sqlspec/adapters/psycopg/events/__init__.py +20 -0
- sqlspec/adapters/psycopg/events/backend.py +458 -0
- sqlspec/adapters/psycopg/events/store.py +42 -0
- sqlspec/adapters/psycopg/litestar/__init__.py +5 -0
- sqlspec/adapters/psycopg/litestar/store.py +552 -0
- sqlspec/adapters/psycopg/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/psycopg/type_converter.py +93 -0
- sqlspec/adapters/pymysql/__init__.py +21 -0
- sqlspec/adapters/pymysql/_typing.py +71 -0
- sqlspec/adapters/pymysql/adk/__init__.py +5 -0
- sqlspec/adapters/pymysql/adk/store.py +540 -0
- sqlspec/adapters/pymysql/config.py +195 -0
- sqlspec/adapters/pymysql/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/pymysql/core.py +299 -0
- sqlspec/adapters/pymysql/data_dictionary.py +122 -0
- sqlspec/adapters/pymysql/driver.py +259 -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.py +137 -0
- sqlspec/adapters/spanner/__init__.py +40 -0
- sqlspec/adapters/spanner/_typing.py +86 -0
- sqlspec/adapters/spanner/adk/__init__.py +5 -0
- sqlspec/adapters/spanner/adk/store.py +732 -0
- sqlspec/adapters/spanner/config.py +352 -0
- sqlspec/adapters/spanner/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/spanner/core.py +188 -0
- sqlspec/adapters/spanner/data_dictionary.py +120 -0
- sqlspec/adapters/spanner/dialect/__init__.py +6 -0
- sqlspec/adapters/spanner/dialect/_spangres.py +57 -0
- sqlspec/adapters/spanner/dialect/_spanner.py +130 -0
- sqlspec/adapters/spanner/driver.py +373 -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.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/spanner/type_converter.py +331 -0
- sqlspec/adapters/sqlite/__init__.py +19 -0
- sqlspec/adapters/sqlite/_typing.py +80 -0
- sqlspec/adapters/sqlite/adk/__init__.py +5 -0
- sqlspec/adapters/sqlite/adk/store.py +958 -0
- sqlspec/adapters/sqlite/config.py +280 -0
- sqlspec/adapters/sqlite/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/sqlite/core.py +312 -0
- sqlspec/adapters/sqlite/data_dictionary.py +202 -0
- sqlspec/adapters/sqlite/driver.py +359 -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.py +198 -0
- sqlspec/adapters/sqlite/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/sqlite/type_converter.py +114 -0
- sqlspec/base.py +747 -0
- sqlspec/builder/__init__.py +179 -0
- sqlspec/builder/_base.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_base.py +1022 -0
- sqlspec/builder/_column.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_column.py +521 -0
- sqlspec/builder/_ddl.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_ddl.py +1642 -0
- sqlspec/builder/_delete.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_delete.py +95 -0
- sqlspec/builder/_dml.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_dml.py +365 -0
- sqlspec/builder/_explain.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_explain.py +579 -0
- sqlspec/builder/_expression_wrappers.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_expression_wrappers.py +46 -0
- sqlspec/builder/_factory.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_factory.py +1697 -0
- sqlspec/builder/_insert.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_insert.py +328 -0
- sqlspec/builder/_join.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_join.py +499 -0
- sqlspec/builder/_merge.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_merge.py +821 -0
- sqlspec/builder/_parsing_utils.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_parsing_utils.py +297 -0
- sqlspec/builder/_select.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_select.py +1660 -0
- sqlspec/builder/_temporal.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_temporal.py +139 -0
- sqlspec/builder/_update.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_update.py +173 -0
- sqlspec/builder/_vector_expressions.py +267 -0
- sqlspec/cli.py +911 -0
- sqlspec/config.py +1755 -0
- sqlspec/core/__init__.py +374 -0
- sqlspec/core/_correlation.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/_correlation.py +176 -0
- sqlspec/core/cache.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/cache.py +1069 -0
- sqlspec/core/compiler.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/compiler.py +954 -0
- sqlspec/core/explain.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/explain.py +275 -0
- sqlspec/core/filters.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/filters.py +952 -0
- sqlspec/core/hashing.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/hashing.py +262 -0
- sqlspec/core/metrics.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/metrics.py +83 -0
- sqlspec/core/parameters/__init__.py +71 -0
- sqlspec/core/parameters/_alignment.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/parameters/_alignment.py +270 -0
- sqlspec/core/parameters/_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/parameters/_converter.py +543 -0
- sqlspec/core/parameters/_processor.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/parameters/_processor.py +505 -0
- sqlspec/core/parameters/_registry.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/parameters/_registry.py +206 -0
- sqlspec/core/parameters/_transformers.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/parameters/_transformers.py +292 -0
- sqlspec/core/parameters/_types.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/parameters/_types.py +499 -0
- sqlspec/core/parameters/_validator.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/parameters/_validator.py +180 -0
- sqlspec/core/pipeline.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/pipeline.py +319 -0
- sqlspec/core/query_modifiers.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/query_modifiers.py +437 -0
- sqlspec/core/result/__init__.py +23 -0
- sqlspec/core/result/_base.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/result/_base.py +1121 -0
- sqlspec/core/result/_io.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/result/_io.py +28 -0
- sqlspec/core/splitter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/splitter.py +966 -0
- sqlspec/core/stack.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/stack.py +163 -0
- sqlspec/core/statement.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/statement.py +1503 -0
- sqlspec/core/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/type_converter.py +339 -0
- sqlspec/data_dictionary/__init__.py +22 -0
- sqlspec/data_dictionary/_loader.py +123 -0
- sqlspec/data_dictionary/_registry.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/_registry.py +74 -0
- sqlspec/data_dictionary/_types.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/_types.py +121 -0
- sqlspec/data_dictionary/dialects/__init__.py +21 -0
- sqlspec/data_dictionary/dialects/bigquery.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/bigquery.py +49 -0
- sqlspec/data_dictionary/dialects/cockroachdb.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/cockroachdb.py +43 -0
- sqlspec/data_dictionary/dialects/duckdb.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/duckdb.py +47 -0
- sqlspec/data_dictionary/dialects/mysql.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/mysql.py +42 -0
- sqlspec/data_dictionary/dialects/oracle.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/oracle.py +34 -0
- sqlspec/data_dictionary/dialects/postgres.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/postgres.py +46 -0
- sqlspec/data_dictionary/dialects/spanner.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/spanner.py +37 -0
- sqlspec/data_dictionary/dialects/sqlite.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/sqlite.py +42 -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/driver/__init__.py +32 -0
- sqlspec/driver/_async.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/driver/_async.py +1737 -0
- sqlspec/driver/_common.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/driver/_common.py +1478 -0
- sqlspec/driver/_sql_helpers.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/driver/_sql_helpers.py +148 -0
- sqlspec/driver/_storage_helpers.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/driver/_storage_helpers.py +144 -0
- sqlspec/driver/_sync.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/driver/_sync.py +1710 -0
- sqlspec/exceptions.py +338 -0
- sqlspec/extensions/__init__.py +0 -0
- sqlspec/extensions/adk/__init__.py +70 -0
- sqlspec/extensions/adk/_types.py +51 -0
- sqlspec/extensions/adk/converters.py +172 -0
- sqlspec/extensions/adk/memory/__init__.py +69 -0
- sqlspec/extensions/adk/memory/_types.py +30 -0
- sqlspec/extensions/adk/memory/converters.py +149 -0
- sqlspec/extensions/adk/memory/service.py +217 -0
- sqlspec/extensions/adk/memory/store.py +569 -0
- sqlspec/extensions/adk/migrations/0001_create_adk_tables.py +246 -0
- sqlspec/extensions/adk/migrations/__init__.py +0 -0
- sqlspec/extensions/adk/service.py +225 -0
- sqlspec/extensions/adk/store.py +567 -0
- sqlspec/extensions/events/__init__.py +51 -0
- sqlspec/extensions/events/_channel.py +703 -0
- sqlspec/extensions/events/_hints.py +45 -0
- sqlspec/extensions/events/_models.py +23 -0
- sqlspec/extensions/events/_payload.py +69 -0
- sqlspec/extensions/events/_protocols.py +134 -0
- sqlspec/extensions/events/_queue.py +461 -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 +19 -0
- sqlspec/extensions/fastapi/extension.py +351 -0
- sqlspec/extensions/fastapi/providers.py +607 -0
- sqlspec/extensions/flask/__init__.py +37 -0
- sqlspec/extensions/flask/_state.py +76 -0
- sqlspec/extensions/flask/_utils.py +71 -0
- sqlspec/extensions/flask/extension.py +519 -0
- sqlspec/extensions/litestar/__init__.py +28 -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 +671 -0
- sqlspec/extensions/litestar/providers.py +526 -0
- sqlspec/extensions/litestar/store.py +296 -0
- sqlspec/extensions/otel/__init__.py +58 -0
- sqlspec/extensions/prometheus/__init__.py +113 -0
- sqlspec/extensions/starlette/__init__.py +19 -0
- sqlspec/extensions/starlette/_state.py +30 -0
- sqlspec/extensions/starlette/_utils.py +96 -0
- sqlspec/extensions/starlette/extension.py +346 -0
- sqlspec/extensions/starlette/middleware.py +235 -0
- sqlspec/loader.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/loader.py +702 -0
- sqlspec/migrations/__init__.py +36 -0
- sqlspec/migrations/base.py +731 -0
- sqlspec/migrations/commands.py +1232 -0
- sqlspec/migrations/context.py +157 -0
- sqlspec/migrations/fix.py +204 -0
- sqlspec/migrations/loaders.py +443 -0
- sqlspec/migrations/runner.py +1172 -0
- sqlspec/migrations/templates.py +234 -0
- sqlspec/migrations/tracker.py +611 -0
- sqlspec/migrations/utils.py +256 -0
- sqlspec/migrations/validation.py +207 -0
- sqlspec/migrations/version.py +446 -0
- sqlspec/observability/__init__.py +55 -0
- sqlspec/observability/_common.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_common.py +77 -0
- sqlspec/observability/_config.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_config.py +348 -0
- sqlspec/observability/_diagnostics.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_diagnostics.py +74 -0
- sqlspec/observability/_dispatcher.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_dispatcher.py +152 -0
- sqlspec/observability/_formatters/__init__.py +13 -0
- sqlspec/observability/_formatters/_aws.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_formatters/_aws.py +102 -0
- sqlspec/observability/_formatters/_azure.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_formatters/_azure.py +96 -0
- sqlspec/observability/_formatters/_base.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_formatters/_base.py +57 -0
- sqlspec/observability/_formatters/_gcp.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_formatters/_gcp.py +131 -0
- sqlspec/observability/_formatting.py +58 -0
- sqlspec/observability/_observer.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_observer.py +357 -0
- sqlspec/observability/_runtime.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_runtime.py +420 -0
- sqlspec/observability/_sampling.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_sampling.py +188 -0
- sqlspec/observability/_spans.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_spans.py +161 -0
- sqlspec/protocols.py +916 -0
- sqlspec/py.typed +0 -0
- sqlspec/storage/__init__.py +48 -0
- sqlspec/storage/_utils.py +104 -0
- sqlspec/storage/backends/__init__.py +1 -0
- sqlspec/storage/backends/base.py +253 -0
- sqlspec/storage/backends/fsspec.py +529 -0
- sqlspec/storage/backends/local.py +441 -0
- sqlspec/storage/backends/obstore.py +916 -0
- sqlspec/storage/errors.py +104 -0
- sqlspec/storage/pipeline.py +582 -0
- sqlspec/storage/registry.py +301 -0
- sqlspec/typing.py +395 -0
- sqlspec/utils/__init__.py +7 -0
- sqlspec/utils/arrow_helpers.py +318 -0
- sqlspec/utils/config_tools.py +332 -0
- sqlspec/utils/correlation.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/correlation.py +134 -0
- sqlspec/utils/deprecation.py +190 -0
- sqlspec/utils/fixtures.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/fixtures.py +258 -0
- sqlspec/utils/logging.py +222 -0
- sqlspec/utils/module_loader.py +306 -0
- sqlspec/utils/portal.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/portal.py +375 -0
- sqlspec/utils/schema.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/schema.py +485 -0
- sqlspec/utils/serializers.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/serializers.py +408 -0
- sqlspec/utils/singleton.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/singleton.py +41 -0
- sqlspec/utils/sync_tools.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/sync_tools.py +311 -0
- sqlspec/utils/text.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/text.py +108 -0
- sqlspec/utils/type_converters.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/type_converters.py +128 -0
- sqlspec/utils/type_guards.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/type_guards.py +1360 -0
- sqlspec/utils/uuids.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/uuids.py +225 -0
- sqlspec-0.36.0.dist-info/METADATA +205 -0
- sqlspec-0.36.0.dist-info/RECORD +531 -0
- sqlspec-0.36.0.dist-info/WHEEL +7 -0
- sqlspec-0.36.0.dist-info/entry_points.txt +2 -0
- sqlspec-0.36.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,715 @@
|
|
|
1
|
+
"""BigQuery adapter compiled helpers."""
|
|
2
|
+
|
|
3
|
+
import datetime
|
|
4
|
+
import importlib
|
|
5
|
+
import io
|
|
6
|
+
import os
|
|
7
|
+
from decimal import Decimal
|
|
8
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
9
|
+
|
|
10
|
+
import sqlglot
|
|
11
|
+
from google.api_core.retry import Retry
|
|
12
|
+
from google.cloud.bigquery import LoadJobConfig, QueryJob, QueryJobConfig
|
|
13
|
+
from google.cloud.exceptions import GoogleCloudError
|
|
14
|
+
from sqlglot import exp
|
|
15
|
+
|
|
16
|
+
from sqlspec.core import (
|
|
17
|
+
DriverParameterProfile,
|
|
18
|
+
ParameterProfile,
|
|
19
|
+
ParameterStyle,
|
|
20
|
+
StatementConfig,
|
|
21
|
+
build_statement_config_from_profile,
|
|
22
|
+
)
|
|
23
|
+
from sqlspec.exceptions import (
|
|
24
|
+
DatabaseConnectionError,
|
|
25
|
+
DataError,
|
|
26
|
+
NotFoundError,
|
|
27
|
+
OperationalError,
|
|
28
|
+
SQLParsingError,
|
|
29
|
+
SQLSpecError,
|
|
30
|
+
StorageCapabilityError,
|
|
31
|
+
UniqueViolationError,
|
|
32
|
+
)
|
|
33
|
+
from sqlspec.utils.logging import get_logger
|
|
34
|
+
from sqlspec.utils.serializers import to_json
|
|
35
|
+
from sqlspec.utils.type_guards import has_errors, has_value_attribute
|
|
36
|
+
|
|
37
|
+
if TYPE_CHECKING:
|
|
38
|
+
from collections.abc import Callable, Mapping
|
|
39
|
+
|
|
40
|
+
from sqlspec.adapters.bigquery._typing import BigQueryConnection, BigQueryParam
|
|
41
|
+
from sqlspec.storage import StorageFormat, StorageTelemetry
|
|
42
|
+
|
|
43
|
+
__all__ = (
|
|
44
|
+
"apply_driver_features",
|
|
45
|
+
"build_dml_rowcount",
|
|
46
|
+
"build_inlined_script",
|
|
47
|
+
"build_load_job_config",
|
|
48
|
+
"build_load_job_telemetry",
|
|
49
|
+
"build_profile",
|
|
50
|
+
"build_retry",
|
|
51
|
+
"build_statement_config",
|
|
52
|
+
"collect_rows",
|
|
53
|
+
"copy_job_config",
|
|
54
|
+
"create_mapped_exception",
|
|
55
|
+
"create_parameters",
|
|
56
|
+
"default_statement_config",
|
|
57
|
+
"detect_emulator",
|
|
58
|
+
"driver_profile",
|
|
59
|
+
"extract_insert_table",
|
|
60
|
+
"is_simple_insert",
|
|
61
|
+
"normalize_script_rowcount",
|
|
62
|
+
"run_query_job",
|
|
63
|
+
"storage_api_available",
|
|
64
|
+
"try_bulk_insert",
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
HTTP_CONFLICT = 409
|
|
68
|
+
HTTP_NOT_FOUND = 404
|
|
69
|
+
HTTP_BAD_REQUEST = 400
|
|
70
|
+
HTTP_FORBIDDEN = 403
|
|
71
|
+
HTTP_SERVER_ERROR = 500
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _identity(value: Any) -> Any:
|
|
75
|
+
return value
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _tuple_to_list(value: Any) -> Any:
|
|
79
|
+
if isinstance(value, tuple):
|
|
80
|
+
return list(value)
|
|
81
|
+
return value
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def _return_none(_: Any) -> None:
|
|
85
|
+
return None
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def storage_api_available() -> bool:
|
|
89
|
+
"""Return True when the BigQuery Storage API client can be imported."""
|
|
90
|
+
try:
|
|
91
|
+
importlib.import_module("google.cloud.bigquery_storage_v1")
|
|
92
|
+
except Exception:
|
|
93
|
+
return False
|
|
94
|
+
return True
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
_BIGQUERY_MODULE: Any | None = None
|
|
98
|
+
_BQ_TYPE_MAP: "dict[type, tuple[str, str | None]]" = {
|
|
99
|
+
bool: ("BOOL", None),
|
|
100
|
+
int: ("INT64", None),
|
|
101
|
+
float: ("FLOAT64", None),
|
|
102
|
+
Decimal: ("BIGNUMERIC", None),
|
|
103
|
+
str: ("STRING", None),
|
|
104
|
+
bytes: ("BYTES", None),
|
|
105
|
+
datetime.date: ("DATE", None),
|
|
106
|
+
datetime.time: ("TIME", None),
|
|
107
|
+
dict: ("JSON", None),
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def try_bulk_insert(
|
|
112
|
+
connection: "BigQueryConnection",
|
|
113
|
+
sql: str,
|
|
114
|
+
parameters: "list[dict[str, Any]]",
|
|
115
|
+
expression: "exp.Expression | None" = None,
|
|
116
|
+
*,
|
|
117
|
+
allow_parse: bool = True,
|
|
118
|
+
) -> "int | None":
|
|
119
|
+
"""Attempt bulk insert via Parquet load.
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
connection: BigQuery connection instance.
|
|
123
|
+
sql: INSERT SQL statement.
|
|
124
|
+
parameters: Parameter dictionaries for the insert.
|
|
125
|
+
expression: Optional parsed expression to reuse.
|
|
126
|
+
allow_parse: Whether to parse SQL when expression is unavailable.
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
Inserted row count if bulk insert succeeds, otherwise None.
|
|
130
|
+
"""
|
|
131
|
+
table_name = extract_insert_table(sql, expression, allow_parse=allow_parse)
|
|
132
|
+
if not table_name:
|
|
133
|
+
return None
|
|
134
|
+
|
|
135
|
+
try:
|
|
136
|
+
import pyarrow as pa
|
|
137
|
+
import pyarrow.parquet as pq
|
|
138
|
+
|
|
139
|
+
arrow_table = pa.Table.from_pylist(parameters)
|
|
140
|
+
|
|
141
|
+
buffer = io.BytesIO()
|
|
142
|
+
pq.write_table(arrow_table, buffer)
|
|
143
|
+
buffer.seek(0)
|
|
144
|
+
|
|
145
|
+
job_config = build_load_job_config("parquet", overwrite=False)
|
|
146
|
+
job = connection.load_table_from_file(buffer, table_name, job_config=job_config)
|
|
147
|
+
job.result()
|
|
148
|
+
return len(parameters)
|
|
149
|
+
except ImportError:
|
|
150
|
+
logger.debug("pyarrow not available, falling back to literal inlining")
|
|
151
|
+
return None
|
|
152
|
+
except Exception as exc:
|
|
153
|
+
logger.debug("Bulk insert failed, falling back to literal inlining: %s", exc)
|
|
154
|
+
return None
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def build_inlined_script(
|
|
158
|
+
sql: str,
|
|
159
|
+
parameters: "list[dict[str, Any]]",
|
|
160
|
+
expression: "exp.Expression | None" = None,
|
|
161
|
+
*,
|
|
162
|
+
allow_parse: bool = True,
|
|
163
|
+
literal_inliner: "Callable[[Any, Any, ParameterProfile], tuple[Any, Any]]",
|
|
164
|
+
) -> str:
|
|
165
|
+
"""Build a BigQuery script with literal inlining.
|
|
166
|
+
|
|
167
|
+
Args:
|
|
168
|
+
sql: SQL statement to inline.
|
|
169
|
+
parameters: Parameter dictionaries to inline.
|
|
170
|
+
expression: Optional parsed expression to reuse.
|
|
171
|
+
allow_parse: Whether to parse SQL when expression is unavailable.
|
|
172
|
+
literal_inliner: Callable used to inline literal values.
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
Script SQL with inlined parameters.
|
|
176
|
+
"""
|
|
177
|
+
parsed_expression = expression
|
|
178
|
+
if parsed_expression is None and allow_parse:
|
|
179
|
+
try:
|
|
180
|
+
parsed_expression = sqlglot.parse_one(sql, dialect="bigquery")
|
|
181
|
+
except sqlglot.ParseError:
|
|
182
|
+
parsed_expression = None
|
|
183
|
+
|
|
184
|
+
if parsed_expression is None:
|
|
185
|
+
return ";\n".join([sql] * len(parameters))
|
|
186
|
+
|
|
187
|
+
script_statements: list[str] = []
|
|
188
|
+
for param_set in parameters:
|
|
189
|
+
expression_copy = parsed_expression.copy()
|
|
190
|
+
script_statements.append(_inline_bigquery_literals(expression_copy, param_set, literal_inliner))
|
|
191
|
+
return ";\n".join(script_statements)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def _create_array_parameter(name: str, value: Any, array_type: str) -> "BigQueryParam":
|
|
195
|
+
"""Create BigQuery ARRAY parameter.
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
name: Parameter name.
|
|
199
|
+
value: Array value (converted to list, empty list if None).
|
|
200
|
+
array_type: BigQuery array element type.
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
ArrayQueryParameter instance.
|
|
204
|
+
"""
|
|
205
|
+
bigquery = _get_bigquery_module()
|
|
206
|
+
return cast("BigQueryParam", bigquery.ArrayQueryParameter(name, array_type, [] if value is None else list(value)))
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def _create_json_parameter(name: str, value: Any, json_serializer: "Callable[[Any], str]") -> "BigQueryParam":
|
|
210
|
+
"""Create BigQuery JSON parameter as STRING type.
|
|
211
|
+
|
|
212
|
+
Args:
|
|
213
|
+
name: Parameter name.
|
|
214
|
+
value: JSON-serializable value.
|
|
215
|
+
json_serializer: Function to serialize to JSON string.
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
ScalarQueryParameter with STRING type.
|
|
219
|
+
"""
|
|
220
|
+
bigquery = _get_bigquery_module()
|
|
221
|
+
return cast("BigQueryParam", bigquery.ScalarQueryParameter(name, "STRING", json_serializer(value)))
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def _create_scalar_parameter(name: str, value: Any, param_type: str) -> "BigQueryParam":
|
|
225
|
+
"""Create BigQuery scalar parameter.
|
|
226
|
+
|
|
227
|
+
Args:
|
|
228
|
+
name: Parameter name.
|
|
229
|
+
value: Scalar value.
|
|
230
|
+
param_type: BigQuery parameter type (INT64, FLOAT64, etc.).
|
|
231
|
+
|
|
232
|
+
Returns:
|
|
233
|
+
ScalarQueryParameter instance.
|
|
234
|
+
"""
|
|
235
|
+
bigquery = _get_bigquery_module()
|
|
236
|
+
return cast("BigQueryParam", bigquery.ScalarQueryParameter(name, param_type, value))
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def _get_bigquery_module() -> Any:
|
|
240
|
+
global _BIGQUERY_MODULE
|
|
241
|
+
if _BIGQUERY_MODULE is None:
|
|
242
|
+
from google.cloud import bigquery
|
|
243
|
+
|
|
244
|
+
_BIGQUERY_MODULE = bigquery
|
|
245
|
+
return _BIGQUERY_MODULE
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
logger = get_logger("sqlspec.adapters.bigquery.core")
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def _get_bq_param_type(value: Any) -> "tuple[str | None, str | None]":
|
|
252
|
+
"""Determine BigQuery parameter type from Python value.
|
|
253
|
+
|
|
254
|
+
Args:
|
|
255
|
+
value: Python value to determine BigQuery type for
|
|
256
|
+
|
|
257
|
+
Returns:
|
|
258
|
+
Tuple of (parameter_type, array_element_type)
|
|
259
|
+
"""
|
|
260
|
+
if value is None:
|
|
261
|
+
return ("STRING", None)
|
|
262
|
+
|
|
263
|
+
value_type = type(value)
|
|
264
|
+
|
|
265
|
+
if value_type is datetime.datetime:
|
|
266
|
+
return ("TIMESTAMP" if value.tzinfo else "DATETIME", None)
|
|
267
|
+
|
|
268
|
+
if value_type in _BQ_TYPE_MAP:
|
|
269
|
+
return _BQ_TYPE_MAP[value_type]
|
|
270
|
+
|
|
271
|
+
if isinstance(value, (list, tuple)):
|
|
272
|
+
if not value:
|
|
273
|
+
msg = "Cannot determine BigQuery ARRAY type for empty sequence."
|
|
274
|
+
raise SQLSpecError(msg)
|
|
275
|
+
element_type, _ = _get_bq_param_type(value[0])
|
|
276
|
+
if element_type is None:
|
|
277
|
+
msg = f"Unsupported element type in ARRAY: {type(value[0])}"
|
|
278
|
+
raise SQLSpecError(msg)
|
|
279
|
+
return "ARRAY", element_type
|
|
280
|
+
|
|
281
|
+
return None, None
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def create_parameters(parameters: Any, json_serializer: "Callable[[Any], str]") -> "list[BigQueryParam]":
|
|
285
|
+
"""Create BigQuery QueryParameter objects from parameters.
|
|
286
|
+
|
|
287
|
+
Args:
|
|
288
|
+
parameters: Dict of named parameters or list of positional parameters
|
|
289
|
+
json_serializer: Function to serialize dict/list to JSON string
|
|
290
|
+
|
|
291
|
+
Returns:
|
|
292
|
+
List of BigQuery QueryParameter objects
|
|
293
|
+
"""
|
|
294
|
+
if not parameters:
|
|
295
|
+
return []
|
|
296
|
+
|
|
297
|
+
bq_parameters: list[BigQueryParam] = []
|
|
298
|
+
|
|
299
|
+
if isinstance(parameters, dict):
|
|
300
|
+
for name, value in parameters.items():
|
|
301
|
+
param_name_for_bq = name.lstrip("@")
|
|
302
|
+
actual_value = value.value if has_value_attribute(value) else value
|
|
303
|
+
param_type, array_element_type = _get_bq_param_type(actual_value)
|
|
304
|
+
|
|
305
|
+
if param_type == "ARRAY" and array_element_type:
|
|
306
|
+
bq_parameters.append(_create_array_parameter(param_name_for_bq, actual_value, array_element_type))
|
|
307
|
+
elif param_type == "JSON":
|
|
308
|
+
bq_parameters.append(_create_json_parameter(param_name_for_bq, actual_value, json_serializer))
|
|
309
|
+
elif param_type:
|
|
310
|
+
bq_parameters.append(_create_scalar_parameter(param_name_for_bq, actual_value, param_type))
|
|
311
|
+
else:
|
|
312
|
+
msg = f"Unsupported BigQuery parameter type for value of param '{name}': {type(actual_value)}"
|
|
313
|
+
raise SQLSpecError(msg)
|
|
314
|
+
|
|
315
|
+
elif isinstance(parameters, (list, tuple)):
|
|
316
|
+
msg = "BigQuery driver requires named parameters (e.g., @name); positional parameters are not supported"
|
|
317
|
+
raise SQLSpecError(msg)
|
|
318
|
+
|
|
319
|
+
return bq_parameters
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
def _inline_bigquery_literals(
|
|
323
|
+
expression: "exp.Expression", parameters: Any, inliner: "Callable[[Any, Any, ParameterProfile], tuple[Any, Any]]"
|
|
324
|
+
) -> str:
|
|
325
|
+
"""Inline literal values into a parsed SQLGlot expression."""
|
|
326
|
+
if not parameters:
|
|
327
|
+
return str(expression.sql(dialect="bigquery"))
|
|
328
|
+
|
|
329
|
+
transformed_expression, _ = inliner(expression, parameters, ParameterProfile.empty())
|
|
330
|
+
return str(transformed_expression.sql(dialect="bigquery"))
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
def detect_emulator(connection: "BigQueryConnection") -> bool:
|
|
334
|
+
"""Detect whether the BigQuery client targets an emulator endpoint."""
|
|
335
|
+
emulator_host = os.getenv("BIGQUERY_EMULATOR_HOST") or os.getenv("BIGQUERY_EMULATOR_HOST_HTTP")
|
|
336
|
+
if emulator_host:
|
|
337
|
+
return True
|
|
338
|
+
|
|
339
|
+
try:
|
|
340
|
+
inner_connection = cast("Any", connection)._connection
|
|
341
|
+
except AttributeError:
|
|
342
|
+
inner_connection = None
|
|
343
|
+
if inner_connection is None:
|
|
344
|
+
return False
|
|
345
|
+
try:
|
|
346
|
+
api_base_url = inner_connection.API_BASE_URL
|
|
347
|
+
except AttributeError:
|
|
348
|
+
api_base_url = ""
|
|
349
|
+
if not api_base_url:
|
|
350
|
+
return False
|
|
351
|
+
return "googleapis.com" not in api_base_url
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
def _should_retry_bigquery_job(exception: Exception) -> bool:
|
|
355
|
+
"""Return True when a BigQuery job exception is safe to retry."""
|
|
356
|
+
if not isinstance(exception, GoogleCloudError):
|
|
357
|
+
return False
|
|
358
|
+
|
|
359
|
+
errors = exception.errors if has_errors(exception) and exception.errors is not None else []
|
|
360
|
+
retryable_reasons = {
|
|
361
|
+
"backendError",
|
|
362
|
+
"internalError",
|
|
363
|
+
"jobInternalError",
|
|
364
|
+
"rateLimitExceeded",
|
|
365
|
+
"jobRateLimitExceeded",
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
for err in errors:
|
|
369
|
+
if not isinstance(err, dict):
|
|
370
|
+
continue
|
|
371
|
+
reason = err.get("reason")
|
|
372
|
+
message = (err.get("message") or "").lower()
|
|
373
|
+
if reason in retryable_reasons:
|
|
374
|
+
return not ("nonexistent_column" in message or ("column" in message and "not present" in message))
|
|
375
|
+
|
|
376
|
+
return False
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
def build_retry(deadline: float, using_emulator: bool) -> "Retry | None":
|
|
380
|
+
"""Build retry policy for job restarts based on error reason codes."""
|
|
381
|
+
if using_emulator:
|
|
382
|
+
return None
|
|
383
|
+
return Retry(predicate=_should_retry_bigquery_job, deadline=deadline)
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
def _should_copy_job_attribute(attr: str, source_config: QueryJobConfig) -> bool:
|
|
387
|
+
if attr.startswith("_"):
|
|
388
|
+
return False
|
|
389
|
+
|
|
390
|
+
try:
|
|
391
|
+
value = source_config.__getattribute__(attr)
|
|
392
|
+
return value is not None and not callable(value)
|
|
393
|
+
except (AttributeError, TypeError):
|
|
394
|
+
return False
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
def copy_job_config(source_config: QueryJobConfig, target_config: QueryJobConfig) -> None:
|
|
398
|
+
"""Copy non-private attributes from source config to target config."""
|
|
399
|
+
for attr in dir(source_config):
|
|
400
|
+
if not _should_copy_job_attribute(attr, source_config):
|
|
401
|
+
continue
|
|
402
|
+
|
|
403
|
+
try:
|
|
404
|
+
value = source_config.__getattribute__(attr)
|
|
405
|
+
setattr(target_config, attr, value)
|
|
406
|
+
except (AttributeError, TypeError):
|
|
407
|
+
continue
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
def run_query_job(
|
|
411
|
+
connection: "BigQueryConnection",
|
|
412
|
+
sql: str,
|
|
413
|
+
parameters: Any,
|
|
414
|
+
*,
|
|
415
|
+
default_job_config: QueryJobConfig | None,
|
|
416
|
+
job_config: QueryJobConfig | None,
|
|
417
|
+
json_serializer: "Callable[[Any], str]",
|
|
418
|
+
) -> QueryJob:
|
|
419
|
+
"""Execute a BigQuery query job with merged configuration.
|
|
420
|
+
|
|
421
|
+
Args:
|
|
422
|
+
connection: BigQuery connection instance.
|
|
423
|
+
sql: SQL string to execute.
|
|
424
|
+
parameters: Prepared parameters payload.
|
|
425
|
+
default_job_config: Default job configuration to merge.
|
|
426
|
+
job_config: Optional job configuration override.
|
|
427
|
+
json_serializer: JSON serializer for parameter values.
|
|
428
|
+
|
|
429
|
+
Returns:
|
|
430
|
+
QueryJob object representing the executed job.
|
|
431
|
+
"""
|
|
432
|
+
final_job_config = QueryJobConfig()
|
|
433
|
+
if default_job_config:
|
|
434
|
+
copy_job_config(default_job_config, final_job_config)
|
|
435
|
+
if job_config:
|
|
436
|
+
copy_job_config(job_config, final_job_config)
|
|
437
|
+
final_job_config.query_parameters = create_parameters(parameters, json_serializer)
|
|
438
|
+
return connection.query(sql, job_config=final_job_config)
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
def build_load_job_config(file_format: "StorageFormat", overwrite: bool) -> "LoadJobConfig":
|
|
442
|
+
job_config = LoadJobConfig()
|
|
443
|
+
job_config.source_format = _map_bigquery_source_format(file_format)
|
|
444
|
+
job_config.write_disposition = "WRITE_TRUNCATE" if overwrite else "WRITE_APPEND"
|
|
445
|
+
return job_config
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
def build_load_job_telemetry(job: QueryJob, table: str, *, format_label: str) -> "StorageTelemetry":
|
|
449
|
+
try:
|
|
450
|
+
properties = cast("Any", job)._properties
|
|
451
|
+
except AttributeError:
|
|
452
|
+
properties = {}
|
|
453
|
+
load_stats = properties.get("statistics", {}).get("load", {})
|
|
454
|
+
rows_processed = int(load_stats.get("outputRows") or 0)
|
|
455
|
+
bytes_processed = int(load_stats.get("outputBytes") or load_stats.get("inputFileBytes", 0) or 0)
|
|
456
|
+
duration = 0.0
|
|
457
|
+
if job.ended and job.started:
|
|
458
|
+
duration = (job.ended - job.started).total_seconds()
|
|
459
|
+
telemetry: StorageTelemetry = {
|
|
460
|
+
"destination": table,
|
|
461
|
+
"rows_processed": rows_processed,
|
|
462
|
+
"bytes_processed": bytes_processed,
|
|
463
|
+
"duration_s": duration,
|
|
464
|
+
"format": format_label,
|
|
465
|
+
}
|
|
466
|
+
return telemetry
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
def is_simple_insert(sql: str, expression: "exp.Expression | None" = None, *, allow_parse: bool = True) -> bool:
|
|
470
|
+
"""Check if SQL is a simple INSERT VALUES statement.
|
|
471
|
+
|
|
472
|
+
Args:
|
|
473
|
+
sql: SQL string to inspect.
|
|
474
|
+
expression: Optional pre-parsed expression to reuse.
|
|
475
|
+
allow_parse: When False, skip parsing and return False if expression is missing.
|
|
476
|
+
"""
|
|
477
|
+
if expression is None and not allow_parse:
|
|
478
|
+
return False
|
|
479
|
+
try:
|
|
480
|
+
parsed = expression or sqlglot.parse_one(sql, dialect="bigquery")
|
|
481
|
+
if not isinstance(parsed, exp.Insert):
|
|
482
|
+
return False
|
|
483
|
+
return parsed.expression is not None or parsed.find(exp.Values) is not None
|
|
484
|
+
except Exception:
|
|
485
|
+
return False
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
def extract_insert_table(
|
|
489
|
+
sql: str, expression: "exp.Expression | None" = None, *, allow_parse: bool = True
|
|
490
|
+
) -> str | None:
|
|
491
|
+
"""Extract table name from INSERT statement using sqlglot.
|
|
492
|
+
|
|
493
|
+
Args:
|
|
494
|
+
sql: SQL string to inspect.
|
|
495
|
+
expression: Optional pre-parsed expression to reuse.
|
|
496
|
+
allow_parse: When False, skip parsing and return None if expression is missing.
|
|
497
|
+
"""
|
|
498
|
+
if expression is None and not allow_parse:
|
|
499
|
+
return None
|
|
500
|
+
try:
|
|
501
|
+
parsed = expression or sqlglot.parse_one(sql, dialect="bigquery")
|
|
502
|
+
if isinstance(parsed, exp.Insert):
|
|
503
|
+
table = parsed.find(exp.Table)
|
|
504
|
+
if table:
|
|
505
|
+
parts = []
|
|
506
|
+
if table.catalog:
|
|
507
|
+
parts.append(table.catalog)
|
|
508
|
+
if table.db:
|
|
509
|
+
parts.append(table.db)
|
|
510
|
+
parts.append(table.name)
|
|
511
|
+
return ".".join(parts)
|
|
512
|
+
except Exception:
|
|
513
|
+
logger.debug("Failed to extract table name from INSERT statement")
|
|
514
|
+
return None
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
def _map_bigquery_source_format(file_format: "StorageFormat") -> str:
|
|
518
|
+
if file_format == "parquet":
|
|
519
|
+
return "PARQUET"
|
|
520
|
+
if file_format in {"json", "jsonl"}:
|
|
521
|
+
return "NEWLINE_DELIMITED_JSON"
|
|
522
|
+
msg = f"BigQuery does not support loading '{file_format}' artifacts via the storage bridge"
|
|
523
|
+
raise StorageCapabilityError(msg, capability="parquet_import_enabled")
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
def _rows_to_results(rows_iterator: Any) -> "list[dict[str, Any]]":
|
|
527
|
+
"""Convert BigQuery rows to dictionary format.
|
|
528
|
+
|
|
529
|
+
Args:
|
|
530
|
+
rows_iterator: BigQuery rows iterator.
|
|
531
|
+
|
|
532
|
+
Returns:
|
|
533
|
+
List of dictionaries representing the rows.
|
|
534
|
+
"""
|
|
535
|
+
return [dict(row) for row in rows_iterator]
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
def collect_rows(job_result: Any, schema: Any | None) -> "tuple[list[dict[str, Any]], list[str]]":
|
|
539
|
+
"""Collect BigQuery rows and schema into structured lists.
|
|
540
|
+
|
|
541
|
+
Args:
|
|
542
|
+
job_result: BigQuery job result iterator.
|
|
543
|
+
schema: BigQuery schema object (or None).
|
|
544
|
+
|
|
545
|
+
Returns:
|
|
546
|
+
Tuple of (rows_list, column_names).
|
|
547
|
+
"""
|
|
548
|
+
rows_list = _rows_to_results(iter(job_result))
|
|
549
|
+
column_names = [field.name for field in schema] if schema else []
|
|
550
|
+
return rows_list, column_names
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
def build_dml_rowcount(job: Any, fallback: int) -> int:
|
|
554
|
+
"""Resolve affected rowcount for BigQuery DML jobs.
|
|
555
|
+
|
|
556
|
+
Args:
|
|
557
|
+
job: BigQuery job object with optional num_dml_affected_rows.
|
|
558
|
+
fallback: Fallback rowcount when job does not expose metadata.
|
|
559
|
+
|
|
560
|
+
Returns:
|
|
561
|
+
Resolved rowcount.
|
|
562
|
+
"""
|
|
563
|
+
try:
|
|
564
|
+
rowcount = job.num_dml_affected_rows
|
|
565
|
+
except AttributeError:
|
|
566
|
+
return fallback
|
|
567
|
+
if rowcount is None:
|
|
568
|
+
return fallback
|
|
569
|
+
if isinstance(rowcount, int):
|
|
570
|
+
return rowcount
|
|
571
|
+
return fallback
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
def normalize_script_rowcount(previous: int, job: Any) -> int:
|
|
575
|
+
"""Normalize BigQuery script rowcount from the latest job metadata.
|
|
576
|
+
|
|
577
|
+
Args:
|
|
578
|
+
previous: Previously recorded rowcount value.
|
|
579
|
+
job: BigQuery job with optional num_dml_affected_rows metadata.
|
|
580
|
+
|
|
581
|
+
Returns:
|
|
582
|
+
Updated rowcount value.
|
|
583
|
+
"""
|
|
584
|
+
return build_dml_rowcount(job, previous)
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
def build_profile() -> "DriverParameterProfile":
|
|
588
|
+
"""Create the BigQuery driver parameter profile."""
|
|
589
|
+
|
|
590
|
+
return DriverParameterProfile(
|
|
591
|
+
name="BigQuery",
|
|
592
|
+
default_style=ParameterStyle.NAMED_AT,
|
|
593
|
+
supported_styles={ParameterStyle.NAMED_AT, ParameterStyle.QMARK},
|
|
594
|
+
default_execution_style=ParameterStyle.NAMED_AT,
|
|
595
|
+
supported_execution_styles={ParameterStyle.NAMED_AT},
|
|
596
|
+
has_native_list_expansion=True,
|
|
597
|
+
preserve_parameter_format=True,
|
|
598
|
+
needs_static_script_compilation=False,
|
|
599
|
+
allow_mixed_parameter_styles=False,
|
|
600
|
+
preserve_original_params_for_many=False,
|
|
601
|
+
json_serializer_strategy="helper",
|
|
602
|
+
custom_type_coercions={
|
|
603
|
+
int: _identity,
|
|
604
|
+
float: _identity,
|
|
605
|
+
bytes: _identity,
|
|
606
|
+
datetime.datetime: _identity,
|
|
607
|
+
datetime.date: _identity,
|
|
608
|
+
datetime.time: _identity,
|
|
609
|
+
Decimal: _identity,
|
|
610
|
+
dict: _identity,
|
|
611
|
+
list: _identity,
|
|
612
|
+
type(None): _return_none,
|
|
613
|
+
},
|
|
614
|
+
extras={"json_tuple_strategy": "tuple", "type_coercion_overrides": {list: _identity, tuple: _tuple_to_list}},
|
|
615
|
+
default_dialect="bigquery",
|
|
616
|
+
)
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
driver_profile = build_profile()
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
def build_statement_config(*, json_serializer: "Callable[[Any], str] | None" = None) -> StatementConfig:
|
|
623
|
+
"""Construct the BigQuery statement configuration with optional JSON serializer."""
|
|
624
|
+
serializer = json_serializer or to_json
|
|
625
|
+
profile = driver_profile
|
|
626
|
+
return build_statement_config_from_profile(
|
|
627
|
+
profile, statement_overrides={"dialect": "bigquery"}, json_serializer=serializer
|
|
628
|
+
)
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
default_statement_config = build_statement_config()
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
def _normalize_bigquery_driver_features(
|
|
635
|
+
driver_features: "Mapping[str, Any] | None",
|
|
636
|
+
) -> "tuple[dict[str, Any], Callable[[Any], str] | None, Callable[[Any], None] | None, Any | None]":
|
|
637
|
+
"""Normalize driver feature defaults and extract core options."""
|
|
638
|
+
features: dict[str, Any] = dict(driver_features) if driver_features else {}
|
|
639
|
+
user_connection_hook = features.pop("on_connection_create", None)
|
|
640
|
+
features.setdefault("enable_uuid_conversion", True)
|
|
641
|
+
serializer = features.setdefault("json_serializer", to_json)
|
|
642
|
+
connection_instance = features.get("connection_instance")
|
|
643
|
+
if connection_instance is not None:
|
|
644
|
+
features.pop("connection_instance", None)
|
|
645
|
+
|
|
646
|
+
return (
|
|
647
|
+
features,
|
|
648
|
+
cast("Callable[[Any], str] | None", serializer),
|
|
649
|
+
cast("Callable[[Any], None] | None", user_connection_hook),
|
|
650
|
+
connection_instance,
|
|
651
|
+
)
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
def apply_driver_features(
|
|
655
|
+
driver_features: "Mapping[str, Any] | None",
|
|
656
|
+
) -> "tuple[dict[str, Any], Callable[[Any], str] | None, Callable[[Any], None] | None, Any | None]":
|
|
657
|
+
"""Apply BigQuery driver feature defaults and extract core options."""
|
|
658
|
+
return _normalize_bigquery_driver_features(driver_features)
|
|
659
|
+
|
|
660
|
+
|
|
661
|
+
def _create_bigquery_error(
|
|
662
|
+
error: Any, code: "int | None", error_class: type[SQLSpecError], description: str
|
|
663
|
+
) -> SQLSpecError:
|
|
664
|
+
"""Create a SQLSpec exception from a BigQuery error.
|
|
665
|
+
|
|
666
|
+
Args:
|
|
667
|
+
error: The original BigQuery exception
|
|
668
|
+
code: HTTP status code
|
|
669
|
+
error_class: The SQLSpec exception class to instantiate
|
|
670
|
+
description: Human-readable description of the error type
|
|
671
|
+
|
|
672
|
+
Returns:
|
|
673
|
+
A new SQLSpec exception instance with the original as its cause
|
|
674
|
+
"""
|
|
675
|
+
code_str = f"[HTTP {code}]" if code else ""
|
|
676
|
+
msg = f"BigQuery {description} {code_str}: {error}" if code_str else f"BigQuery {description}: {error}"
|
|
677
|
+
exc = error_class(msg)
|
|
678
|
+
exc.__cause__ = error
|
|
679
|
+
return exc
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
def create_mapped_exception(error: Any) -> SQLSpecError:
|
|
683
|
+
"""Map BigQuery exceptions to SQLSpec exceptions.
|
|
684
|
+
|
|
685
|
+
This is a factory function that returns an exception instance rather than
|
|
686
|
+
raising. This pattern is more robust for use in __exit__ handlers and
|
|
687
|
+
avoids issues with exception control flow in different Python versions.
|
|
688
|
+
|
|
689
|
+
Args:
|
|
690
|
+
error: The BigQuery exception to map
|
|
691
|
+
|
|
692
|
+
Returns:
|
|
693
|
+
A SQLSpec exception that wraps the original error
|
|
694
|
+
"""
|
|
695
|
+
try:
|
|
696
|
+
status_code = error.code
|
|
697
|
+
except AttributeError:
|
|
698
|
+
status_code = None
|
|
699
|
+
error_msg = str(error).lower()
|
|
700
|
+
|
|
701
|
+
if status_code == HTTP_CONFLICT or "already exists" in error_msg:
|
|
702
|
+
return _create_bigquery_error(error, status_code, UniqueViolationError, "resource already exists")
|
|
703
|
+
if status_code == HTTP_NOT_FOUND or "not found" in error_msg:
|
|
704
|
+
return _create_bigquery_error(error, status_code, NotFoundError, "resource not found")
|
|
705
|
+
if status_code == HTTP_BAD_REQUEST:
|
|
706
|
+
if "syntax" in error_msg or "invalid query" in error_msg:
|
|
707
|
+
return _create_bigquery_error(error, status_code, SQLParsingError, "query syntax error")
|
|
708
|
+
if "type" in error_msg or "format" in error_msg:
|
|
709
|
+
return _create_bigquery_error(error, status_code, DataError, "data error")
|
|
710
|
+
return _create_bigquery_error(error, status_code, SQLSpecError, "error")
|
|
711
|
+
if status_code == HTTP_FORBIDDEN:
|
|
712
|
+
return _create_bigquery_error(error, status_code, DatabaseConnectionError, "permission denied")
|
|
713
|
+
if status_code and status_code >= HTTP_SERVER_ERROR:
|
|
714
|
+
return _create_bigquery_error(error, status_code, OperationalError, "operational error")
|
|
715
|
+
return _create_bigquery_error(error, status_code, SQLSpecError, "error")
|