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,535 @@
|
|
|
1
|
+
"""Oracle-specific migration implementations.
|
|
2
|
+
|
|
3
|
+
This module provides Oracle Database-specific overrides for migration functionality
|
|
4
|
+
to handle Oracle's unique SQL syntax requirements.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import getpass
|
|
8
|
+
from typing import TYPE_CHECKING, Any
|
|
9
|
+
|
|
10
|
+
from rich.console import Console
|
|
11
|
+
|
|
12
|
+
from sqlspec.builder import CreateTable, Select, sql
|
|
13
|
+
from sqlspec.migrations.base import BaseMigrationTracker
|
|
14
|
+
from sqlspec.migrations.version import parse_version
|
|
15
|
+
from sqlspec.utils.logging import get_logger
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from sqlspec.driver import AsyncDriverAdapterBase, SyncDriverAdapterBase
|
|
19
|
+
|
|
20
|
+
__all__ = ("OracleAsyncMigrationTracker", "OracleSyncMigrationTracker")
|
|
21
|
+
|
|
22
|
+
logger = get_logger("sqlspec.migrations.oracle")
|
|
23
|
+
console = Console()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class OracleMigrationTrackerMixin:
|
|
27
|
+
"""Mixin providing Oracle-specific migration table creation and querying.
|
|
28
|
+
|
|
29
|
+
Oracle has unique identifier handling rules:
|
|
30
|
+
- Unquoted identifiers are case-insensitive and stored as UPPERCASE
|
|
31
|
+
- Quoted identifiers are case-sensitive and stored exactly as written
|
|
32
|
+
|
|
33
|
+
This mixin overrides SQL builder methods to add quoted identifiers for
|
|
34
|
+
all column references, ensuring they match the lowercase column names
|
|
35
|
+
created by the migration table.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
__slots__ = ()
|
|
39
|
+
|
|
40
|
+
version_table: str
|
|
41
|
+
|
|
42
|
+
def _get_create_table_sql(self) -> CreateTable:
|
|
43
|
+
"""Get Oracle-specific SQL builder for creating the tracking table.
|
|
44
|
+
|
|
45
|
+
Oracle doesn't support:
|
|
46
|
+
- CREATE TABLE IF NOT EXISTS (need try/catch logic)
|
|
47
|
+
- TEXT type (use VARCHAR2)
|
|
48
|
+
- DEFAULT before NOT NULL is required
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
SQL builder object for Oracle table creation.
|
|
52
|
+
"""
|
|
53
|
+
return (
|
|
54
|
+
sql
|
|
55
|
+
.create_table(self.version_table)
|
|
56
|
+
.column("version_num", "VARCHAR2(32)", primary_key=True)
|
|
57
|
+
.column("version_type", "VARCHAR2(16)")
|
|
58
|
+
.column("execution_sequence", "INTEGER")
|
|
59
|
+
.column("description", "VARCHAR2(2000)")
|
|
60
|
+
.column("applied_at", "TIMESTAMP", default="CURRENT_TIMESTAMP")
|
|
61
|
+
.column("execution_time_ms", "INTEGER")
|
|
62
|
+
.column("checksum", "VARCHAR2(64)")
|
|
63
|
+
.column("applied_by", "VARCHAR2(255)")
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
def _get_current_version_sql(self) -> Select:
|
|
67
|
+
"""Get Oracle-specific SQL for retrieving current version.
|
|
68
|
+
|
|
69
|
+
Uses uppercase column names with lowercase aliases to match Python expectations.
|
|
70
|
+
Oracle stores unquoted identifiers as UPPERCASE, so we query UPPERCASE columns
|
|
71
|
+
and alias them as quoted "lowercase" for result consistency.
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
SQL builder object for version query.
|
|
75
|
+
"""
|
|
76
|
+
return (
|
|
77
|
+
sql
|
|
78
|
+
.select('VERSION_NUM AS "version_num"')
|
|
79
|
+
.from_(self.version_table)
|
|
80
|
+
.order_by("EXECUTION_SEQUENCE DESC")
|
|
81
|
+
.limit(1)
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
def _get_applied_migrations_sql(self) -> Select:
|
|
85
|
+
"""Get Oracle-specific SQL for retrieving all applied migrations.
|
|
86
|
+
|
|
87
|
+
Uses uppercase column names with lowercase aliases to match Python expectations.
|
|
88
|
+
Oracle stores unquoted identifiers as UPPERCASE, so we query UPPERCASE columns
|
|
89
|
+
and alias them as quoted "lowercase" for result consistency.
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
SQL builder object for migrations query.
|
|
93
|
+
"""
|
|
94
|
+
return (
|
|
95
|
+
sql
|
|
96
|
+
.select(
|
|
97
|
+
'VERSION_NUM AS "version_num"',
|
|
98
|
+
'VERSION_TYPE AS "version_type"',
|
|
99
|
+
'EXECUTION_SEQUENCE AS "execution_sequence"',
|
|
100
|
+
'DESCRIPTION AS "description"',
|
|
101
|
+
'APPLIED_AT AS "applied_at"',
|
|
102
|
+
'EXECUTION_TIME_MS AS "execution_time_ms"',
|
|
103
|
+
'CHECKSUM AS "checksum"',
|
|
104
|
+
'APPLIED_BY AS "applied_by"',
|
|
105
|
+
)
|
|
106
|
+
.from_(self.version_table)
|
|
107
|
+
.order_by("EXECUTION_SEQUENCE")
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
def _get_next_execution_sequence_sql(self) -> Select:
|
|
111
|
+
"""Get Oracle-specific SQL for retrieving next execution sequence.
|
|
112
|
+
|
|
113
|
+
Uses uppercase column names with lowercase alias to match Python expectations.
|
|
114
|
+
Oracle stores unquoted identifiers as UPPERCASE, so we query UPPERCASE columns
|
|
115
|
+
and alias them as quoted "lowercase" for result consistency.
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
SQL builder object for sequence query.
|
|
119
|
+
"""
|
|
120
|
+
return sql.select('COALESCE(MAX(EXECUTION_SEQUENCE), 0) + 1 AS "next_seq"').from_(self.version_table)
|
|
121
|
+
|
|
122
|
+
def _get_existing_columns_sql(self) -> str:
|
|
123
|
+
"""Get SQL to query existing columns in the tracking table.
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
Raw SQL string for Oracle's USER_TAB_COLUMNS query.
|
|
127
|
+
"""
|
|
128
|
+
return f"""
|
|
129
|
+
SELECT column_name
|
|
130
|
+
FROM user_tab_columns
|
|
131
|
+
WHERE table_name = '{self.version_table.upper()}'
|
|
132
|
+
"""
|
|
133
|
+
|
|
134
|
+
def _detect_missing_columns(self, existing_columns: "set[str]") -> "set[str]":
|
|
135
|
+
"""Detect which columns are missing from the current schema.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
existing_columns: Set of existing column names (uppercase).
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
Set of missing column names (lowercase).
|
|
142
|
+
"""
|
|
143
|
+
target_create = self._get_create_table_sql()
|
|
144
|
+
target_columns = {col.name.lower() for col in target_create.columns}
|
|
145
|
+
existing_lower = {col.lower() for col in existing_columns}
|
|
146
|
+
return target_columns - existing_lower
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class OracleSyncMigrationTracker(OracleMigrationTrackerMixin, BaseMigrationTracker["SyncDriverAdapterBase"]):
|
|
150
|
+
"""Oracle-specific sync migration tracker."""
|
|
151
|
+
|
|
152
|
+
__slots__ = ()
|
|
153
|
+
|
|
154
|
+
def _migrate_schema_if_needed(self, driver: "SyncDriverAdapterBase") -> None:
|
|
155
|
+
"""Check for and add any missing columns to the tracking table.
|
|
156
|
+
|
|
157
|
+
Uses the driver's data dictionary to query existing columns from Oracle's
|
|
158
|
+
USER_TAB_COLUMNS metadata table.
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
driver: The database driver to use.
|
|
162
|
+
"""
|
|
163
|
+
try:
|
|
164
|
+
columns_data = driver.data_dictionary.get_columns(driver, self.version_table)
|
|
165
|
+
existing_columns = {str(row["column_name"]).upper() for row in columns_data}
|
|
166
|
+
missing_columns = self._detect_missing_columns(existing_columns)
|
|
167
|
+
|
|
168
|
+
if not missing_columns:
|
|
169
|
+
logger.debug("Migration tracking table schema is up-to-date")
|
|
170
|
+
return
|
|
171
|
+
|
|
172
|
+
console.print(
|
|
173
|
+
f"[cyan]Migrating tracking table schema, adding columns: {', '.join(sorted(missing_columns))}[/]"
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
for col_name in sorted(missing_columns):
|
|
177
|
+
self._add_column(driver, col_name)
|
|
178
|
+
|
|
179
|
+
driver.commit()
|
|
180
|
+
console.print("[green]Migration tracking table schema updated successfully[/]")
|
|
181
|
+
|
|
182
|
+
except Exception as e:
|
|
183
|
+
logger.warning("Could not check or migrate tracking table schema: %s", e)
|
|
184
|
+
|
|
185
|
+
def _add_column(self, driver: "SyncDriverAdapterBase", column_name: str) -> None:
|
|
186
|
+
"""Add a single column to the tracking table.
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
driver: The database driver to use.
|
|
190
|
+
column_name: Name of the column to add (lowercase).
|
|
191
|
+
"""
|
|
192
|
+
target_create = self._get_create_table_sql()
|
|
193
|
+
column_def = next((col for col in target_create.columns if col.name.lower() == column_name), None)
|
|
194
|
+
|
|
195
|
+
if not column_def:
|
|
196
|
+
return
|
|
197
|
+
|
|
198
|
+
default_clause = f" DEFAULT {column_def.default}" if column_def.default else ""
|
|
199
|
+
not_null_clause = " NOT NULL" if column_def.not_null else ""
|
|
200
|
+
|
|
201
|
+
alter_sql = f"""
|
|
202
|
+
ALTER TABLE {self.version_table}
|
|
203
|
+
ADD {column_def.name} {column_def.dtype}{default_clause}{not_null_clause}
|
|
204
|
+
"""
|
|
205
|
+
|
|
206
|
+
driver.execute(alter_sql)
|
|
207
|
+
logger.debug("Added column %s to tracking table", column_name)
|
|
208
|
+
|
|
209
|
+
def ensure_tracking_table(self, driver: "SyncDriverAdapterBase") -> None:
|
|
210
|
+
"""Create the migration tracking table if it doesn't exist.
|
|
211
|
+
|
|
212
|
+
Uses a PL/SQL block to make the operation atomic and prevent race conditions.
|
|
213
|
+
Also checks for and adds missing columns to support schema migrations.
|
|
214
|
+
|
|
215
|
+
Args:
|
|
216
|
+
driver: The database driver to use.
|
|
217
|
+
"""
|
|
218
|
+
create_script = f"""
|
|
219
|
+
BEGIN
|
|
220
|
+
EXECUTE IMMEDIATE '
|
|
221
|
+
CREATE TABLE {self.version_table} (
|
|
222
|
+
version_num VARCHAR2(32) PRIMARY KEY,
|
|
223
|
+
version_type VARCHAR2(16),
|
|
224
|
+
execution_sequence INTEGER,
|
|
225
|
+
description VARCHAR2(2000),
|
|
226
|
+
applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
227
|
+
execution_time_ms INTEGER,
|
|
228
|
+
checksum VARCHAR2(64),
|
|
229
|
+
applied_by VARCHAR2(255)
|
|
230
|
+
)';
|
|
231
|
+
EXCEPTION
|
|
232
|
+
WHEN OTHERS THEN
|
|
233
|
+
IF SQLCODE = -955 THEN
|
|
234
|
+
NULL; -- Table already exists
|
|
235
|
+
ELSE
|
|
236
|
+
RAISE;
|
|
237
|
+
END IF;
|
|
238
|
+
END;
|
|
239
|
+
"""
|
|
240
|
+
driver.execute_script(create_script)
|
|
241
|
+
driver.commit()
|
|
242
|
+
|
|
243
|
+
self._migrate_schema_if_needed(driver)
|
|
244
|
+
|
|
245
|
+
def get_current_version(self, driver: "SyncDriverAdapterBase") -> "str | None":
|
|
246
|
+
"""Get the latest applied migration version.
|
|
247
|
+
|
|
248
|
+
Args:
|
|
249
|
+
driver: The database driver to use.
|
|
250
|
+
|
|
251
|
+
Returns:
|
|
252
|
+
The current migration version or None if no migrations applied.
|
|
253
|
+
"""
|
|
254
|
+
result = driver.execute(self._get_current_version_sql())
|
|
255
|
+
data = result.get_data()
|
|
256
|
+
return data[0]["version_num"] if data else None
|
|
257
|
+
|
|
258
|
+
def get_applied_migrations(self, driver: "SyncDriverAdapterBase") -> "list[dict[str, Any]]":
|
|
259
|
+
"""Get all applied migrations in order.
|
|
260
|
+
|
|
261
|
+
Args:
|
|
262
|
+
driver: The database driver to use.
|
|
263
|
+
|
|
264
|
+
Returns:
|
|
265
|
+
List of migration records as dictionaries with lowercase keys.
|
|
266
|
+
"""
|
|
267
|
+
result = driver.execute(self._get_applied_migrations_sql())
|
|
268
|
+
return result.get_data()
|
|
269
|
+
|
|
270
|
+
def record_migration(
|
|
271
|
+
self, driver: "SyncDriverAdapterBase", version: str, description: str, execution_time_ms: int, checksum: str
|
|
272
|
+
) -> None:
|
|
273
|
+
"""Record a successfully applied migration.
|
|
274
|
+
|
|
275
|
+
Args:
|
|
276
|
+
driver: The database driver to use.
|
|
277
|
+
version: Version number of the migration.
|
|
278
|
+
description: Description of the migration.
|
|
279
|
+
execution_time_ms: Execution time in milliseconds.
|
|
280
|
+
checksum: MD5 checksum of the migration content.
|
|
281
|
+
"""
|
|
282
|
+
applied_by = getpass.getuser()
|
|
283
|
+
parsed_version = parse_version(version)
|
|
284
|
+
version_type = parsed_version.type.value
|
|
285
|
+
|
|
286
|
+
next_seq_result = driver.execute(self._get_next_execution_sequence_sql())
|
|
287
|
+
seq_data = next_seq_result.get_data()
|
|
288
|
+
execution_sequence = seq_data[0]["next_seq"] if seq_data else 1
|
|
289
|
+
|
|
290
|
+
record_sql = self._get_record_migration_sql(
|
|
291
|
+
version, version_type, execution_sequence, description, execution_time_ms, checksum, applied_by
|
|
292
|
+
)
|
|
293
|
+
driver.execute(record_sql)
|
|
294
|
+
driver.commit()
|
|
295
|
+
|
|
296
|
+
def remove_migration(self, driver: "SyncDriverAdapterBase", version: str) -> None:
|
|
297
|
+
"""Remove a migration record.
|
|
298
|
+
|
|
299
|
+
Args:
|
|
300
|
+
driver: The database driver to use.
|
|
301
|
+
version: Version number to remove.
|
|
302
|
+
"""
|
|
303
|
+
remove_sql = self._get_remove_migration_sql(version)
|
|
304
|
+
driver.execute(remove_sql)
|
|
305
|
+
driver.commit()
|
|
306
|
+
|
|
307
|
+
def update_version_record(self, driver: "SyncDriverAdapterBase", old_version: str, new_version: str) -> None:
|
|
308
|
+
"""Update migration version record from timestamp to sequential.
|
|
309
|
+
|
|
310
|
+
Updates version_num and version_type while preserving execution_sequence,
|
|
311
|
+
applied_at, and other tracking metadata. Used during fix command.
|
|
312
|
+
|
|
313
|
+
Idempotent: If the version is already updated, logs and continues without error.
|
|
314
|
+
This allows fix command to be safely re-run after pulling changes.
|
|
315
|
+
|
|
316
|
+
Args:
|
|
317
|
+
driver: The database driver to use.
|
|
318
|
+
old_version: Current timestamp version string.
|
|
319
|
+
new_version: New sequential version string.
|
|
320
|
+
|
|
321
|
+
Raises:
|
|
322
|
+
ValueError: If neither old_version nor new_version found in database.
|
|
323
|
+
"""
|
|
324
|
+
parsed_new_version = parse_version(new_version)
|
|
325
|
+
new_version_type = parsed_new_version.type.value
|
|
326
|
+
|
|
327
|
+
result = driver.execute(self._get_update_version_sql(old_version, new_version, new_version_type))
|
|
328
|
+
|
|
329
|
+
if result.rows_affected == 0:
|
|
330
|
+
check_result = driver.execute(self._get_applied_migrations_sql())
|
|
331
|
+
applied_versions = {row["version_num"] for row in check_result.data} if check_result.data else set()
|
|
332
|
+
|
|
333
|
+
if new_version in applied_versions:
|
|
334
|
+
logger.debug("Version already updated: %s -> %s", old_version, new_version)
|
|
335
|
+
return
|
|
336
|
+
|
|
337
|
+
msg = f"Migration {old_version} not found in database for update to {new_version}"
|
|
338
|
+
raise ValueError(msg)
|
|
339
|
+
|
|
340
|
+
driver.commit()
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
class OracleAsyncMigrationTracker(OracleMigrationTrackerMixin, BaseMigrationTracker["AsyncDriverAdapterBase"]):
|
|
344
|
+
"""Oracle-specific async migration tracker."""
|
|
345
|
+
|
|
346
|
+
__slots__ = ()
|
|
347
|
+
|
|
348
|
+
async def _migrate_schema_if_needed(self, driver: "AsyncDriverAdapterBase") -> None:
|
|
349
|
+
"""Check for and add any missing columns to the tracking table.
|
|
350
|
+
|
|
351
|
+
Uses the driver's data dictionary to query existing columns from Oracle's
|
|
352
|
+
USER_TAB_COLUMNS metadata table.
|
|
353
|
+
|
|
354
|
+
Args:
|
|
355
|
+
driver: The database driver to use.
|
|
356
|
+
"""
|
|
357
|
+
try:
|
|
358
|
+
columns_data = await driver.data_dictionary.get_columns(driver, self.version_table)
|
|
359
|
+
existing_columns = {str(row["column_name"]).upper() for row in columns_data}
|
|
360
|
+
missing_columns = self._detect_missing_columns(existing_columns)
|
|
361
|
+
|
|
362
|
+
if not missing_columns:
|
|
363
|
+
logger.debug("Migration tracking table schema is up-to-date")
|
|
364
|
+
return
|
|
365
|
+
|
|
366
|
+
console.print(
|
|
367
|
+
f"[cyan]Migrating tracking table schema, adding columns: {', '.join(sorted(missing_columns))}[/]"
|
|
368
|
+
)
|
|
369
|
+
|
|
370
|
+
for col_name in sorted(missing_columns):
|
|
371
|
+
await self._add_column(driver, col_name)
|
|
372
|
+
|
|
373
|
+
await driver.commit()
|
|
374
|
+
console.print("[green]Migration tracking table schema updated successfully[/]")
|
|
375
|
+
|
|
376
|
+
except Exception as e:
|
|
377
|
+
logger.warning("Could not check or migrate tracking table schema: %s", e)
|
|
378
|
+
|
|
379
|
+
async def _add_column(self, driver: "AsyncDriverAdapterBase", column_name: str) -> None:
|
|
380
|
+
"""Add a single column to the tracking table.
|
|
381
|
+
|
|
382
|
+
Args:
|
|
383
|
+
driver: The database driver to use.
|
|
384
|
+
column_name: Name of the column to add (lowercase).
|
|
385
|
+
"""
|
|
386
|
+
target_create = self._get_create_table_sql()
|
|
387
|
+
column_def = next((col for col in target_create.columns if col.name.lower() == column_name), None)
|
|
388
|
+
|
|
389
|
+
if not column_def:
|
|
390
|
+
return
|
|
391
|
+
|
|
392
|
+
default_clause = f" DEFAULT {column_def.default}" if column_def.default else ""
|
|
393
|
+
not_null_clause = " NOT NULL" if column_def.not_null else ""
|
|
394
|
+
|
|
395
|
+
alter_sql = f"""
|
|
396
|
+
ALTER TABLE {self.version_table}
|
|
397
|
+
ADD {column_def.name} {column_def.dtype}{default_clause}{not_null_clause}
|
|
398
|
+
"""
|
|
399
|
+
|
|
400
|
+
await driver.execute(alter_sql)
|
|
401
|
+
logger.debug("Added column %s to tracking table", column_name)
|
|
402
|
+
|
|
403
|
+
async def ensure_tracking_table(self, driver: "AsyncDriverAdapterBase") -> None:
|
|
404
|
+
"""Create the migration tracking table if it doesn't exist.
|
|
405
|
+
|
|
406
|
+
Uses a PL/SQL block to make the operation atomic and prevent race conditions.
|
|
407
|
+
Also checks for and adds missing columns to support schema migrations.
|
|
408
|
+
|
|
409
|
+
Args:
|
|
410
|
+
driver: The database driver to use.
|
|
411
|
+
"""
|
|
412
|
+
create_script = f"""
|
|
413
|
+
BEGIN
|
|
414
|
+
EXECUTE IMMEDIATE '
|
|
415
|
+
CREATE TABLE {self.version_table} (
|
|
416
|
+
version_num VARCHAR2(32) PRIMARY KEY,
|
|
417
|
+
version_type VARCHAR2(16),
|
|
418
|
+
execution_sequence INTEGER,
|
|
419
|
+
description VARCHAR2(2000),
|
|
420
|
+
applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
421
|
+
execution_time_ms INTEGER,
|
|
422
|
+
checksum VARCHAR2(64),
|
|
423
|
+
applied_by VARCHAR2(255)
|
|
424
|
+
)';
|
|
425
|
+
EXCEPTION
|
|
426
|
+
WHEN OTHERS THEN
|
|
427
|
+
IF SQLCODE = -955 THEN
|
|
428
|
+
NULL; -- Table already exists
|
|
429
|
+
ELSE
|
|
430
|
+
RAISE;
|
|
431
|
+
END IF;
|
|
432
|
+
END;
|
|
433
|
+
"""
|
|
434
|
+
await driver.execute_script(create_script)
|
|
435
|
+
await driver.commit()
|
|
436
|
+
|
|
437
|
+
await self._migrate_schema_if_needed(driver)
|
|
438
|
+
|
|
439
|
+
async def get_current_version(self, driver: "AsyncDriverAdapterBase") -> "str | None":
|
|
440
|
+
"""Get the latest applied migration version.
|
|
441
|
+
|
|
442
|
+
Args:
|
|
443
|
+
driver: The database driver to use.
|
|
444
|
+
|
|
445
|
+
Returns:
|
|
446
|
+
The current migration version or None if no migrations applied.
|
|
447
|
+
"""
|
|
448
|
+
result = await driver.execute(self._get_current_version_sql())
|
|
449
|
+
data = result.get_data()
|
|
450
|
+
return data[0]["version_num"] if data else None
|
|
451
|
+
|
|
452
|
+
async def get_applied_migrations(self, driver: "AsyncDriverAdapterBase") -> "list[dict[str, Any]]":
|
|
453
|
+
"""Get all applied migrations in order.
|
|
454
|
+
|
|
455
|
+
Args:
|
|
456
|
+
driver: The database driver to use.
|
|
457
|
+
|
|
458
|
+
Returns:
|
|
459
|
+
List of migration records as dictionaries with lowercase keys.
|
|
460
|
+
"""
|
|
461
|
+
result = await driver.execute(self._get_applied_migrations_sql())
|
|
462
|
+
return result.get_data()
|
|
463
|
+
|
|
464
|
+
async def record_migration(
|
|
465
|
+
self, driver: "AsyncDriverAdapterBase", version: str, description: str, execution_time_ms: int, checksum: str
|
|
466
|
+
) -> None:
|
|
467
|
+
"""Record a successfully applied migration.
|
|
468
|
+
|
|
469
|
+
Args:
|
|
470
|
+
driver: The database driver to use.
|
|
471
|
+
version: Version number of the migration.
|
|
472
|
+
description: Description of the migration.
|
|
473
|
+
execution_time_ms: Execution time in milliseconds.
|
|
474
|
+
checksum: MD5 checksum of the migration content.
|
|
475
|
+
"""
|
|
476
|
+
|
|
477
|
+
applied_by = getpass.getuser()
|
|
478
|
+
parsed_version = parse_version(version)
|
|
479
|
+
version_type = parsed_version.type.value
|
|
480
|
+
|
|
481
|
+
next_seq_result = await driver.execute(self._get_next_execution_sequence_sql())
|
|
482
|
+
seq_data = next_seq_result.get_data()
|
|
483
|
+
execution_sequence = seq_data[0]["next_seq"] if seq_data else 1
|
|
484
|
+
|
|
485
|
+
record_sql = self._get_record_migration_sql(
|
|
486
|
+
version, version_type, execution_sequence, description, execution_time_ms, checksum, applied_by
|
|
487
|
+
)
|
|
488
|
+
await driver.execute(record_sql)
|
|
489
|
+
await driver.commit()
|
|
490
|
+
|
|
491
|
+
async def remove_migration(self, driver: "AsyncDriverAdapterBase", version: str) -> None:
|
|
492
|
+
"""Remove a migration record.
|
|
493
|
+
|
|
494
|
+
Args:
|
|
495
|
+
driver: The database driver to use.
|
|
496
|
+
version: Version number to remove.
|
|
497
|
+
"""
|
|
498
|
+
remove_sql = self._get_remove_migration_sql(version)
|
|
499
|
+
await driver.execute(remove_sql)
|
|
500
|
+
await driver.commit()
|
|
501
|
+
|
|
502
|
+
async def update_version_record(self, driver: "AsyncDriverAdapterBase", old_version: str, new_version: str) -> None:
|
|
503
|
+
"""Update migration version record from timestamp to sequential.
|
|
504
|
+
|
|
505
|
+
Updates version_num and version_type while preserving execution_sequence,
|
|
506
|
+
applied_at, and other tracking metadata. Used during fix command.
|
|
507
|
+
|
|
508
|
+
Idempotent: If the version is already updated, logs and continues without error.
|
|
509
|
+
This allows fix command to be safely re-run after pulling changes.
|
|
510
|
+
|
|
511
|
+
Args:
|
|
512
|
+
driver: The database driver to use.
|
|
513
|
+
old_version: Current timestamp version string.
|
|
514
|
+
new_version: New sequential version string.
|
|
515
|
+
|
|
516
|
+
Raises:
|
|
517
|
+
ValueError: If neither old_version nor new_version found in database.
|
|
518
|
+
"""
|
|
519
|
+
parsed_new_version = parse_version(new_version)
|
|
520
|
+
new_version_type = parsed_new_version.type.value
|
|
521
|
+
|
|
522
|
+
result = await driver.execute(self._get_update_version_sql(old_version, new_version, new_version_type))
|
|
523
|
+
|
|
524
|
+
if result.rows_affected == 0:
|
|
525
|
+
check_result = await driver.execute(self._get_applied_migrations_sql())
|
|
526
|
+
applied_versions = {row["version_num"] for row in check_result.data} if check_result.data else set()
|
|
527
|
+
|
|
528
|
+
if new_version in applied_versions:
|
|
529
|
+
logger.debug("Version already updated: %s -> %s", old_version, new_version)
|
|
530
|
+
return
|
|
531
|
+
|
|
532
|
+
msg = f"Migration {old_version} not found in database for update to {new_version}"
|
|
533
|
+
raise ValueError(msg)
|
|
534
|
+
|
|
535
|
+
await driver.commit()
|