dblift 2.5.2__tar.gz → 2.6.1__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.
- {dblift-2.5.2 → dblift-2.6.1}/PKG-INFO +69 -7
- {dblift-2.5.2 → dblift-2.6.1}/README.md +65 -6
- {dblift-2.5.2 → dblift-2.6.1}/cli/_command_handlers.py +26 -0
- {dblift-2.5.2 → dblift-2.6.1}/cli/_constants.py +6 -0
- {dblift-2.5.2 → dblift-2.6.1}/cli/_parser_setup.py +30 -0
- {dblift-2.5.2 → dblift-2.6.1}/cli/main.py +14 -0
- dblift-2.6.1/cli/premium_manifest.py +101 -0
- dblift-2.6.1/db/plugins/_pg_compatible.py +150 -0
- dblift-2.6.1/db/plugins/alloydb/__init__.py +12 -0
- dblift-2.6.1/db/plugins/alloydb/plugin.py +18 -0
- dblift-2.6.1/db/plugins/aurora_postgresql/__init__.py +12 -0
- dblift-2.6.1/db/plugins/aurora_postgresql/plugin.py +18 -0
- dblift-2.6.1/db/plugins/citus/__init__.py +12 -0
- dblift-2.6.1/db/plugins/citus/plugin.py +18 -0
- dblift-2.6.1/db/plugins/neon/__init__.py +12 -0
- dblift-2.6.1/db/plugins/neon/plugin.py +18 -0
- dblift-2.6.1/db/plugins/snowflake/__init__.py +12 -0
- dblift-2.6.1/db/plugins/snowflake/config.py +67 -0
- dblift-2.6.1/db/plugins/snowflake/plugin.py +22 -0
- dblift-2.6.1/db/plugins/snowflake/provider.py +449 -0
- dblift-2.6.1/db/plugins/snowflake/quirks.py +70 -0
- dblift-2.6.1/db/plugins/snowflake/sqlalchemy_url.py +83 -0
- dblift-2.6.1/db/plugins/supabase/__init__.py +12 -0
- dblift-2.6.1/db/plugins/supabase/plugin.py +18 -0
- dblift-2.6.1/db/plugins/timescaledb/__init__.py +12 -0
- dblift-2.6.1/db/plugins/timescaledb/plugin.py +18 -0
- dblift-2.6.1/db/plugins/yugabytedb/__init__.py +12 -0
- dblift-2.6.1/db/plugins/yugabytedb/plugin.py +18 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/provider_registry.py +62 -48
- {dblift-2.5.2 → dblift-2.6.1}/dblift.egg-info/PKG-INFO +69 -7
- {dblift-2.5.2 → dblift-2.6.1}/dblift.egg-info/SOURCES.txt +8 -14
- {dblift-2.5.2 → dblift-2.6.1}/dblift.egg-info/entry_points.txt +1 -0
- {dblift-2.5.2 → dblift-2.6.1}/dblift.egg-info/requires.txt +4 -0
- {dblift-2.5.2 → dblift-2.6.1}/pyproject.toml +7 -2
- dblift-2.5.2/db/plugins/alloydb/__init__.py +0 -12
- dblift-2.5.2/db/plugins/alloydb/plugin.py +0 -28
- dblift-2.5.2/db/plugins/alloydb/provider.py +0 -14
- dblift-2.5.2/db/plugins/alloydb/quirks.py +0 -32
- dblift-2.5.2/db/plugins/aurora_postgresql/__init__.py +0 -12
- dblift-2.5.2/db/plugins/aurora_postgresql/plugin.py +0 -28
- dblift-2.5.2/db/plugins/aurora_postgresql/provider.py +0 -14
- dblift-2.5.2/db/plugins/aurora_postgresql/quirks.py +0 -32
- dblift-2.5.2/db/plugins/citus/__init__.py +0 -12
- dblift-2.5.2/db/plugins/citus/plugin.py +0 -28
- dblift-2.5.2/db/plugins/citus/provider.py +0 -14
- dblift-2.5.2/db/plugins/citus/quirks.py +0 -32
- dblift-2.5.2/db/plugins/neon/__init__.py +0 -12
- dblift-2.5.2/db/plugins/neon/plugin.py +0 -28
- dblift-2.5.2/db/plugins/neon/provider.py +0 -14
- dblift-2.5.2/db/plugins/neon/quirks.py +0 -32
- dblift-2.5.2/db/plugins/supabase/__init__.py +0 -12
- dblift-2.5.2/db/plugins/supabase/plugin.py +0 -28
- dblift-2.5.2/db/plugins/supabase/provider.py +0 -14
- dblift-2.5.2/db/plugins/supabase/quirks.py +0 -32
- dblift-2.5.2/db/plugins/timescaledb/__init__.py +0 -12
- dblift-2.5.2/db/plugins/timescaledb/plugin.py +0 -28
- dblift-2.5.2/db/plugins/timescaledb/provider.py +0 -14
- dblift-2.5.2/db/plugins/timescaledb/quirks.py +0 -32
- dblift-2.5.2/db/plugins/yugabytedb/__init__.py +0 -12
- dblift-2.5.2/db/plugins/yugabytedb/plugin.py +0 -28
- dblift-2.5.2/db/plugins/yugabytedb/provider.py +0 -14
- dblift-2.5.2/db/plugins/yugabytedb/quirks.py +0 -32
- {dblift-2.5.2 → dblift-2.6.1}/LICENSE +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/api/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/api/_cli_support.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/api/_client_factory.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/api/_client_operations.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/api/_engine_config.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/api/async_client.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/api/client.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/api/events.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/api/migrations.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/api/py.typed +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/cli/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/cli/_config_helpers.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/cli/_output.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/cli/commands/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/cli/commands/config_command.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/cli/db_utils.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/cli/extensions.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/cli/handlers/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/cli/handlers/_shared.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/cli/handlers/baseline.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/cli/handlers/clean.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/cli/handlers/import_flyway.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/cli/handlers/info.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/cli/handlers/migrate.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/cli/handlers/repair.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/cli/handlers/undo.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/cli/handlers/validate.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/config/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/config/_credential_masking.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/config/_subclasses/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/config/_subclasses/dummy_config.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/config/_url_builder_mixin.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/config/config_builder.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/config/database_config.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/config/dblift_config.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/config/errors.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/config/property_registry.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/config/secrets/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/config/secrets/_cache.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/config/secrets/_provider_base.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/config/secrets/_registry.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/config/secrets/_resolver.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/config/secrets/_secrets_config.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/constants.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/dialect_boundary.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/exceptions.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/_column_enricher.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/_partition_enricher.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/_schema_orchestrator.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/_utils.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/_vendor_property_applier.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/base_introspector.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/extractors/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/extractors/base_extractor.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/extractors/column_extractor.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/extractors/constraint_extractor.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/extractors/index_extractor.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/extractors/misc_extractor.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/extractors/procedure_extractor.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/extractors/sequence_extractor.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/extractors/table_extractor.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/extractors/trigger_extractor.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/extractors/view_extractor.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/introspector_factory.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/result.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/schema_introspector.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/vendor_queries_base.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/vendor_queries_factory.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/vendor_queries_protocols.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/introspection/version_detector.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/logger/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/logger/_base.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/logger/_factory.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/logger/_formatters.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/logger/_levels.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/logger/_multi.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/logger/_null.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/logger/console.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/logger/formatters/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/logger/formatters/_formatter_impl.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/logger/formatters/factory.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/logger/formatters/formatter.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/logger/formatters/htmlformatter.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/logger/formatters/jsonformatter.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/logger/log.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/logger/results.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/logger/templates/oldreport.html +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/logger/templates/report.html +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/_type_match.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/clean_summary.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/commands/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/commands/_script_events.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/commands/base_command.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/commands/baseline_command.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/commands/clean_command.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/commands/import_flyway_command.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/commands/info_command.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/commands/migrate_command.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/commands/repair_command.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/commands/undo_command.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/commands/validate_command.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/encoding.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/executor/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/executor/execution_engine.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/executor/migration_executor.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/executor/migration_helpers.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/executor/placeholder_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/executor/transaction_policy.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/executors/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/executors/base_executor.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/executors/executor_factory.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/executors/python_executor.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/executors/sql_executor.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/formats/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/formats/format_detector.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/formats/migration_format.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/history/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/history/migration_history_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/journals/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/journals/migration_journal.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/migration.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/placeholders/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/placeholders/placeholder_service.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/rules/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/rules/migration_rules.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/scripting/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/scripting/migration_script_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/scripting/undo_script_generator/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/scripting/undo_script_generator/_ddl_reversers.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/scripting/undo_script_generator/_dml_reversers.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/scripting/undo_script_generator/_extractors.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/scripting/undo_script_generator/_generator.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/scripting/undo_script_generator/_helpers.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/scripting/undo_script_generator/_models.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/scripting/undo_script_generator/_reversers.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/sql/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/sql/execution_statement.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/sql/sql_analyzer.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/sql/sql_execution_service.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/sql/statement_splitter.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/state/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/state/migration_data_service.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/state/migration_display_state.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/state/migration_formatter.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/state/migration_state.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/state/migration_state_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/state/migration_state_service.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/ui/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/ui/data_collector.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/ui/display_formatters.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/ui/migration_analyzer.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/ui/migration_ui.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/ui/table_renderer.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/migration/version_utils.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/normalization/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/normalization/dependency_resolver.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/normalization/identifier_normalizer.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/normalization/object_orderer.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/normalization/type_constants.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/normalization/type_mapper.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/normalization/type_mappings.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/normalization/type_normalizer.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/seams/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/seams/capabilities.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/seams/event_listeners.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/seams/feature_loading.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/seams/introspection.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/seams/license_info.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/seams/runtime_checks.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/seams/sql_generators.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/seams/tier_resolver.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_generator/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_generator/alter/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_generator/alter/alter_generator_factory.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_generator/alter/base_alter_generator.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_generator/alter_generator.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_generator/base_generator.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_generator/basic_table_ddl_generator.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_generator/dependency_analyzer.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_generator/diff_converters/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_generator/diff_converters/base_converter.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_generator/formatter.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_generator/generator_factory.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_generator/options.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_generator/script_organizer.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_generator/sql_generator.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_generator/sql_statement.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_generator/table_ddl_render.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/_base_parse_result.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/_base_sql_column.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/_base_sql_constraint.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/_base_sql_object.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/_base_sql_statement.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/base.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/constraint_validator.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/database_link.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/dialect.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/event.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/extension.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/foreign_data_wrapper.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/foreign_server.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/index.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/linked_server.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/module.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/package.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/partition.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/procedure.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/sequence.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/synonym.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/table.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/table_canonicalizer.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/table_options.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/trigger.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/user_defined_type.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/view.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_model/view_options.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_parser/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_parser/_partition_handler.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_parser/_sqlglot_builders.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_parser/base_statement_parser.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_parser/base_tokenizer.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_parser/common/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_parser/common/base_parser.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_parser/dialects/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_parser/dialects/base_config.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_parser/enhanced_regex_parser.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_parser/hybrid_parser.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_parser/parser_context.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_parser/parser_factory.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_parser/parser_interface.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_parser/sqlglot_parser.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_parser/tokens.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_parser/unified_regex_parser.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_validator/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_validator/_checksum_validator.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_validator/_flyway_compatibility.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_validator/_migration_filter.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_validator/_sql_syntax_validator.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_validator/_strict_mode_validator.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/sql_validator/migration_validator.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/state/sql_script_formatter.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/state/sql_statement.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/utils/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/utils/database_url_parser.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/utils/metadata_helpers.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/utils/row_access.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/utils/string_utils.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/core/utils/url_masking.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/base_provider.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/base_quirks.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/constants.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/dml_analysis.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/error.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/error_handler.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/exceptions.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/native_connection_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/object_naming.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/base_history_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/base_locking_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/base_query_executor.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/base_schema_operations.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/base_snapshot_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/base_undo_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cockroachdb/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cockroachdb/plugin.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cockroachdb/provider.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cockroachdb/quirks.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/config.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/cosmosdb/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/cosmosdb/_sdk.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/cosmosdb/connection_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/cosmosdb/history_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/cosmosdb/locking_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/cosmosdb/query_executor.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/cosmosdb/schema_operations.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/introspection/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/parser/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/parser/cosmosdb_regex_parser.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/plugin.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/provider.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/quirks.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/sdk_translator/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/sdk_translator/_executor.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/sdk_translator/_executors.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/sdk_translator/_parsing.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/sdk_translator/_script_generation.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/sdk_translator/_translator.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/cosmosdb/sdk_translator/_translators.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/db2/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/db2/config.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/db2/db2/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/db2/db2/history_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/db2/db2/locking_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/db2/db2/schema_operations.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/db2/introspection/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/db2/parser/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/db2/parser/db2_regex_parser.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/db2/parser/parser_config.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/db2/plugin.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/db2/provider.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/db2/quirks.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/db2/sqlalchemy_url.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/duckdb/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/duckdb/config.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/duckdb/parser/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/duckdb/parser/duckdb_regex_parser.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/duckdb/parser/parser_config.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/duckdb/plugin.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/duckdb/provider.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/duckdb/quirks.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/duckdb/sqlalchemy_url.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/mariadb/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/mariadb/plugin.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/mariadb/provider.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/mariadb/quirks.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/mysql/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/mysql/config.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/mysql/introspection/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/mysql/mysql/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/mysql/mysql/history_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/mysql/mysql/locking_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/mysql/mysql/schema_operations.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/mysql/parser/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/mysql/parser/mysql_regex_parser.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/mysql/parser/mysql_statement_parser.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/mysql/parser/mysql_tokenizer.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/mysql/parser/parser_config.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/mysql/plugin.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/mysql/provider.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/mysql/quirks.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/mysql/sqlalchemy_url.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/config.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/introspection/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/introspection/oracle_utils.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/oracle/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/oracle/dbms_output.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/oracle/history_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/oracle/locking_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/oracle/schema_operations.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/parser/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/parser/_comments.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/parser/_object_extractor.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/parser/_plsql_block.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/parser/_sqlplus.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/parser/_statement_splitter.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/parser/oracle_parser.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/parser/oracle_statement_parser.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/parser/oracle_tokenizer.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/parser/parser_config.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/parser/sqlplus_context.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/plugin.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/provider.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/quirks.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/oracle/sqlalchemy_url.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/postgresql/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/postgresql/_provider_query_executor.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/postgresql/config.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/postgresql/introspection/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/postgresql/parser/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/postgresql/parser/parser_config.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/postgresql/parser/postgresql_regex_parser.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/postgresql/parser/postgresql_statement_parser.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/postgresql/parser/postgresql_tokenizer.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/postgresql/plugin.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/postgresql/postgresql/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/postgresql/postgresql/history_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/postgresql/postgresql/locking_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/postgresql/postgresql/schema_operations.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/postgresql/provider.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/postgresql/quirks.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/postgresql/sqlalchemy_url.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/redshift/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/redshift/plugin.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/redshift/provider.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/redshift/quirks.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/redshift/sqlalchemy_url.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlite/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlite/config.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlite/introspection/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlite/parser/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlite/parser/parser_config.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlite/parser/sqlite_regex_parser.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlite/plugin.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlite/provider.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlite/quirks.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlite/sqlalchemy_url.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlite/sqlite/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlite/sqlite/connection_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlite/sqlite/history_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlite/sqlite/locking_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlite/sqlite/query_executor.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlite/sqlite/schema_operations.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlserver/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlserver/config.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlserver/introspection/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlserver/parser/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlserver/parser/parser_config.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlserver/parser/sqlserver_regex_parser.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlserver/parser/sqlserver_statement_parser.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlserver/parser/sqlserver_tokenizer.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlserver/parser/tsql_batch_separator.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlserver/plugin.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlserver/provider.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlserver/quirks.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlserver/sqlalchemy_url.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlserver/sqlserver/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlserver/sqlserver/history_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlserver/sqlserver/locking_manager.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/plugins/sqlserver/sqlserver/schema_operations.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/provider_capabilities.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/provider_interfaces.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/sqlalchemy_provider.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/db/value_utils.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/dblift.egg-info/dependency_links.txt +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/dblift.egg-info/top_level.txt +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/integrations/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/integrations/django/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/integrations/django/_client.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/integrations/django/_engine.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/integrations/django/apps.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/integrations/django/checks.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/integrations/django/management/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/integrations/django/management/commands/__init__.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/integrations/django/management/commands/dblift_info.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/integrations/django/management/commands/dblift_migrate.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/integrations/django/management/commands/dblift_validate.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/integrations/fastapi.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/integrations/flask.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/integrations/opentelemetry.py +0 -0
- {dblift-2.5.2 → dblift-2.6.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dblift
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.6.1
|
|
4
4
|
Summary: A database migration tool that supports multiple databases with native Python drivers
|
|
5
5
|
Classifier: Development Status :: 5 - Production/Stable
|
|
6
6
|
Classifier: Intended Audience :: Developers
|
|
@@ -46,6 +46,7 @@ Requires-Dist: types-PyYAML>=6.0.12.12; extra == "dev"
|
|
|
46
46
|
Requires-Dist: types-setuptools; extra == "dev"
|
|
47
47
|
Requires-Dist: pre-commit>=4.0.0; extra == "dev"
|
|
48
48
|
Requires-Dist: Cython>=3.0.0; extra == "dev"
|
|
49
|
+
Requires-Dist: setuptools>=83.0.0; extra == "dev"
|
|
49
50
|
Requires-Dist: bandit>=1.7.9; extra == "dev"
|
|
50
51
|
Requires-Dist: pip-audit>=2.7.3; extra == "dev"
|
|
51
52
|
Requires-Dist: radon>=6.0.1; extra == "dev"
|
|
@@ -88,6 +89,8 @@ Requires-Dist: psycopg[binary]>=3.1; extra == "cockroachdb"
|
|
|
88
89
|
Provides-Extra: redshift
|
|
89
90
|
Requires-Dist: sqlalchemy-redshift>=1.0.0; extra == "redshift"
|
|
90
91
|
Requires-Dist: redshift-connector>=2.1.0; extra == "redshift"
|
|
92
|
+
Provides-Extra: snowflake
|
|
93
|
+
Requires-Dist: snowflake-sqlalchemy>=1.11.0; extra == "snowflake"
|
|
91
94
|
Provides-Extra: fastapi
|
|
92
95
|
Requires-Dist: fastapi>=0.100; extra == "fastapi"
|
|
93
96
|
Provides-Extra: flask
|
|
@@ -444,15 +447,26 @@ def migrate(context: MigrationContext) -> None:
|
|
|
444
447
|
f"INSERT INTO {schema_prefix}roles (code, label) VALUES (?, ?)",
|
|
445
448
|
[code, label],
|
|
446
449
|
)
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
> **Undo is a separate script, not a function.** DBLift does not call an
|
|
453
|
+
> `undo()` function inside a `V*.py` migration. To make a Python migration
|
|
454
|
+
> reversible, add a companion undo script `U2__seed_lookup_tables.py` that
|
|
455
|
+
> exposes its own `migrate(context)` performing the reverse change — exactly
|
|
456
|
+
> like the `U*.sql` undo files described in
|
|
457
|
+
> [Rolling Back Changes](#rolling-back-changes). `dblift undo` runs that
|
|
458
|
+
> companion script; the `Undoable` column in `dblift info` reflects whether a
|
|
459
|
+
> matching `U*` file exists.
|
|
447
460
|
|
|
448
|
-
|
|
449
|
-
|
|
461
|
+
```python
|
|
462
|
+
# migrations/U2__seed_lookup_tables.py (undo companion for V2)
|
|
463
|
+
from api import MigrationContext
|
|
464
|
+
|
|
465
|
+
def migrate(context: MigrationContext) -> None:
|
|
466
|
+
"""Reverse V2 by removing the seeded lookup rows."""
|
|
450
467
|
if context.dry_run:
|
|
451
468
|
return
|
|
452
|
-
context.execute(
|
|
453
|
-
"DELETE FROM roles WHERE code IN (?, ?)",
|
|
454
|
-
["admin", "user"],
|
|
455
|
-
)
|
|
469
|
+
context.execute("DELETE FROM roles WHERE code IN (?, ?)", ["admin", "user"])
|
|
456
470
|
```
|
|
457
471
|
|
|
458
472
|
---
|
|
@@ -725,6 +739,53 @@ migrations:
|
|
|
725
739
|
recursive: false # Dict format (per-directory setting)
|
|
726
740
|
```
|
|
727
741
|
|
|
742
|
+
### Configuration Sources and Precedence
|
|
743
|
+
|
|
744
|
+
The `dblift.yaml` file is only one of three ways to supply configuration. Every
|
|
745
|
+
setting can also be passed as a **command-line flag** or an **environment
|
|
746
|
+
variable**, which is convenient for CI pipelines and for keeping secrets out of
|
|
747
|
+
files. When the same setting comes from more than one source, the higher-priority
|
|
748
|
+
source wins:
|
|
749
|
+
|
|
750
|
+
```
|
|
751
|
+
command-line flag > environment variable > dblift.yaml > values embedded in the database URL
|
|
752
|
+
```
|
|
753
|
+
|
|
754
|
+
The database connection settings are the most common to override:
|
|
755
|
+
|
|
756
|
+
| Setting | `dblift.yaml` key | Environment variable | CLI flag |
|
|
757
|
+
|---------|-------------------|----------------------|----------|
|
|
758
|
+
| Connection URL | `database.url` | `DBLIFT_DB_URL` | `--db-url` |
|
|
759
|
+
| Username | `database.username` | `DBLIFT_DB_USERNAME` | `--db-username` |
|
|
760
|
+
| Password | `database.password` | `DBLIFT_DB_PASSWORD` | `--db-password` |
|
|
761
|
+
| Schema | `database.schema` | `DBLIFT_DB_SCHEMA` | `--db-schema` |
|
|
762
|
+
| Scripts directory | `migrations.directory` | — | `--scripts` |
|
|
763
|
+
| Strict ordering | `strict_mode` (top level) | `DBLIFT_STRICT_MODE` | `--strict` |
|
|
764
|
+
|
|
765
|
+
For example, the same run configured three ways:
|
|
766
|
+
|
|
767
|
+
```bash
|
|
768
|
+
# 1. Everything from dblift.yaml
|
|
769
|
+
dblift migrate
|
|
770
|
+
|
|
771
|
+
# 2. Connection from the environment (nothing sensitive on disk)
|
|
772
|
+
export DBLIFT_DB_URL="postgresql+psycopg://localhost:5432/mydb"
|
|
773
|
+
export DBLIFT_DB_PASSWORD="s3cret"
|
|
774
|
+
dblift migrate
|
|
775
|
+
|
|
776
|
+
# 3. Overriding a file-based config on the command line (e.g. targeting staging)
|
|
777
|
+
dblift migrate --db-url "postgresql+psycopg://staging:5432/mydb" --scripts ./migrations
|
|
778
|
+
```
|
|
779
|
+
|
|
780
|
+
Non-database settings follow the same pattern: the environment variable is the
|
|
781
|
+
setting name upper-cased with a `DBLIFT_` prefix (for example `--installed-by` ↔
|
|
782
|
+
`DBLIFT_INSTALLED_BY`). For the authoritative, always-current list of every
|
|
783
|
+
setting and its three surfaces, run:
|
|
784
|
+
|
|
785
|
+
```bash
|
|
786
|
+
dblift config --list
|
|
787
|
+
```
|
|
788
|
+
|
|
728
789
|
### Supported Databases
|
|
729
790
|
|
|
730
791
|
DBLift works with these databases:
|
|
@@ -734,6 +795,7 @@ DBLift works with these databases:
|
|
|
734
795
|
| PostgreSQL | `postgresql+psycopg://localhost:5432/mydb` | `dblift[postgresql]` |
|
|
735
796
|
| CockroachDB | `postgresql+psycopg://localhost:26257/mydb` | `dblift[cockroachdb]` |
|
|
736
797
|
| Redshift | `postgresql+psycopg://cluster.example.com:5439/dev` | `dblift[redshift]` |
|
|
798
|
+
| Snowflake | `snowflake://user:password@account_identifier/database/schema?warehouse=WH&role=ROLE` | `dblift[snowflake]` |
|
|
737
799
|
| SQL Server | `mssql+pymssql://localhost:1433/mydb` | `dblift[sqlserver]` |
|
|
738
800
|
| Oracle | `oracle+oracledb://localhost:1521?sid=SID` | `dblift[oracle]` |
|
|
739
801
|
| MySQL | `mysql+pymysql://localhost:3306/mydb` | `dblift[mysql]` |
|
|
@@ -342,15 +342,26 @@ def migrate(context: MigrationContext) -> None:
|
|
|
342
342
|
f"INSERT INTO {schema_prefix}roles (code, label) VALUES (?, ?)",
|
|
343
343
|
[code, label],
|
|
344
344
|
)
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
> **Undo is a separate script, not a function.** DBLift does not call an
|
|
348
|
+
> `undo()` function inside a `V*.py` migration. To make a Python migration
|
|
349
|
+
> reversible, add a companion undo script `U2__seed_lookup_tables.py` that
|
|
350
|
+
> exposes its own `migrate(context)` performing the reverse change — exactly
|
|
351
|
+
> like the `U*.sql` undo files described in
|
|
352
|
+
> [Rolling Back Changes](#rolling-back-changes). `dblift undo` runs that
|
|
353
|
+
> companion script; the `Undoable` column in `dblift info` reflects whether a
|
|
354
|
+
> matching `U*` file exists.
|
|
345
355
|
|
|
346
|
-
|
|
347
|
-
|
|
356
|
+
```python
|
|
357
|
+
# migrations/U2__seed_lookup_tables.py (undo companion for V2)
|
|
358
|
+
from api import MigrationContext
|
|
359
|
+
|
|
360
|
+
def migrate(context: MigrationContext) -> None:
|
|
361
|
+
"""Reverse V2 by removing the seeded lookup rows."""
|
|
348
362
|
if context.dry_run:
|
|
349
363
|
return
|
|
350
|
-
context.execute(
|
|
351
|
-
"DELETE FROM roles WHERE code IN (?, ?)",
|
|
352
|
-
["admin", "user"],
|
|
353
|
-
)
|
|
364
|
+
context.execute("DELETE FROM roles WHERE code IN (?, ?)", ["admin", "user"])
|
|
354
365
|
```
|
|
355
366
|
|
|
356
367
|
---
|
|
@@ -623,6 +634,53 @@ migrations:
|
|
|
623
634
|
recursive: false # Dict format (per-directory setting)
|
|
624
635
|
```
|
|
625
636
|
|
|
637
|
+
### Configuration Sources and Precedence
|
|
638
|
+
|
|
639
|
+
The `dblift.yaml` file is only one of three ways to supply configuration. Every
|
|
640
|
+
setting can also be passed as a **command-line flag** or an **environment
|
|
641
|
+
variable**, which is convenient for CI pipelines and for keeping secrets out of
|
|
642
|
+
files. When the same setting comes from more than one source, the higher-priority
|
|
643
|
+
source wins:
|
|
644
|
+
|
|
645
|
+
```
|
|
646
|
+
command-line flag > environment variable > dblift.yaml > values embedded in the database URL
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
The database connection settings are the most common to override:
|
|
650
|
+
|
|
651
|
+
| Setting | `dblift.yaml` key | Environment variable | CLI flag |
|
|
652
|
+
|---------|-------------------|----------------------|----------|
|
|
653
|
+
| Connection URL | `database.url` | `DBLIFT_DB_URL` | `--db-url` |
|
|
654
|
+
| Username | `database.username` | `DBLIFT_DB_USERNAME` | `--db-username` |
|
|
655
|
+
| Password | `database.password` | `DBLIFT_DB_PASSWORD` | `--db-password` |
|
|
656
|
+
| Schema | `database.schema` | `DBLIFT_DB_SCHEMA` | `--db-schema` |
|
|
657
|
+
| Scripts directory | `migrations.directory` | — | `--scripts` |
|
|
658
|
+
| Strict ordering | `strict_mode` (top level) | `DBLIFT_STRICT_MODE` | `--strict` |
|
|
659
|
+
|
|
660
|
+
For example, the same run configured three ways:
|
|
661
|
+
|
|
662
|
+
```bash
|
|
663
|
+
# 1. Everything from dblift.yaml
|
|
664
|
+
dblift migrate
|
|
665
|
+
|
|
666
|
+
# 2. Connection from the environment (nothing sensitive on disk)
|
|
667
|
+
export DBLIFT_DB_URL="postgresql+psycopg://localhost:5432/mydb"
|
|
668
|
+
export DBLIFT_DB_PASSWORD="s3cret"
|
|
669
|
+
dblift migrate
|
|
670
|
+
|
|
671
|
+
# 3. Overriding a file-based config on the command line (e.g. targeting staging)
|
|
672
|
+
dblift migrate --db-url "postgresql+psycopg://staging:5432/mydb" --scripts ./migrations
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
Non-database settings follow the same pattern: the environment variable is the
|
|
676
|
+
setting name upper-cased with a `DBLIFT_` prefix (for example `--installed-by` ↔
|
|
677
|
+
`DBLIFT_INSTALLED_BY`). For the authoritative, always-current list of every
|
|
678
|
+
setting and its three surfaces, run:
|
|
679
|
+
|
|
680
|
+
```bash
|
|
681
|
+
dblift config --list
|
|
682
|
+
```
|
|
683
|
+
|
|
626
684
|
### Supported Databases
|
|
627
685
|
|
|
628
686
|
DBLift works with these databases:
|
|
@@ -632,6 +690,7 @@ DBLift works with these databases:
|
|
|
632
690
|
| PostgreSQL | `postgresql+psycopg://localhost:5432/mydb` | `dblift[postgresql]` |
|
|
633
691
|
| CockroachDB | `postgresql+psycopg://localhost:26257/mydb` | `dblift[cockroachdb]` |
|
|
634
692
|
| Redshift | `postgresql+psycopg://cluster.example.com:5439/dev` | `dblift[redshift]` |
|
|
693
|
+
| Snowflake | `snowflake://user:password@account_identifier/database/schema?warehouse=WH&role=ROLE` | `dblift[snowflake]` |
|
|
635
694
|
| SQL Server | `mssql+pymssql://localhost:1433/mydb` | `dblift[sqlserver]` |
|
|
636
695
|
| Oracle | `oracle+oracledb://localhost:1521?sid=SID` | `dblift[oracle]` |
|
|
637
696
|
| MySQL | `mysql+pymysql://localhost:3306/mydb` | `dblift[mysql]` |
|
|
@@ -22,6 +22,7 @@ from cli.handlers.migrate import _handle_migrate
|
|
|
22
22
|
from cli.handlers.repair import _handle_repair
|
|
23
23
|
from cli.handlers.undo import _handle_undo
|
|
24
24
|
from cli.handlers.validate import _handle_validate
|
|
25
|
+
from cli.premium_manifest import PremiumCommand, premium_stub_index, render_upsell
|
|
25
26
|
from core.seams.tier_resolver import resolve_tier
|
|
26
27
|
|
|
27
28
|
_COMMAND_HANDLERS: Dict[str, Callable[[CliCommandContext], Tuple[bool, Any]]] = {
|
|
@@ -44,6 +45,31 @@ if _builtin_conflicts:
|
|
|
44
45
|
_COMMAND_HANDLERS.update(_extension_handlers)
|
|
45
46
|
del _extension_handlers, _builtin_conflicts
|
|
46
47
|
|
|
48
|
+
|
|
49
|
+
def _make_premium_stub_handler(
|
|
50
|
+
cmd: "PremiumCommand",
|
|
51
|
+
) -> Callable[[CliCommandContext], Tuple[bool, Any]]:
|
|
52
|
+
"""Build a handler that reports the upsell message and fails.
|
|
53
|
+
|
|
54
|
+
Only reachable in chained invocations (``dblift migrate diff``): a stub
|
|
55
|
+
in first position short-circuits in ``cli/main.py`` before any config
|
|
56
|
+
or database work, with the dedicated ``EXIT_LICENSE_REQUIRED`` code.
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
def _handle_premium_stub(ctx: CliCommandContext) -> Tuple[bool, Any]:
|
|
60
|
+
ctx.log.error(render_upsell(cmd))
|
|
61
|
+
return False, None
|
|
62
|
+
|
|
63
|
+
return _handle_premium_stub
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# Gap-fill AFTER extension merge so entry-point registrations always win:
|
|
67
|
+
# with the paid runtime installed, the real handlers already own these
|
|
68
|
+
# names and PREMIUM_STUB_COMMANDS is empty.
|
|
69
|
+
PREMIUM_STUB_COMMANDS: Dict[str, "PremiumCommand"] = premium_stub_index(_COMMAND_HANDLERS)
|
|
70
|
+
for _stub_cmd in PREMIUM_STUB_COMMANDS.values():
|
|
71
|
+
_COMMAND_HANDLERS[_stub_cmd.name] = _make_premium_stub_handler(_stub_cmd)
|
|
72
|
+
|
|
47
73
|
_AVAILABLE_COMMANDS = (
|
|
48
74
|
list(_COMMAND_HANDLERS.keys()) + ["db", "config"] + list(load_terminal_commands())
|
|
49
75
|
)
|
|
@@ -22,3 +22,9 @@ from __future__ import annotations
|
|
|
22
22
|
MACHINE_READABLE_FORMATS: frozenset[str] = frozenset(
|
|
23
23
|
{"json", "sarif", "github-actions", "gitlab", "compact"}
|
|
24
24
|
)
|
|
25
|
+
|
|
26
|
+
# Exit code for "this command needs a paid edition or a higher license
|
|
27
|
+
# tier": returned by the OSS premium-command stubs (cli/premium_manifest.py)
|
|
28
|
+
# so scripts and CI pipelines can branch on entitlement without parsing
|
|
29
|
+
# stderr. Distinct from 1 (command failure) and 2 (argparse usage error).
|
|
30
|
+
EXIT_LICENSE_REQUIRED: int = 4
|
|
@@ -308,6 +308,34 @@ def _register_builtin_command_parsers(
|
|
|
308
308
|
return registered
|
|
309
309
|
|
|
310
310
|
|
|
311
|
+
def _register_premium_stub_parsers(parser: argparse.ArgumentParser) -> None:
|
|
312
|
+
"""Add stub subparsers for paid commands with no registered extension.
|
|
313
|
+
|
|
314
|
+
Must run AFTER ``load_command_extensions`` so real entry-point parsers
|
|
315
|
+
always win: with the paid runtime installed the manifest entries are
|
|
316
|
+
already in ``subparsers.choices`` and no stub is created. The stub
|
|
317
|
+
swallows any arguments via ``REMAINDER`` (and disables ``-h``) so every
|
|
318
|
+
invocation shape — ``dblift diff``, ``dblift diff --anything``,
|
|
319
|
+
``dblift diff --help`` — reaches the upsell message instead of an
|
|
320
|
+
argparse usage error.
|
|
321
|
+
"""
|
|
322
|
+
from cli.premium_manifest import premium_commands_missing_from
|
|
323
|
+
|
|
324
|
+
subparser_actions = [
|
|
325
|
+
action for action in parser._actions if isinstance(action, argparse._SubParsersAction)
|
|
326
|
+
]
|
|
327
|
+
if not subparser_actions:
|
|
328
|
+
return
|
|
329
|
+
subparsers = subparser_actions[0]
|
|
330
|
+
for cmd in premium_commands_missing_from(subparsers.choices):
|
|
331
|
+
stub = subparsers.add_parser(
|
|
332
|
+
cmd.name,
|
|
333
|
+
help=f"{cmd.summary} [{cmd.edition}]",
|
|
334
|
+
add_help=False,
|
|
335
|
+
)
|
|
336
|
+
stub.add_argument("stub_args", nargs=argparse.REMAINDER, help=argparse.SUPPRESS)
|
|
337
|
+
|
|
338
|
+
|
|
311
339
|
def create_parser(
|
|
312
340
|
exit_on_error: bool = True, suppress_errors: bool = False
|
|
313
341
|
) -> argparse.ArgumentParser:
|
|
@@ -485,6 +513,8 @@ def create_parser(
|
|
|
485
513
|
help="List all properties and how to set them (config key / env var / CLI flag)",
|
|
486
514
|
)
|
|
487
515
|
import_module("cli.extensions").load_command_extensions(parser)
|
|
516
|
+
# Stubs fill whatever gaps the extensions left — never the reverse.
|
|
517
|
+
_register_premium_stub_parsers(parser)
|
|
488
518
|
# Emit registry-derived flags LAST, after every subparser (built-in and
|
|
489
519
|
# extension) is registered, so the tree walk in _add_registry_flags can see
|
|
490
520
|
# subcommand-only flags and skip them instead of shadowing them on the root.
|
|
@@ -23,6 +23,7 @@ _mask_database_url = mask_database_url
|
|
|
23
23
|
from cli._command_handlers import ( # noqa: F401
|
|
24
24
|
_AVAILABLE_COMMANDS,
|
|
25
25
|
_COMMAND_HANDLERS,
|
|
26
|
+
PREMIUM_STUB_COMMANDS,
|
|
26
27
|
CliCommandContext,
|
|
27
28
|
_extract_version_filters,
|
|
28
29
|
_handle_baseline,
|
|
@@ -51,9 +52,11 @@ from cli._config_helpers import ( # noqa: F401
|
|
|
51
52
|
_validate_db_config,
|
|
52
53
|
_validate_log_format_for_cli,
|
|
53
54
|
)
|
|
55
|
+
from cli._constants import EXIT_LICENSE_REQUIRED
|
|
54
56
|
from cli._output import CommandOutput, from_args
|
|
55
57
|
from cli._parser_setup import create_parser, parse_with_selective_errors
|
|
56
58
|
from cli.extensions import load_terminal_commands
|
|
59
|
+
from cli.premium_manifest import render_upsell
|
|
57
60
|
from core.seams.feature_loading import load_feature_extensions
|
|
58
61
|
from core.seams.license_info import get_license_info
|
|
59
62
|
|
|
@@ -309,6 +312,17 @@ def _parse_argv_and_load_config(argv: List[str]) -> _CliContext:
|
|
|
309
312
|
sys.exit(0)
|
|
310
313
|
sys.exit(terminal_commands[commands[0]](args))
|
|
311
314
|
|
|
315
|
+
# Premium-command stubs short-circuit here — before argparse builds the
|
|
316
|
+
# namespace and before any config/database work — because the stub's only
|
|
317
|
+
# behaviour is the upsell message: subcommand flags the OSS parser doesn't
|
|
318
|
+
# know (e.g. ``diff --snapshot-model``) must not fail as usage errors, and
|
|
319
|
+
# a missing database config must not bury the message. Chained invocations
|
|
320
|
+
# (stub not in first position) are covered by the gap-fill handlers in
|
|
321
|
+
# cli/_command_handlers.py instead.
|
|
322
|
+
if commands and commands[0] in PREMIUM_STUB_COMMANDS:
|
|
323
|
+
CommandOutput("console").error(render_upsell(PREMIUM_STUB_COMMANDS[commands[0]]))
|
|
324
|
+
sys.exit(EXIT_LICENSE_REQUIRED)
|
|
325
|
+
|
|
312
326
|
args, _unknown_args = _build_args_namespace(commands, global_arguments, subcommand_args)
|
|
313
327
|
|
|
314
328
|
if hasattr(args, "version") and args.version:
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""Catalog of paid dblift commands surfaced as stubs in the OSS CLI.
|
|
2
|
+
|
|
3
|
+
This module is the ONLY place OSS code may name paid-edition commands
|
|
4
|
+
(2026-07 amendment to the tier-architecture naming invariant: the
|
|
5
|
+
unidirectional dependency rule is untouched — OSS still imports nothing
|
|
6
|
+
from a higher tier — but this one file may carry a declarative catalog so
|
|
7
|
+
the OSS CLI can advertise paid commands instead of silently omitting them).
|
|
8
|
+
|
|
9
|
+
It is pure data plus rendering helpers. When the paid runtime is installed,
|
|
10
|
+
its entry-point registrations run first and the stubs for those commands
|
|
11
|
+
are never created (see ``_register_premium_stub_parsers`` in
|
|
12
|
+
``cli/_parser_setup.py`` and the gap-fill block in
|
|
13
|
+
``cli/_command_handlers.py``), so precedence is structural, not conditional.
|
|
14
|
+
|
|
15
|
+
The paid monorepo carries a CI check that diffs this catalog against the
|
|
16
|
+
commands its packages actually register — keep entries in sync with the
|
|
17
|
+
real command surface, never ahead of it.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
from dataclasses import dataclass
|
|
23
|
+
from typing import Dict, Iterable, Tuple
|
|
24
|
+
|
|
25
|
+
UPGRADE_URL = "https://dblift.com/upgrade"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass(frozen=True)
|
|
29
|
+
class PremiumCommand:
|
|
30
|
+
"""Declarative descriptor for a command that exists only in a paid edition."""
|
|
31
|
+
|
|
32
|
+
name: str
|
|
33
|
+
edition: str # human-facing label: "Pro" or "Enterprise"
|
|
34
|
+
summary: str # one-line help, mirrored from the paid parser registration
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
PREMIUM_COMMANDS: Tuple[PremiumCommand, ...] = (
|
|
38
|
+
PremiumCommand(
|
|
39
|
+
"diff",
|
|
40
|
+
"Pro",
|
|
41
|
+
"Compare applied migrations against live database schema (drift detection)",
|
|
42
|
+
),
|
|
43
|
+
PremiumCommand(
|
|
44
|
+
"export-schema",
|
|
45
|
+
"Pro",
|
|
46
|
+
"Export database schema to SQL migration file(s)",
|
|
47
|
+
),
|
|
48
|
+
PremiumCommand(
|
|
49
|
+
"validate-sql",
|
|
50
|
+
"Pro",
|
|
51
|
+
"Validate SQL files with business rules and performance analysis",
|
|
52
|
+
),
|
|
53
|
+
PremiumCommand(
|
|
54
|
+
"data",
|
|
55
|
+
"Pro",
|
|
56
|
+
"Manage data corrections - audited DML with plan/apply/undo",
|
|
57
|
+
),
|
|
58
|
+
PremiumCommand(
|
|
59
|
+
"snapshot",
|
|
60
|
+
"Enterprise",
|
|
61
|
+
"Export database schema snapshot to JSON model file",
|
|
62
|
+
),
|
|
63
|
+
PremiumCommand(
|
|
64
|
+
"plan",
|
|
65
|
+
"Enterprise",
|
|
66
|
+
"Build an offline migration plan from a snapshot model",
|
|
67
|
+
),
|
|
68
|
+
PremiumCommand(
|
|
69
|
+
"preflight",
|
|
70
|
+
"Enterprise",
|
|
71
|
+
"Run deployment preflight checks from a snapshot model",
|
|
72
|
+
),
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def premium_commands_missing_from(
|
|
77
|
+
registered: Iterable[str],
|
|
78
|
+
) -> Tuple[PremiumCommand, ...]:
|
|
79
|
+
"""Manifest entries with no real registration among ``registered``.
|
|
80
|
+
|
|
81
|
+
Callers pass the names already claimed by builtins and entry-point
|
|
82
|
+
extensions; anything returned needs a stub. With the paid runtime
|
|
83
|
+
installed this is empty and the OSS surface is untouched.
|
|
84
|
+
"""
|
|
85
|
+
taken = set(registered)
|
|
86
|
+
return tuple(cmd for cmd in PREMIUM_COMMANDS if cmd.name not in taken)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def premium_stub_index(registered: Iterable[str]) -> Dict[str, PremiumCommand]:
|
|
90
|
+
"""Like :func:`premium_commands_missing_from`, keyed by command name."""
|
|
91
|
+
return {cmd.name: cmd for cmd in premium_commands_missing_from(registered)}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def render_upsell(cmd: PremiumCommand) -> str:
|
|
95
|
+
"""Message shown when a stubbed paid command is invoked in OSS."""
|
|
96
|
+
return (
|
|
97
|
+
f"'{cmd.name}' is a dblift {cmd.edition} command and is not included "
|
|
98
|
+
f"in the open-source edition.\n"
|
|
99
|
+
f" {cmd.summary}.\n"
|
|
100
|
+
f"Learn more and upgrade: {UPGRADE_URL}"
|
|
101
|
+
)
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"""Factory for PostgreSQL-wire-compatible distribution plugins.
|
|
2
|
+
|
|
3
|
+
Several engines (Neon, Supabase, Aurora PostgreSQL, AlloyDB, YugabyteDB,
|
|
4
|
+
TimescaleDB, Citus) speak the PostgreSQL wire protocol and reuse PostgreSQL's
|
|
5
|
+
provider, config, SQLAlchemy URL builder, and ``psycopg`` driver wholesale.
|
|
6
|
+
Their only per-engine content is *identity*, not *behavior*:
|
|
7
|
+
|
|
8
|
+
* a ``canonical_dialect_key`` on the provider, and
|
|
9
|
+
* a quirks subclass that resets the two "reference dialect" flags to ``False``
|
|
10
|
+
(exactly one registered plugin — PostgreSQL — may own each, see
|
|
11
|
+
:meth:`ProviderRegistry.reference_dialect_name`).
|
|
12
|
+
|
|
13
|
+
Historically each such engine shipped three near-identical files
|
|
14
|
+
(``provider.py`` / ``quirks.py`` / ``plugin.py``) that differed only by a name
|
|
15
|
+
string. This module collapses that boilerplate: :func:`make_pg_compatible_plugin`
|
|
16
|
+
builds the provider class, the quirks class, and the :class:`PluginInfo` from a
|
|
17
|
+
single dialect name, so a new PG-wire engine is one declaration in its
|
|
18
|
+
``plugin.py``.
|
|
19
|
+
|
|
20
|
+
Engines with genuine behavioral differences (CockroachDB's table locking,
|
|
21
|
+
Redshift's catalog/history SQL) are **not** built here — they keep hand-written
|
|
22
|
+
provider/quirks classes.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
from typing import Callable, List, Optional, Type
|
|
28
|
+
|
|
29
|
+
from db.base_provider import BaseProvider
|
|
30
|
+
from db.plugins.postgresql.provider import PostgreSqlProvider
|
|
31
|
+
from db.plugins.postgresql.quirks import PostgresqlQuirks
|
|
32
|
+
from db.plugins.postgresql.sqlalchemy_url import build_sqlalchemy_url
|
|
33
|
+
from db.provider_registry import PluginInfo
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _class_stem(dialect: str) -> str:
|
|
37
|
+
"""Derive the CamelCase class-name stem from a dialect key.
|
|
38
|
+
|
|
39
|
+
``"neon"`` -> ``"Neon"``; ``"aurora-postgresql"`` -> ``"AuroraPostgresql"``.
|
|
40
|
+
Kept deliberately simple (``str.capitalize`` per hyphen segment) so the
|
|
41
|
+
generated names match the ``<Stem>Provider`` / ``<Stem>Quirks`` strings the
|
|
42
|
+
plugin-contract tests assert.
|
|
43
|
+
"""
|
|
44
|
+
return "".join(part.capitalize() for part in dialect.split("-"))
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _register_global(cls: type) -> type:
|
|
48
|
+
"""Expose a factory-built class as a module global.
|
|
49
|
+
|
|
50
|
+
``type(...)`` sets ``__module__`` to this module, so ``pickle`` (and
|
|
51
|
+
anything resolving a class by qualified name, e.g. multiprocessing in
|
|
52
|
+
``spawn`` mode) looks the class up as ``db.plugins._pg_compatible.<Name>``.
|
|
53
|
+
Registering it here makes that lookup succeed instead of raising
|
|
54
|
+
``AttributeError``, and also lets callers ``from db.plugins._pg_compatible
|
|
55
|
+
import NeonProvider`` if they need the class directly.
|
|
56
|
+
"""
|
|
57
|
+
globals()[cls.__name__] = cls
|
|
58
|
+
return cls
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def make_pg_compatible_provider(dialect: str) -> Type[PostgreSqlProvider]:
|
|
62
|
+
"""Build a PostgreSQL provider subclass carrying only a distinct identity."""
|
|
63
|
+
stem = _class_stem(dialect)
|
|
64
|
+
return _register_global(
|
|
65
|
+
type(
|
|
66
|
+
f"{stem}Provider",
|
|
67
|
+
(PostgreSqlProvider,),
|
|
68
|
+
{
|
|
69
|
+
"__module__": __name__,
|
|
70
|
+
"__doc__": (
|
|
71
|
+
f"{stem} provider — wire-compatible with PostgreSQL; reuses the "
|
|
72
|
+
"PostgreSQL provider with a distinct dialect identity."
|
|
73
|
+
),
|
|
74
|
+
"canonical_dialect_key": dialect,
|
|
75
|
+
},
|
|
76
|
+
)
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def make_pg_compatible_quirks(dialect: str) -> Type[PostgresqlQuirks]:
|
|
81
|
+
"""Build a PostgreSQL quirks subclass that drops the reference-dialect flags.
|
|
82
|
+
|
|
83
|
+
The two flags are set in the class body (not per instance) because
|
|
84
|
+
:meth:`ProviderRegistry.canonical_dialect_name_for_capability` reads
|
|
85
|
+
``vars(quirks_class)`` — only a class-level override makes this engine a
|
|
86
|
+
non-owner of the ANSI-reference and sqlglot-read-fallback capabilities,
|
|
87
|
+
preserving PostgreSQL as the single owner of each.
|
|
88
|
+
"""
|
|
89
|
+
stem = _class_stem(dialect)
|
|
90
|
+
|
|
91
|
+
def __init__(self: PostgresqlQuirks, dialect_name: str = dialect) -> None:
|
|
92
|
+
# type()-built classes have no __class__ cell, so ``super()`` is
|
|
93
|
+
# unavailable — call the base initializer explicitly.
|
|
94
|
+
PostgresqlQuirks.__init__(self, dialect_name=dialect_name)
|
|
95
|
+
|
|
96
|
+
return _register_global(
|
|
97
|
+
type(
|
|
98
|
+
f"{stem}Quirks",
|
|
99
|
+
(PostgresqlQuirks,),
|
|
100
|
+
{
|
|
101
|
+
"__module__": __name__,
|
|
102
|
+
"__doc__": (
|
|
103
|
+
f"{stem} quirks, inheriting every PostgreSQL quirk. Only the "
|
|
104
|
+
"reference-dialect flags are reset so PostgreSQL stays the sole "
|
|
105
|
+
"owner of each."
|
|
106
|
+
),
|
|
107
|
+
"is_ansi_reference_dialect": False,
|
|
108
|
+
"is_default_sqlglot_read_fallback": False,
|
|
109
|
+
"__init__": __init__,
|
|
110
|
+
},
|
|
111
|
+
)
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def make_pg_compatible_plugin(
|
|
116
|
+
dialect: str,
|
|
117
|
+
description: str,
|
|
118
|
+
*,
|
|
119
|
+
dialects: Optional[List[str]] = None,
|
|
120
|
+
version: str = "1.0.0",
|
|
121
|
+
sqlalchemy_url_builder: Callable[..., str] = build_sqlalchemy_url,
|
|
122
|
+
native_driver_module: str = "psycopg",
|
|
123
|
+
) -> PluginInfo:
|
|
124
|
+
"""Assemble the :class:`PluginInfo` for a PostgreSQL-wire-compatible engine.
|
|
125
|
+
|
|
126
|
+
Reuses PostgreSQL's config (``config_dialect="postgresql"``), URL builder,
|
|
127
|
+
and driver; only the identity (provider/quirks classes + dialect key) is
|
|
128
|
+
engine-specific. ``dialects`` defaults to ``[dialect]``.
|
|
129
|
+
"""
|
|
130
|
+
provider_class: Type[BaseProvider] = make_pg_compatible_provider(dialect)
|
|
131
|
+
quirks_class = make_pg_compatible_quirks(dialect)
|
|
132
|
+
return PluginInfo(
|
|
133
|
+
name=dialect,
|
|
134
|
+
version=version,
|
|
135
|
+
description=description,
|
|
136
|
+
dialects=dialects if dialects is not None else [dialect],
|
|
137
|
+
provider_class=provider_class,
|
|
138
|
+
transport="native",
|
|
139
|
+
quirks_class=quirks_class,
|
|
140
|
+
config_dialect="postgresql", # lint: allow-dialect-string: reuse PG config class
|
|
141
|
+
sqlalchemy_url_builder=sqlalchemy_url_builder,
|
|
142
|
+
native_driver_module=native_driver_module,
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
__all__ = [
|
|
147
|
+
"make_pg_compatible_provider",
|
|
148
|
+
"make_pg_compatible_quirks",
|
|
149
|
+
"make_pg_compatible_plugin",
|
|
150
|
+
]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Google AlloyDB for PostgreSQL database provider plugin package (PostgreSQL-compatible).
|
|
2
|
+
|
|
3
|
+
The provider and quirks classes are built by the shared factory invoked in
|
|
4
|
+
``plugin.py`` (:mod:`db.plugins._pg_compatible`); this package intentionally
|
|
5
|
+
ships no ``provider.py`` / ``quirks.py``.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
__plugin_name__ = "alloydb"
|
|
9
|
+
__plugin_version__ = "1.0.0"
|
|
10
|
+
__plugin_description__ = "Google AlloyDB for PostgreSQL database provider"
|
|
11
|
+
__plugin_dialects__ = ["alloydb"]
|
|
12
|
+
__plugin_transport__ = "native"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Entry-point declaration for the alloydb plugin.
|
|
2
|
+
|
|
3
|
+
This engine is wire-compatible with PostgreSQL, so it reuses PostgreSQL's
|
|
4
|
+
provider, config, SQLAlchemy URL builder, and ``psycopg`` driver through the
|
|
5
|
+
shared factory in :mod:`db.plugins._pg_compatible`, attaching only a distinct
|
|
6
|
+
dialect identity. Users keep their ``postgresql://`` connection string and
|
|
7
|
+
select this engine via ``type: alloydb``.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from db.plugins._pg_compatible import make_pg_compatible_plugin
|
|
13
|
+
from db.provider_registry import PluginInfo
|
|
14
|
+
|
|
15
|
+
PLUGIN: PluginInfo = make_pg_compatible_plugin(
|
|
16
|
+
"alloydb",
|
|
17
|
+
"Google AlloyDB for PostgreSQL database provider",
|
|
18
|
+
)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Amazon Aurora PostgreSQL database provider plugin package (PostgreSQL-compatible).
|
|
2
|
+
|
|
3
|
+
The provider and quirks classes are built by the shared factory invoked in
|
|
4
|
+
``plugin.py`` (:mod:`db.plugins._pg_compatible`); this package intentionally
|
|
5
|
+
ships no ``provider.py`` / ``quirks.py``.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
__plugin_name__ = "aurora-postgresql"
|
|
9
|
+
__plugin_version__ = "1.0.0"
|
|
10
|
+
__plugin_description__ = "Amazon Aurora PostgreSQL database provider"
|
|
11
|
+
__plugin_dialects__ = ["aurora-postgresql"]
|
|
12
|
+
__plugin_transport__ = "native"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Entry-point declaration for the aurora-postgresql plugin.
|
|
2
|
+
|
|
3
|
+
This engine is wire-compatible with PostgreSQL, so it reuses PostgreSQL's
|
|
4
|
+
provider, config, SQLAlchemy URL builder, and ``psycopg`` driver through the
|
|
5
|
+
shared factory in :mod:`db.plugins._pg_compatible`, attaching only a distinct
|
|
6
|
+
dialect identity. Users keep their ``postgresql://`` connection string and
|
|
7
|
+
select this engine via ``type: aurora-postgresql``.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from db.plugins._pg_compatible import make_pg_compatible_plugin
|
|
13
|
+
from db.provider_registry import PluginInfo
|
|
14
|
+
|
|
15
|
+
PLUGIN: PluginInfo = make_pg_compatible_plugin(
|
|
16
|
+
"aurora-postgresql",
|
|
17
|
+
"Amazon Aurora PostgreSQL database provider",
|
|
18
|
+
)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Citus (distributed PostgreSQL) database provider plugin package (PostgreSQL-compatible).
|
|
2
|
+
|
|
3
|
+
The provider and quirks classes are built by the shared factory invoked in
|
|
4
|
+
``plugin.py`` (:mod:`db.plugins._pg_compatible`); this package intentionally
|
|
5
|
+
ships no ``provider.py`` / ``quirks.py``.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
__plugin_name__ = "citus"
|
|
9
|
+
__plugin_version__ = "1.0.0"
|
|
10
|
+
__plugin_description__ = "Citus (distributed PostgreSQL) database provider"
|
|
11
|
+
__plugin_dialects__ = ["citus"]
|
|
12
|
+
__plugin_transport__ = "native"
|