sqlspec 0.18.0__tar.gz → 0.19.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sqlspec might be problematic. Click here for more details.
- {sqlspec-0.18.0 → sqlspec-0.19.0}/PKG-INFO +1 -1
- {sqlspec-0.18.0 → sqlspec-0.19.0}/pyproject.toml +1 -1
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/base.py +18 -14
- sqlspec-0.19.0/sqlspec/cli.py +495 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/config.py +151 -1
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/extensions/litestar/plugin.py +15 -8
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_duckdb/test_connection.py +4 -1
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_duckdb/test_execute_many.py +5 -2
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_duckdb/test_parameter_styles.py +6 -4
- sqlspec-0.19.0/tests/unit/test_base/test_sql_integration.py +298 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/uv.lock +7 -7
- sqlspec-0.18.0/sqlspec/cli.py +0 -247
- sqlspec-0.18.0/tests/unit/test_base_sql_integration.py +0 -282
- {sqlspec-0.18.0 → sqlspec-0.19.0}/.gitignore +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/.pre-commit-config.yaml +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/CONTRIBUTING.rst +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/LICENSE +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/Makefile +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/NOTICE +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/README.md +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/__main__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/__metadata__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/_serialization.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/_sql.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/_typing.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/adbc/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/adbc/_types.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/adbc/config.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/adbc/driver.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/aiosqlite/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/aiosqlite/_types.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/aiosqlite/config.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/aiosqlite/driver.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/aiosqlite/pool.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/asyncmy/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/asyncmy/_types.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/asyncmy/config.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/asyncmy/driver.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/asyncpg/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/asyncpg/_types.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/asyncpg/config.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/asyncpg/driver.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/bigquery/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/bigquery/_types.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/bigquery/config.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/bigquery/driver.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/duckdb/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/duckdb/_types.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/duckdb/config.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/duckdb/driver.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/duckdb/pool.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/oracledb/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/oracledb/_types.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/oracledb/config.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/oracledb/driver.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/oracledb/migrations.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/psqlpy/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/psqlpy/_types.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/psqlpy/config.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/psqlpy/driver.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/psycopg/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/psycopg/_types.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/psycopg/config.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/psycopg/driver.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/sqlite/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/sqlite/_types.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/sqlite/config.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/sqlite/driver.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/adapters/sqlite/pool.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/_base.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/_column.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/_ddl.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/_delete.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/_expression_wrappers.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/_insert.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/_merge.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/_parsing_utils.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/_select.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/_update.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/mixins/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/mixins/_cte_and_set_ops.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/mixins/_delete_operations.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/mixins/_insert_operations.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/mixins/_join_operations.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/mixins/_merge_operations.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/mixins/_order_limit_operations.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/mixins/_pivot_operations.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/mixins/_select_operations.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/mixins/_update_operations.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/builder/mixins/_where_clause.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/core/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/core/cache.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/core/compiler.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/core/filters.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/core/hashing.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/core/parameters.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/core/result.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/core/splitter.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/core/statement.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/driver/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/driver/_async.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/driver/_common.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/driver/_sync.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/driver/mixins/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/driver/mixins/_result_tools.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/driver/mixins/_sql_translator.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/exceptions.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/extensions/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/extensions/aiosql/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/extensions/aiosql/adapter.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/extensions/litestar/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/extensions/litestar/_utils.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/extensions/litestar/cli.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/extensions/litestar/config.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/extensions/litestar/handlers.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/extensions/litestar/providers.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/loader.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/migrations/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/migrations/base.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/migrations/commands.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/migrations/loaders.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/migrations/runner.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/migrations/tracker.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/migrations/utils.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/protocols.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/py.typed +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/storage/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/storage/backends/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/storage/backends/base.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/storage/backends/fsspec.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/storage/backends/obstore.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/storage/capabilities.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/storage/registry.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/typing.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/utils/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/utils/correlation.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/utils/deprecation.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/utils/fixtures.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/utils/logging.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/utils/module_loader.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/utils/serializers.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/utils/singleton.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/utils/sync_tools.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/utils/text.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/sqlspec/utils/type_guards.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/conftest.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/asset_maintenance.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/ddls-mysql-collection.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/ddls-postgres-collection.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/example_usage.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/init.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/mysql/collection-config.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/mysql/collection-data_types.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/mysql/collection-database_details.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/mysql/collection-engines.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/mysql/collection-hostname.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/mysql/collection-plugins.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/mysql/collection-process_list.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/mysql/collection-resource-groups.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/mysql/collection-schema_objects.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/mysql/collection-table_details.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/mysql/collection-users.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/mysql/init.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/oracle.ddl.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/postgres/collection-applications.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/postgres/collection-aws_extension_dependency.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/postgres/collection-aws_oracle_exists.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/postgres/collection-bg_writer_stats.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/postgres/collection-calculated_metrics.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/postgres/collection-data_types.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/postgres/collection-database_details.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/postgres/collection-extensions.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/postgres/collection-index_details.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/postgres/collection-pglogical-details.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/postgres/collection-privileges.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/postgres/collection-replication_slots.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/postgres/collection-replication_stats.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/postgres/collection-schema_details.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/postgres/collection-schema_objects.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/postgres/collection-settings.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/postgres/collection-source_details.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/postgres/collection-table_details.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/postgres/extended-collection-all-databases.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/postgres/init.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/readiness-check.sql +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/fixtures/sql_utils.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/conftest.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_adbc/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_adbc/conftest.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_adbc/test_adbc_arrow_features.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_adbc/test_adbc_backends.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_adbc/test_adbc_connection.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_adbc/test_adbc_driver.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_adbc/test_adbc_edge_cases.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_adbc/test_adbc_results.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_adbc/test_migrations.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_aiosqlite/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_aiosqlite/conftest.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_aiosqlite/test_connection.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_aiosqlite/test_driver.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_aiosqlite/test_migrations.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_aiosqlite/test_pooling.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_asyncmy/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_asyncmy/conftest.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_asyncmy/test_asyncmy_features.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_asyncmy/test_config.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_asyncmy/test_driver.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_asyncmy/test_migrations.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_asyncmy/test_parameter_styles.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_asyncpg/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_asyncpg/conftest.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_asyncpg/test_connection.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_asyncpg/test_driver.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_asyncpg/test_execute_many.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_asyncpg/test_migrations.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_asyncpg/test_parameter_styles.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_bigquery/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_bigquery/conftest.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_bigquery/test_bigquery_features.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_bigquery/test_config.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_bigquery/test_connection.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_bigquery/test_driver.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_bigquery/test_migrations.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_bigquery/test_parameter_styles.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_duckdb/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_duckdb/test_driver.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_duckdb/test_migrations.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_duckdb/test_mixed_parameter_styles.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_duckdb/test_pooling.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_duckdb/utils.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_oracledb/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_oracledb/conftest.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_oracledb/test_connection.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_oracledb/test_driver_async.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_oracledb/test_driver_sync.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_oracledb/test_execute_many.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_oracledb/test_migrations.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_oracledb/test_oracle_features.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_oracledb/test_parameter_styles.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_psqlpy/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_psqlpy/conftest.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_psqlpy/test_connection.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_psqlpy/test_driver.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_psqlpy/test_migrations.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_psqlpy/test_parameter_styles.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_psqlpy/test_psqlpy_features.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_psycopg/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_psycopg/conftest.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_psycopg/test_async_copy.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_psycopg/test_connection.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_psycopg/test_driver.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_psycopg/test_execute_many.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_psycopg/test_migrations.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_psycopg/test_parameter_styles.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_sqlite/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_sqlite/conftest.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_sqlite/test_driver.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_sqlite/test_migrations.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_sqlite/test_parameter_styles.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_sqlite/test_pooling.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_adapters/test_sqlite/test_query_mixin.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_loader/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_loader/test_file_system_loading.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/integration/test_migrations/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/conftest.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_adapters/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_adapters/conftest.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_adapters/test_adapter_implementations.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_adapters/test_aiosqlite/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_adapters/test_aiosqlite/test_pool.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_adapters/test_async_adapters.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_adapters/test_sqlite/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_adapters/test_sqlite/test_pool.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_adapters/test_sync_adapters.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_base/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_base/test_sqlspec_class.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_builder/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_builder/test_insert_builder.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_builder/test_parameter_naming.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_builder_parameter_naming.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_core/test_cache.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_core/test_compiler.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_core/test_filters.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_core/test_hashing.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_core/test_parameters.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_core/test_result.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_core/test_statement.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_loader/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_loader/test_cache_integration.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_loader/test_fixtures_directory_loading.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_loader/test_loading_patterns.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_loader/test_sql_file_loader.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_migrations/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_migrations/test_migration.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_migrations/test_migration_commands.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_migrations/test_migration_execution.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_migrations/test_migration_runner.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_parsing_utils.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_sql_factory.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_utils/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_utils/test_correlation.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_utils/test_deprecation.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_utils/test_fixtures.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_utils/test_logging.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_utils/test_module_loader.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_utils/test_serializers.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_utils/test_singleton.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_utils/test_sync_tools.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_utils/test_text.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tests/unit/test_utils/test_type_guards.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tools/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tools/build_docs.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tools/local-infra.sh +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tools/pypi_readme.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tools/sphinx_ext/__init__.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tools/sphinx_ext/changelog.py +0 -0
- {sqlspec-0.18.0 → sqlspec-0.19.0}/tools/sphinx_ext/missing_references.py +0 -0
|
@@ -13,7 +13,7 @@ maintainers = [{ name = "Litestar Developers", email = "hello@litestar.dev" }]
|
|
|
13
13
|
name = "sqlspec"
|
|
14
14
|
readme = "README.md"
|
|
15
15
|
requires-python = ">=3.9, <4.0"
|
|
16
|
-
version = "0.
|
|
16
|
+
version = "0.19.0"
|
|
17
17
|
|
|
18
18
|
[project.urls]
|
|
19
19
|
Discord = "https://discord.gg/litestar"
|
|
@@ -593,22 +593,18 @@ class SQLSpec:
|
|
|
593
593
|
)
|
|
594
594
|
)
|
|
595
595
|
|
|
596
|
-
def _ensure_sql_loader(self) -> "SQLFileLoader":
|
|
597
|
-
"""Ensure SQL loader is initialized lazily."""
|
|
598
|
-
if self._sql_loader is None:
|
|
599
|
-
from sqlspec.loader import SQLFileLoader
|
|
600
|
-
|
|
601
|
-
self._sql_loader = SQLFileLoader()
|
|
602
|
-
return self._sql_loader
|
|
603
|
-
|
|
604
596
|
def load_sql_files(self, *paths: "Union[str, Path]") -> None:
|
|
605
597
|
"""Load SQL files from paths or directories.
|
|
606
598
|
|
|
607
599
|
Args:
|
|
608
600
|
*paths: One or more file paths or directory paths to load.
|
|
609
601
|
"""
|
|
610
|
-
|
|
611
|
-
|
|
602
|
+
if self._sql_loader is None:
|
|
603
|
+
from sqlspec.loader import SQLFileLoader
|
|
604
|
+
|
|
605
|
+
self._sql_loader = SQLFileLoader()
|
|
606
|
+
|
|
607
|
+
self._sql_loader.load_sql(*paths)
|
|
612
608
|
logger.debug("Loaded SQL files: %s", paths)
|
|
613
609
|
|
|
614
610
|
def add_named_sql(self, name: str, sql: str, dialect: "Optional[str]" = None) -> None:
|
|
@@ -619,8 +615,12 @@ class SQLSpec:
|
|
|
619
615
|
sql: Raw SQL content.
|
|
620
616
|
dialect: Optional dialect for the SQL statement.
|
|
621
617
|
"""
|
|
622
|
-
|
|
623
|
-
|
|
618
|
+
if self._sql_loader is None:
|
|
619
|
+
from sqlspec.loader import SQLFileLoader
|
|
620
|
+
|
|
621
|
+
self._sql_loader = SQLFileLoader()
|
|
622
|
+
|
|
623
|
+
self._sql_loader.add_named_sql(name, sql, dialect)
|
|
624
624
|
logger.debug("Added named SQL: %s", name)
|
|
625
625
|
|
|
626
626
|
def get_sql(self, name: str) -> "SQL":
|
|
@@ -633,8 +633,12 @@ class SQLSpec:
|
|
|
633
633
|
Returns:
|
|
634
634
|
SQL object ready for execution.
|
|
635
635
|
"""
|
|
636
|
-
|
|
637
|
-
|
|
636
|
+
if self._sql_loader is None:
|
|
637
|
+
from sqlspec.loader import SQLFileLoader
|
|
638
|
+
|
|
639
|
+
self._sql_loader = SQLFileLoader()
|
|
640
|
+
|
|
641
|
+
return self._sql_loader.get_sql(name)
|
|
638
642
|
|
|
639
643
|
def list_sql_queries(self) -> "list[str]":
|
|
640
644
|
"""List all available query names.
|
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
# ruff: noqa: C901
|
|
2
|
+
import sys
|
|
3
|
+
from collections.abc import Sequence
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Optional, Union, cast
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from click import Group
|
|
8
|
+
|
|
9
|
+
from sqlspec.config import AsyncDatabaseConfig, SyncDatabaseConfig
|
|
10
|
+
|
|
11
|
+
__all__ = ("add_migration_commands", "get_sqlspec_group")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def get_sqlspec_group() -> "Group":
|
|
15
|
+
"""Get the SQLSpec CLI group.
|
|
16
|
+
|
|
17
|
+
Raises:
|
|
18
|
+
MissingDependencyError: If the `click` package is not installed.
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
The SQLSpec CLI group.
|
|
22
|
+
"""
|
|
23
|
+
from sqlspec.exceptions import MissingDependencyError
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
import rich_click as click
|
|
27
|
+
except ImportError:
|
|
28
|
+
try:
|
|
29
|
+
import click # type: ignore[no-redef]
|
|
30
|
+
except ImportError as e:
|
|
31
|
+
raise MissingDependencyError(package="click", install_package="cli") from e
|
|
32
|
+
|
|
33
|
+
@click.group(name="sqlspec")
|
|
34
|
+
@click.option(
|
|
35
|
+
"--config",
|
|
36
|
+
help="Dotted path to SQLSpec config(s) (e.g. 'myapp.config.sqlspec_configs')",
|
|
37
|
+
required=True,
|
|
38
|
+
type=str,
|
|
39
|
+
)
|
|
40
|
+
@click.pass_context
|
|
41
|
+
def sqlspec_group(ctx: "click.Context", config: str) -> None:
|
|
42
|
+
"""SQLSpec CLI commands."""
|
|
43
|
+
from rich import get_console
|
|
44
|
+
|
|
45
|
+
from sqlspec.utils import module_loader
|
|
46
|
+
|
|
47
|
+
console = get_console()
|
|
48
|
+
ctx.ensure_object(dict)
|
|
49
|
+
try:
|
|
50
|
+
config_instance = module_loader.import_string(config)
|
|
51
|
+
if isinstance(config_instance, Sequence):
|
|
52
|
+
ctx.obj["configs"] = config_instance
|
|
53
|
+
else:
|
|
54
|
+
ctx.obj["configs"] = [config_instance]
|
|
55
|
+
except ImportError as e:
|
|
56
|
+
console.print(f"[red]Error loading config: {e}[/]")
|
|
57
|
+
ctx.exit(1)
|
|
58
|
+
|
|
59
|
+
return sqlspec_group
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def add_migration_commands(database_group: Optional["Group"] = None) -> "Group":
|
|
63
|
+
"""Add migration commands to the database group.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
database_group: The database group to add the commands to.
|
|
67
|
+
|
|
68
|
+
Raises:
|
|
69
|
+
MissingDependencyError: If the `click` package is not installed.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
The database group with the migration commands added.
|
|
73
|
+
"""
|
|
74
|
+
from sqlspec.exceptions import MissingDependencyError
|
|
75
|
+
|
|
76
|
+
try:
|
|
77
|
+
import rich_click as click
|
|
78
|
+
except ImportError:
|
|
79
|
+
try:
|
|
80
|
+
import click # type: ignore[no-redef]
|
|
81
|
+
except ImportError as e:
|
|
82
|
+
raise MissingDependencyError(package="click", install_package="cli") from e
|
|
83
|
+
from rich import get_console
|
|
84
|
+
|
|
85
|
+
console = get_console()
|
|
86
|
+
|
|
87
|
+
if database_group is None:
|
|
88
|
+
database_group = get_sqlspec_group()
|
|
89
|
+
|
|
90
|
+
bind_key_option = click.option(
|
|
91
|
+
"--bind-key", help="Specify which SQLSpec config to use by bind key", type=str, default=None
|
|
92
|
+
)
|
|
93
|
+
verbose_option = click.option("--verbose", help="Enable verbose output.", type=bool, default=False, is_flag=True)
|
|
94
|
+
no_prompt_option = click.option(
|
|
95
|
+
"--no-prompt",
|
|
96
|
+
help="Do not prompt for confirmation before executing the command.",
|
|
97
|
+
type=bool,
|
|
98
|
+
default=False,
|
|
99
|
+
required=False,
|
|
100
|
+
show_default=True,
|
|
101
|
+
is_flag=True,
|
|
102
|
+
)
|
|
103
|
+
include_option = click.option(
|
|
104
|
+
"--include", multiple=True, help="Include only specific configurations (can be used multiple times)"
|
|
105
|
+
)
|
|
106
|
+
exclude_option = click.option(
|
|
107
|
+
"--exclude", multiple=True, help="Exclude specific configurations (can be used multiple times)"
|
|
108
|
+
)
|
|
109
|
+
dry_run_option = click.option(
|
|
110
|
+
"--dry-run", is_flag=True, default=False, help="Show what would be executed without making changes"
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
def get_config_by_bind_key(
|
|
114
|
+
ctx: "click.Context", bind_key: Optional[str]
|
|
115
|
+
) -> "Union[AsyncDatabaseConfig[Any, Any, Any], SyncDatabaseConfig[Any, Any, Any]]":
|
|
116
|
+
"""Get the SQLSpec config for the specified bind key.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
ctx: The click context.
|
|
120
|
+
bind_key: The bind key to get the config for.
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
The SQLSpec config for the specified bind key.
|
|
124
|
+
"""
|
|
125
|
+
configs = ctx.obj["configs"]
|
|
126
|
+
if bind_key is None:
|
|
127
|
+
config = configs[0]
|
|
128
|
+
else:
|
|
129
|
+
config = None
|
|
130
|
+
for cfg in configs:
|
|
131
|
+
config_name = getattr(cfg, "name", None) or getattr(cfg, "bind_key", None)
|
|
132
|
+
if config_name == bind_key:
|
|
133
|
+
config = cfg
|
|
134
|
+
break
|
|
135
|
+
|
|
136
|
+
if config is None:
|
|
137
|
+
console.print(f"[red]No config found for bind key: {bind_key}[/]")
|
|
138
|
+
sys.exit(1)
|
|
139
|
+
|
|
140
|
+
# Extract the actual config from DatabaseConfig wrapper if needed
|
|
141
|
+
from sqlspec.extensions.litestar.config import DatabaseConfig
|
|
142
|
+
|
|
143
|
+
if isinstance(config, DatabaseConfig):
|
|
144
|
+
config = config.config
|
|
145
|
+
|
|
146
|
+
return cast("Union[AsyncDatabaseConfig[Any, Any, Any], SyncDatabaseConfig[Any, Any, Any]]", config)
|
|
147
|
+
|
|
148
|
+
def get_configs_with_migrations(ctx: "click.Context", enabled_only: bool = False) -> "list[tuple[str, Any]]":
|
|
149
|
+
"""Get all configurations that have migrations enabled.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
ctx: The click context.
|
|
153
|
+
enabled_only: If True, only return configs with enabled=True.
|
|
154
|
+
|
|
155
|
+
Returns:
|
|
156
|
+
List of tuples (config_name, config) for configs with migrations enabled.
|
|
157
|
+
"""
|
|
158
|
+
configs = ctx.obj["configs"]
|
|
159
|
+
migration_configs = []
|
|
160
|
+
|
|
161
|
+
from sqlspec.extensions.litestar.config import DatabaseConfig
|
|
162
|
+
|
|
163
|
+
for config in configs:
|
|
164
|
+
# Extract the actual config from DatabaseConfig wrapper if needed
|
|
165
|
+
actual_config = config.config if isinstance(config, DatabaseConfig) else config
|
|
166
|
+
|
|
167
|
+
migration_config = getattr(actual_config, "migration_config", None)
|
|
168
|
+
if migration_config:
|
|
169
|
+
enabled = migration_config.get("enabled", True)
|
|
170
|
+
if not enabled_only or enabled:
|
|
171
|
+
config_name = (
|
|
172
|
+
getattr(actual_config, "name", None)
|
|
173
|
+
or getattr(actual_config, "bind_key", None)
|
|
174
|
+
or str(type(actual_config).__name__)
|
|
175
|
+
)
|
|
176
|
+
migration_configs.append((config_name, actual_config))
|
|
177
|
+
|
|
178
|
+
return migration_configs
|
|
179
|
+
|
|
180
|
+
def filter_configs(
|
|
181
|
+
configs: "list[tuple[str, Any]]", include: "tuple[str, ...]", exclude: "tuple[str, ...]"
|
|
182
|
+
) -> "list[tuple[str, Any]]":
|
|
183
|
+
"""Filter configuration list based on include/exclude criteria.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
configs: List of (config_name, config) tuples.
|
|
187
|
+
include: Config names to include (empty means include all).
|
|
188
|
+
exclude: Config names to exclude.
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
Filtered list of configurations.
|
|
192
|
+
"""
|
|
193
|
+
filtered = configs
|
|
194
|
+
if include:
|
|
195
|
+
filtered = [(name, config) for name, config in filtered if name in include]
|
|
196
|
+
if exclude:
|
|
197
|
+
filtered = [(name, config) for name, config in filtered if name not in exclude]
|
|
198
|
+
return filtered
|
|
199
|
+
|
|
200
|
+
def process_multiple_configs(
|
|
201
|
+
ctx: "click.Context",
|
|
202
|
+
bind_key: Optional[str],
|
|
203
|
+
include: "tuple[str, ...]",
|
|
204
|
+
exclude: "tuple[str, ...]",
|
|
205
|
+
dry_run: bool,
|
|
206
|
+
operation_name: str,
|
|
207
|
+
) -> "Optional[list[tuple[str, Any]]]":
|
|
208
|
+
"""Process configuration selection for multi-config operations.
|
|
209
|
+
|
|
210
|
+
Args:
|
|
211
|
+
ctx: Click context.
|
|
212
|
+
bind_key: Specific bind key to target.
|
|
213
|
+
include: Config names to include.
|
|
214
|
+
exclude: Config names to exclude.
|
|
215
|
+
dry_run: Whether this is a dry run.
|
|
216
|
+
operation_name: Name of the operation for display.
|
|
217
|
+
|
|
218
|
+
Returns:
|
|
219
|
+
List of (config_name, config) tuples to process, or None for single config mode.
|
|
220
|
+
"""
|
|
221
|
+
# If specific bind_key requested, use single config mode
|
|
222
|
+
if bind_key and not include and not exclude:
|
|
223
|
+
return None
|
|
224
|
+
|
|
225
|
+
# Get enabled configs by default, all configs if include/exclude specified
|
|
226
|
+
enabled_only = not include and not exclude
|
|
227
|
+
migration_configs = get_configs_with_migrations(ctx, enabled_only=enabled_only)
|
|
228
|
+
|
|
229
|
+
# If only one config and no filtering, use single config mode
|
|
230
|
+
if len(migration_configs) <= 1 and not include and not exclude:
|
|
231
|
+
return None
|
|
232
|
+
|
|
233
|
+
# Apply filtering
|
|
234
|
+
configs_to_process = filter_configs(migration_configs, include, exclude)
|
|
235
|
+
|
|
236
|
+
if not configs_to_process:
|
|
237
|
+
console.print("[yellow]No configurations match the specified criteria.[/]")
|
|
238
|
+
return []
|
|
239
|
+
|
|
240
|
+
# Show what will be processed
|
|
241
|
+
if dry_run:
|
|
242
|
+
console.print(f"[blue]Dry run: Would {operation_name} {len(configs_to_process)} configuration(s)[/]")
|
|
243
|
+
for config_name, _ in configs_to_process:
|
|
244
|
+
console.print(f" • {config_name}")
|
|
245
|
+
return []
|
|
246
|
+
|
|
247
|
+
return configs_to_process
|
|
248
|
+
|
|
249
|
+
@database_group.command(name="show-current-revision", help="Shows the current revision for the database.")
|
|
250
|
+
@bind_key_option
|
|
251
|
+
@verbose_option
|
|
252
|
+
@include_option
|
|
253
|
+
@exclude_option
|
|
254
|
+
def show_database_revision( # pyright: ignore[reportUnusedFunction]
|
|
255
|
+
bind_key: Optional[str], verbose: bool, include: "tuple[str, ...]", exclude: "tuple[str, ...]"
|
|
256
|
+
) -> None:
|
|
257
|
+
"""Show current database revision."""
|
|
258
|
+
from sqlspec.migrations.commands import MigrationCommands
|
|
259
|
+
|
|
260
|
+
ctx = click.get_current_context()
|
|
261
|
+
|
|
262
|
+
# Check if this is a multi-config operation
|
|
263
|
+
configs_to_process = process_multiple_configs(
|
|
264
|
+
ctx, bind_key, include, exclude, dry_run=False, operation_name="show current revision"
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
if configs_to_process is not None:
|
|
268
|
+
if not configs_to_process:
|
|
269
|
+
return
|
|
270
|
+
|
|
271
|
+
console.rule("[yellow]Listing current revisions for all configurations[/]", align="left")
|
|
272
|
+
|
|
273
|
+
for config_name, config in configs_to_process:
|
|
274
|
+
console.print(f"\n[blue]Configuration: {config_name}[/]")
|
|
275
|
+
try:
|
|
276
|
+
migration_commands = MigrationCommands(config=config)
|
|
277
|
+
migration_commands.current(verbose=verbose)
|
|
278
|
+
except Exception as e:
|
|
279
|
+
console.print(f"[red]✗ Failed to get current revision for {config_name}: {e}[/]")
|
|
280
|
+
else:
|
|
281
|
+
# Single config operation
|
|
282
|
+
console.rule("[yellow]Listing current revision[/]", align="left")
|
|
283
|
+
sqlspec_config = get_config_by_bind_key(ctx, bind_key)
|
|
284
|
+
migration_commands = MigrationCommands(config=sqlspec_config)
|
|
285
|
+
migration_commands.current(verbose=verbose)
|
|
286
|
+
|
|
287
|
+
@database_group.command(name="downgrade", help="Downgrade database to a specific revision.")
|
|
288
|
+
@bind_key_option
|
|
289
|
+
@no_prompt_option
|
|
290
|
+
@include_option
|
|
291
|
+
@exclude_option
|
|
292
|
+
@dry_run_option
|
|
293
|
+
@click.argument("revision", type=str, default="-1")
|
|
294
|
+
def downgrade_database( # pyright: ignore[reportUnusedFunction]
|
|
295
|
+
bind_key: Optional[str],
|
|
296
|
+
revision: str,
|
|
297
|
+
no_prompt: bool,
|
|
298
|
+
include: "tuple[str, ...]",
|
|
299
|
+
exclude: "tuple[str, ...]",
|
|
300
|
+
dry_run: bool,
|
|
301
|
+
) -> None:
|
|
302
|
+
"""Downgrade the database to the latest revision."""
|
|
303
|
+
from rich.prompt import Confirm
|
|
304
|
+
|
|
305
|
+
from sqlspec.migrations.commands import MigrationCommands
|
|
306
|
+
|
|
307
|
+
ctx = click.get_current_context()
|
|
308
|
+
|
|
309
|
+
# Check if this is a multi-config operation
|
|
310
|
+
configs_to_process = process_multiple_configs(
|
|
311
|
+
ctx, bind_key, include, exclude, dry_run=dry_run, operation_name=f"downgrade to {revision}"
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
if configs_to_process is not None:
|
|
315
|
+
if not configs_to_process:
|
|
316
|
+
return
|
|
317
|
+
|
|
318
|
+
if not no_prompt and not Confirm.ask(
|
|
319
|
+
f"[bold]Are you sure you want to downgrade {len(configs_to_process)} configuration(s) to revision {revision}?[/]"
|
|
320
|
+
):
|
|
321
|
+
console.print("[yellow]Operation cancelled.[/]")
|
|
322
|
+
return
|
|
323
|
+
|
|
324
|
+
console.rule("[yellow]Starting multi-configuration downgrade process[/]", align="left")
|
|
325
|
+
|
|
326
|
+
for config_name, config in configs_to_process:
|
|
327
|
+
console.print(f"[blue]Downgrading configuration: {config_name}[/]")
|
|
328
|
+
try:
|
|
329
|
+
migration_commands = MigrationCommands(config=config)
|
|
330
|
+
migration_commands.downgrade(revision=revision)
|
|
331
|
+
console.print(f"[green]✓ Successfully downgraded: {config_name}[/]")
|
|
332
|
+
except Exception as e:
|
|
333
|
+
console.print(f"[red]✗ Failed to downgrade {config_name}: {e}[/]")
|
|
334
|
+
else:
|
|
335
|
+
# Single config operation
|
|
336
|
+
console.rule("[yellow]Starting database downgrade process[/]", align="left")
|
|
337
|
+
input_confirmed = (
|
|
338
|
+
True
|
|
339
|
+
if no_prompt
|
|
340
|
+
else Confirm.ask(f"Are you sure you want to downgrade the database to the `{revision}` revision?")
|
|
341
|
+
)
|
|
342
|
+
if input_confirmed:
|
|
343
|
+
sqlspec_config = get_config_by_bind_key(ctx, bind_key)
|
|
344
|
+
migration_commands = MigrationCommands(config=sqlspec_config)
|
|
345
|
+
migration_commands.downgrade(revision=revision)
|
|
346
|
+
|
|
347
|
+
@database_group.command(name="upgrade", help="Upgrade database to a specific revision.")
|
|
348
|
+
@bind_key_option
|
|
349
|
+
@no_prompt_option
|
|
350
|
+
@include_option
|
|
351
|
+
@exclude_option
|
|
352
|
+
@dry_run_option
|
|
353
|
+
@click.argument("revision", type=str, default="head")
|
|
354
|
+
def upgrade_database( # pyright: ignore[reportUnusedFunction]
|
|
355
|
+
bind_key: Optional[str],
|
|
356
|
+
revision: str,
|
|
357
|
+
no_prompt: bool,
|
|
358
|
+
include: "tuple[str, ...]",
|
|
359
|
+
exclude: "tuple[str, ...]",
|
|
360
|
+
dry_run: bool,
|
|
361
|
+
) -> None:
|
|
362
|
+
"""Upgrade the database to the latest revision."""
|
|
363
|
+
from rich.prompt import Confirm
|
|
364
|
+
|
|
365
|
+
from sqlspec.migrations.commands import MigrationCommands
|
|
366
|
+
|
|
367
|
+
ctx = click.get_current_context()
|
|
368
|
+
|
|
369
|
+
# Check if this is a multi-config operation
|
|
370
|
+
configs_to_process = process_multiple_configs(
|
|
371
|
+
ctx, bind_key, include, exclude, dry_run, operation_name=f"upgrade to {revision}"
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
if configs_to_process is not None:
|
|
375
|
+
if not configs_to_process:
|
|
376
|
+
return
|
|
377
|
+
|
|
378
|
+
if not no_prompt and not Confirm.ask(
|
|
379
|
+
f"[bold]Are you sure you want to upgrade {len(configs_to_process)} configuration(s) to revision {revision}?[/]"
|
|
380
|
+
):
|
|
381
|
+
console.print("[yellow]Operation cancelled.[/]")
|
|
382
|
+
return
|
|
383
|
+
|
|
384
|
+
console.rule("[yellow]Starting multi-configuration upgrade process[/]", align="left")
|
|
385
|
+
|
|
386
|
+
for config_name, config in configs_to_process:
|
|
387
|
+
console.print(f"[blue]Upgrading configuration: {config_name}[/]")
|
|
388
|
+
try:
|
|
389
|
+
migration_commands = MigrationCommands(config=config)
|
|
390
|
+
migration_commands.upgrade(revision=revision)
|
|
391
|
+
console.print(f"[green]✓ Successfully upgraded: {config_name}[/]")
|
|
392
|
+
except Exception as e:
|
|
393
|
+
console.print(f"[red]✗ Failed to upgrade {config_name}: {e}[/]")
|
|
394
|
+
else:
|
|
395
|
+
# Single config operation
|
|
396
|
+
console.rule("[yellow]Starting database upgrade process[/]", align="left")
|
|
397
|
+
input_confirmed = (
|
|
398
|
+
True
|
|
399
|
+
if no_prompt
|
|
400
|
+
else Confirm.ask(f"[bold]Are you sure you want migrate the database to the `{revision}` revision?[/]")
|
|
401
|
+
)
|
|
402
|
+
if input_confirmed:
|
|
403
|
+
sqlspec_config = get_config_by_bind_key(ctx, bind_key)
|
|
404
|
+
migration_commands = MigrationCommands(config=sqlspec_config)
|
|
405
|
+
migration_commands.upgrade(revision=revision)
|
|
406
|
+
|
|
407
|
+
@database_group.command(help="Stamp the revision table with the given revision")
|
|
408
|
+
@click.argument("revision", type=str)
|
|
409
|
+
@bind_key_option
|
|
410
|
+
def stamp(bind_key: Optional[str], revision: str) -> None: # pyright: ignore[reportUnusedFunction]
|
|
411
|
+
"""Stamp the revision table with the given revision."""
|
|
412
|
+
from sqlspec.migrations.commands import MigrationCommands
|
|
413
|
+
|
|
414
|
+
ctx = click.get_current_context()
|
|
415
|
+
sqlspec_config = get_config_by_bind_key(ctx, bind_key)
|
|
416
|
+
migration_commands = MigrationCommands(config=sqlspec_config)
|
|
417
|
+
migration_commands.stamp(revision=revision)
|
|
418
|
+
|
|
419
|
+
@database_group.command(name="init", help="Initialize migrations for the project.")
|
|
420
|
+
@bind_key_option
|
|
421
|
+
@click.argument("directory", default=None, required=False)
|
|
422
|
+
@click.option("--package", is_flag=True, default=True, help="Create `__init__.py` for created folder")
|
|
423
|
+
@no_prompt_option
|
|
424
|
+
def init_sqlspec( # pyright: ignore[reportUnusedFunction]
|
|
425
|
+
bind_key: Optional[str], directory: Optional[str], package: bool, no_prompt: bool
|
|
426
|
+
) -> None:
|
|
427
|
+
"""Initialize the database migrations."""
|
|
428
|
+
from rich.prompt import Confirm
|
|
429
|
+
|
|
430
|
+
from sqlspec.migrations.commands import MigrationCommands
|
|
431
|
+
|
|
432
|
+
ctx = click.get_current_context()
|
|
433
|
+
console.rule("[yellow]Initializing database migrations.", align="left")
|
|
434
|
+
input_confirmed = (
|
|
435
|
+
True if no_prompt else Confirm.ask("[bold]Are you sure you want initialize migrations for the project?[/]")
|
|
436
|
+
)
|
|
437
|
+
if input_confirmed:
|
|
438
|
+
configs = [get_config_by_bind_key(ctx, bind_key)] if bind_key is not None else ctx.obj["configs"]
|
|
439
|
+
from sqlspec.extensions.litestar.config import DatabaseConfig
|
|
440
|
+
|
|
441
|
+
for config in configs:
|
|
442
|
+
# Extract the actual config from DatabaseConfig wrapper if needed
|
|
443
|
+
actual_config = config.config if isinstance(config, DatabaseConfig) else config
|
|
444
|
+
migration_config = getattr(actual_config, "migration_config", {})
|
|
445
|
+
directory = migration_config.get("script_location", "migrations") if directory is None else directory
|
|
446
|
+
migration_commands = MigrationCommands(config=actual_config)
|
|
447
|
+
migration_commands.init(directory=cast("str", directory), package=package)
|
|
448
|
+
|
|
449
|
+
@database_group.command(name="make-migrations", help="Create a new migration revision.")
|
|
450
|
+
@bind_key_option
|
|
451
|
+
@click.option("-m", "--message", default=None, help="Revision message")
|
|
452
|
+
@no_prompt_option
|
|
453
|
+
def create_revision( # pyright: ignore[reportUnusedFunction]
|
|
454
|
+
bind_key: Optional[str], message: Optional[str], no_prompt: bool
|
|
455
|
+
) -> None:
|
|
456
|
+
"""Create a new database revision."""
|
|
457
|
+
from rich.prompt import Prompt
|
|
458
|
+
|
|
459
|
+
from sqlspec.migrations.commands import MigrationCommands
|
|
460
|
+
|
|
461
|
+
ctx = click.get_current_context()
|
|
462
|
+
console.rule("[yellow]Creating new migration revision[/]", align="left")
|
|
463
|
+
if message is None:
|
|
464
|
+
message = "new migration" if no_prompt else Prompt.ask("Please enter a message describing this revision")
|
|
465
|
+
|
|
466
|
+
sqlspec_config = get_config_by_bind_key(ctx, bind_key)
|
|
467
|
+
migration_commands = MigrationCommands(config=sqlspec_config)
|
|
468
|
+
migration_commands.revision(message=message)
|
|
469
|
+
|
|
470
|
+
@database_group.command(name="show-config", help="Show all configurations with migrations enabled.")
|
|
471
|
+
def show_config() -> None: # pyright: ignore[reportUnusedFunction]
|
|
472
|
+
"""Show and display all configurations with migrations enabled."""
|
|
473
|
+
from rich.table import Table
|
|
474
|
+
|
|
475
|
+
ctx = click.get_current_context()
|
|
476
|
+
migration_configs = get_configs_with_migrations(ctx)
|
|
477
|
+
|
|
478
|
+
if not migration_configs:
|
|
479
|
+
console.print("[yellow]No configurations with migrations detected.[/]")
|
|
480
|
+
return
|
|
481
|
+
|
|
482
|
+
table = Table(title="Migration Configurations")
|
|
483
|
+
table.add_column("Configuration Name", style="cyan")
|
|
484
|
+
table.add_column("Migration Path", style="blue")
|
|
485
|
+
table.add_column("Status", style="green")
|
|
486
|
+
|
|
487
|
+
for config_name, config in migration_configs:
|
|
488
|
+
migration_config = getattr(config, "migration_config", {})
|
|
489
|
+
script_location = migration_config.get("script_location", "migrations")
|
|
490
|
+
table.add_row(config_name, script_location, "Migration Enabled")
|
|
491
|
+
|
|
492
|
+
console.print(table)
|
|
493
|
+
console.print(f"[blue]Found {len(migration_configs)} configuration(s) with migrations enabled.[/]")
|
|
494
|
+
|
|
495
|
+
return database_group
|