dblift 2.1.1__tar.gz → 2.2.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.
Files changed (435) hide show
  1. {dblift-2.1.1 → dblift-2.2.1}/PKG-INFO +1 -1
  2. dblift-2.2.1/api/__init__.py +16 -0
  3. {dblift-2.1.1 → dblift-2.2.1}/api/_client_operations.py +6 -2
  4. {dblift-2.1.1 → dblift-2.2.1}/api/client.py +9 -5
  5. {dblift-2.1.1 → dblift-2.2.1}/cli/_command_handlers.py +3 -1
  6. {dblift-2.1.1 → dblift-2.2.1}/cli/_config_helpers.py +40 -11
  7. {dblift-2.1.1 → dblift-2.2.1}/cli/_output.py +2 -1
  8. {dblift-2.1.1 → dblift-2.2.1}/cli/_parser_setup.py +89 -5
  9. dblift-2.2.1/cli/commands/__init__.py +1 -0
  10. dblift-2.2.1/cli/commands/config_command.py +48 -0
  11. {dblift-2.1.1 → dblift-2.2.1}/cli/handlers/_shared.py +20 -10
  12. {dblift-2.1.1 → dblift-2.2.1}/cli/main.py +51 -8
  13. {dblift-2.1.1 → dblift-2.2.1}/config/database_config.py +3 -3
  14. {dblift-2.1.1 → dblift-2.2.1}/config/dblift_config.py +124 -55
  15. dblift-2.2.1/config/property_registry.py +135 -0
  16. {dblift-2.1.1 → dblift-2.2.1}/config/secrets/_registry.py +3 -2
  17. {dblift-2.1.1 → dblift-2.2.1}/core/dialect_boundary.py +9 -4
  18. {dblift-2.1.1 → dblift-2.2.1}/core/logger/formatters/_formatter_impl.py +1 -3
  19. {dblift-2.1.1 → dblift-2.2.1}/core/logger/formatters/htmlformatter.py +26 -14
  20. {dblift-2.1.1 → dblift-2.2.1}/core/migration/commands/base_command.py +2 -2
  21. {dblift-2.1.1 → dblift-2.2.1}/core/migration/commands/migrate_command.py +3 -0
  22. {dblift-2.1.1 → dblift-2.2.1}/core/migration/commands/undo_command.py +28 -258
  23. {dblift-2.1.1 → dblift-2.2.1}/core/migration/executor/execution_engine.py +3 -0
  24. {dblift-2.1.1 → dblift-2.2.1}/core/migration/executor/migration_executor.py +1 -1
  25. {dblift-2.1.1 → dblift-2.2.1}/core/migration/ui/data_collector.py +9 -15
  26. dblift-2.2.1/core/seams/capabilities.py +20 -0
  27. {dblift-2.1.1 → dblift-2.2.1}/core/seams/event_listeners.py +3 -2
  28. dblift-2.2.1/core/seams/feature_loading.py +66 -0
  29. {dblift-2.1.1 → dblift-2.2.1}/core/seams/introspection.py +1 -1
  30. dblift-2.2.1/core/seams/license_info.py +42 -0
  31. dblift-2.2.1/core/seams/runtime_checks.py +35 -0
  32. dblift-2.2.1/core/seams/sql_generators.py +42 -0
  33. dblift-2.2.1/core/seams/tier_resolver.py +59 -0
  34. dblift-2.2.1/core/sql_generator/__init__.py +42 -0
  35. dblift-2.2.1/core/sql_generator/alter/__init__.py +17 -0
  36. dblift-2.2.1/core/sql_generator/alter/alter_generator_factory.py +123 -0
  37. dblift-2.2.1/core/sql_generator/alter/base_alter_generator.py +169 -0
  38. dblift-2.2.1/core/sql_generator/alter_generator.py +64 -0
  39. dblift-2.2.1/core/sql_generator/base_generator.py +607 -0
  40. dblift-2.2.1/core/sql_generator/basic_table_ddl_generator.py +1034 -0
  41. dblift-2.2.1/core/sql_generator/dependency_analyzer.py +602 -0
  42. dblift-2.2.1/core/sql_generator/diff_converters/__init__.py +5 -0
  43. dblift-2.2.1/core/sql_generator/diff_converters/base_converter.py +36 -0
  44. dblift-2.2.1/core/sql_generator/formatter.py +112 -0
  45. dblift-2.2.1/core/sql_generator/generator_factory.py +188 -0
  46. dblift-2.2.1/core/sql_generator/options.py +59 -0
  47. dblift-2.2.1/core/sql_generator/script_organizer.py +307 -0
  48. dblift-2.2.1/core/sql_generator/sql_generator.py +50 -0
  49. dblift-2.2.1/core/sql_generator/sql_statement.py +5 -0
  50. dblift-2.2.1/core/sql_generator/table_ddl_render.py +61 -0
  51. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/event.py +14 -2
  52. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/extension.py +14 -2
  53. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/foreign_data_wrapper.py +12 -2
  54. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/foreign_server.py +14 -2
  55. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/index.py +14 -2
  56. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/package.py +14 -2
  57. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/procedure.py +14 -2
  58. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/sequence.py +21 -1
  59. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/synonym.py +14 -2
  60. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/table.py +32 -61
  61. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/trigger.py +12 -2
  62. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/user_defined_type.py +12 -2
  63. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/view.py +14 -2
  64. {dblift-2.1.1 → dblift-2.2.1}/core/sql_validator/__init__.py +1 -1
  65. {dblift-2.1.1 → dblift-2.2.1}/core/sql_validator/migration_validator.py +2 -2
  66. {dblift-2.1.1 → dblift-2.2.1}/db/base_quirks.py +22 -7
  67. {dblift-2.1.1 → dblift-2.2.1}/db/dml_analysis.py +1 -1
  68. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/cosmosdb/query_executor.py +1 -1
  69. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/quirks.py +13 -6
  70. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/db2/db2/schema_operations.py +10 -8
  71. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/db2/provider.py +14 -8
  72. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/db2/quirks.py +10 -5
  73. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/mysql/quirks.py +11 -6
  74. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/quirks.py +47 -38
  75. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/postgresql/quirks.py +13 -9
  76. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlite/quirks.py +9 -5
  77. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlserver/quirks.py +11 -7
  78. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlserver/sqlalchemy_url.py +12 -1
  79. {dblift-2.1.1 → dblift-2.2.1}/dblift.egg-info/PKG-INFO +1 -1
  80. {dblift-2.1.1 → dblift-2.2.1}/dblift.egg-info/SOURCES.txt +26 -3
  81. {dblift-2.1.1 → dblift-2.2.1}/pyproject.toml +3 -1
  82. dblift-2.1.1/api/__init__.py +0 -12
  83. dblift-2.1.1/core/features.py +0 -123
  84. dblift-2.1.1/core/logger/formatters/diff_utils.py +0 -414
  85. dblift-2.1.1/core/normalization/data_type_normalizer.py +0 -5
  86. {dblift-2.1.1 → dblift-2.2.1}/LICENSE +0 -0
  87. {dblift-2.1.1 → dblift-2.2.1}/README.md +0 -0
  88. {dblift-2.1.1 → dblift-2.2.1}/api/_cli_support.py +0 -0
  89. {dblift-2.1.1 → dblift-2.2.1}/api/_client_factory.py +0 -0
  90. {dblift-2.1.1 → dblift-2.2.1}/api/_engine_config.py +0 -0
  91. {dblift-2.1.1 → dblift-2.2.1}/api/async_client.py +0 -0
  92. {dblift-2.1.1 → dblift-2.2.1}/api/events.py +0 -0
  93. {dblift-2.1.1 → dblift-2.2.1}/api/migrations.py +0 -0
  94. {dblift-2.1.1 → dblift-2.2.1}/api/py.typed +0 -0
  95. {dblift-2.1.1 → dblift-2.2.1}/cli/__init__.py +0 -0
  96. {dblift-2.1.1 → dblift-2.2.1}/cli/_constants.py +0 -0
  97. {dblift-2.1.1 → dblift-2.2.1}/cli/db_utils.py +0 -0
  98. {dblift-2.1.1 → dblift-2.2.1}/cli/extensions.py +0 -0
  99. {dblift-2.1.1 → dblift-2.2.1}/cli/handlers/__init__.py +0 -0
  100. {dblift-2.1.1 → dblift-2.2.1}/cli/handlers/baseline.py +0 -0
  101. {dblift-2.1.1 → dblift-2.2.1}/cli/handlers/clean.py +0 -0
  102. {dblift-2.1.1 → dblift-2.2.1}/cli/handlers/import_flyway.py +0 -0
  103. {dblift-2.1.1 → dblift-2.2.1}/cli/handlers/info.py +0 -0
  104. {dblift-2.1.1 → dblift-2.2.1}/cli/handlers/migrate.py +0 -0
  105. {dblift-2.1.1 → dblift-2.2.1}/cli/handlers/repair.py +0 -0
  106. {dblift-2.1.1 → dblift-2.2.1}/cli/handlers/undo.py +0 -0
  107. {dblift-2.1.1 → dblift-2.2.1}/cli/handlers/validate.py +0 -0
  108. {dblift-2.1.1 → dblift-2.2.1}/config/__init__.py +0 -0
  109. {dblift-2.1.1 → dblift-2.2.1}/config/_credential_masking.py +0 -0
  110. {dblift-2.1.1 → dblift-2.2.1}/config/_subclasses/__init__.py +0 -0
  111. {dblift-2.1.1 → dblift-2.2.1}/config/_subclasses/dummy_config.py +0 -0
  112. {dblift-2.1.1 → dblift-2.2.1}/config/_url_builder_mixin.py +0 -0
  113. {dblift-2.1.1 → dblift-2.2.1}/config/config_builder.py +0 -0
  114. {dblift-2.1.1 → dblift-2.2.1}/config/errors.py +0 -0
  115. {dblift-2.1.1 → dblift-2.2.1}/config/secrets/__init__.py +0 -0
  116. {dblift-2.1.1 → dblift-2.2.1}/config/secrets/_cache.py +0 -0
  117. {dblift-2.1.1 → dblift-2.2.1}/config/secrets/_provider_base.py +0 -0
  118. {dblift-2.1.1 → dblift-2.2.1}/config/secrets/_resolver.py +0 -0
  119. {dblift-2.1.1 → dblift-2.2.1}/config/secrets/_secrets_config.py +0 -0
  120. {dblift-2.1.1 → dblift-2.2.1}/core/__init__.py +0 -0
  121. {dblift-2.1.1 → dblift-2.2.1}/core/constants.py +0 -0
  122. {dblift-2.1.1 → dblift-2.2.1}/core/exceptions.py +0 -0
  123. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/__init__.py +0 -0
  124. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/_column_enricher.py +0 -0
  125. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/_partition_enricher.py +0 -0
  126. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/_schema_orchestrator.py +0 -0
  127. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/_utils.py +0 -0
  128. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/_vendor_property_applier.py +0 -0
  129. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/base_introspector.py +0 -0
  130. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/extractors/__init__.py +0 -0
  131. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/extractors/base_extractor.py +0 -0
  132. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/extractors/column_extractor.py +0 -0
  133. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/extractors/constraint_extractor.py +0 -0
  134. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/extractors/index_extractor.py +0 -0
  135. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/extractors/misc_extractor.py +0 -0
  136. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/extractors/procedure_extractor.py +0 -0
  137. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/extractors/sequence_extractor.py +0 -0
  138. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/extractors/table_extractor.py +0 -0
  139. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/extractors/trigger_extractor.py +0 -0
  140. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/extractors/view_extractor.py +0 -0
  141. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/introspector_factory.py +0 -0
  142. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/result.py +0 -0
  143. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/schema_introspector.py +0 -0
  144. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/vendor_queries_base.py +0 -0
  145. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/vendor_queries_factory.py +0 -0
  146. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/vendor_queries_protocols.py +0 -0
  147. {dblift-2.1.1 → dblift-2.2.1}/core/introspection/version_detector.py +0 -0
  148. {dblift-2.1.1 → dblift-2.2.1}/core/logger/__init__.py +0 -0
  149. {dblift-2.1.1 → dblift-2.2.1}/core/logger/_base.py +0 -0
  150. {dblift-2.1.1 → dblift-2.2.1}/core/logger/_factory.py +0 -0
  151. {dblift-2.1.1 → dblift-2.2.1}/core/logger/_formatters.py +0 -0
  152. {dblift-2.1.1 → dblift-2.2.1}/core/logger/_levels.py +0 -0
  153. {dblift-2.1.1 → dblift-2.2.1}/core/logger/_multi.py +0 -0
  154. {dblift-2.1.1 → dblift-2.2.1}/core/logger/_null.py +0 -0
  155. {dblift-2.1.1 → dblift-2.2.1}/core/logger/console.py +0 -0
  156. {dblift-2.1.1 → dblift-2.2.1}/core/logger/formatters/__init__.py +0 -0
  157. {dblift-2.1.1 → dblift-2.2.1}/core/logger/formatters/factory.py +0 -0
  158. {dblift-2.1.1 → dblift-2.2.1}/core/logger/formatters/formatter.py +0 -0
  159. {dblift-2.1.1 → dblift-2.2.1}/core/logger/formatters/jsonformatter.py +0 -0
  160. {dblift-2.1.1 → dblift-2.2.1}/core/logger/log.py +0 -0
  161. {dblift-2.1.1 → dblift-2.2.1}/core/logger/results.py +0 -0
  162. {dblift-2.1.1 → dblift-2.2.1}/core/migration/__init__.py +0 -0
  163. {dblift-2.1.1 → dblift-2.2.1}/core/migration/_type_match.py +0 -0
  164. {dblift-2.1.1 → dblift-2.2.1}/core/migration/clean_summary.py +0 -0
  165. {dblift-2.1.1 → dblift-2.2.1}/core/migration/commands/__init__.py +0 -0
  166. {dblift-2.1.1 → dblift-2.2.1}/core/migration/commands/_script_events.py +0 -0
  167. {dblift-2.1.1 → dblift-2.2.1}/core/migration/commands/baseline_command.py +0 -0
  168. {dblift-2.1.1 → dblift-2.2.1}/core/migration/commands/clean_command.py +0 -0
  169. {dblift-2.1.1 → dblift-2.2.1}/core/migration/commands/import_flyway_command.py +0 -0
  170. {dblift-2.1.1 → dblift-2.2.1}/core/migration/commands/info_command.py +0 -0
  171. {dblift-2.1.1 → dblift-2.2.1}/core/migration/commands/repair_command.py +0 -0
  172. {dblift-2.1.1 → dblift-2.2.1}/core/migration/commands/validate_command.py +0 -0
  173. {dblift-2.1.1 → dblift-2.2.1}/core/migration/encoding.py +0 -0
  174. {dblift-2.1.1 → dblift-2.2.1}/core/migration/executor/__init__.py +0 -0
  175. {dblift-2.1.1 → dblift-2.2.1}/core/migration/executor/migration_helpers.py +0 -0
  176. {dblift-2.1.1 → dblift-2.2.1}/core/migration/executor/placeholder_manager.py +0 -0
  177. {dblift-2.1.1 → dblift-2.2.1}/core/migration/executor/transaction_policy.py +0 -0
  178. {dblift-2.1.1 → dblift-2.2.1}/core/migration/executors/__init__.py +0 -0
  179. {dblift-2.1.1 → dblift-2.2.1}/core/migration/executors/base_executor.py +0 -0
  180. {dblift-2.1.1 → dblift-2.2.1}/core/migration/executors/executor_factory.py +0 -0
  181. {dblift-2.1.1 → dblift-2.2.1}/core/migration/executors/python_executor.py +0 -0
  182. {dblift-2.1.1 → dblift-2.2.1}/core/migration/executors/sql_executor.py +0 -0
  183. {dblift-2.1.1 → dblift-2.2.1}/core/migration/formats/__init__.py +0 -0
  184. {dblift-2.1.1 → dblift-2.2.1}/core/migration/formats/format_detector.py +0 -0
  185. {dblift-2.1.1 → dblift-2.2.1}/core/migration/formats/migration_format.py +0 -0
  186. {dblift-2.1.1 → dblift-2.2.1}/core/migration/history/__init__.py +0 -0
  187. {dblift-2.1.1 → dblift-2.2.1}/core/migration/history/migration_history_manager.py +0 -0
  188. {dblift-2.1.1 → dblift-2.2.1}/core/migration/journals/__init__.py +0 -0
  189. {dblift-2.1.1 → dblift-2.2.1}/core/migration/journals/migration_journal.py +0 -0
  190. {dblift-2.1.1 → dblift-2.2.1}/core/migration/migration.py +0 -0
  191. {dblift-2.1.1 → dblift-2.2.1}/core/migration/placeholders/__init__.py +0 -0
  192. {dblift-2.1.1 → dblift-2.2.1}/core/migration/placeholders/placeholder_service.py +0 -0
  193. {dblift-2.1.1 → dblift-2.2.1}/core/migration/rules/__init__.py +0 -0
  194. {dblift-2.1.1 → dblift-2.2.1}/core/migration/rules/migration_rules.py +0 -0
  195. {dblift-2.1.1 → dblift-2.2.1}/core/migration/scripting/__init__.py +0 -0
  196. {dblift-2.1.1 → dblift-2.2.1}/core/migration/scripting/migration_script_manager.py +0 -0
  197. {dblift-2.1.1 → dblift-2.2.1}/core/migration/scripting/undo_script_generator/__init__.py +0 -0
  198. {dblift-2.1.1 → dblift-2.2.1}/core/migration/scripting/undo_script_generator/_ddl_reversers.py +0 -0
  199. {dblift-2.1.1 → dblift-2.2.1}/core/migration/scripting/undo_script_generator/_dml_reversers.py +0 -0
  200. {dblift-2.1.1 → dblift-2.2.1}/core/migration/scripting/undo_script_generator/_extractors.py +0 -0
  201. {dblift-2.1.1 → dblift-2.2.1}/core/migration/scripting/undo_script_generator/_generator.py +0 -0
  202. {dblift-2.1.1 → dblift-2.2.1}/core/migration/scripting/undo_script_generator/_helpers.py +0 -0
  203. {dblift-2.1.1 → dblift-2.2.1}/core/migration/scripting/undo_script_generator/_models.py +0 -0
  204. {dblift-2.1.1 → dblift-2.2.1}/core/migration/scripting/undo_script_generator/_reversers.py +0 -0
  205. {dblift-2.1.1 → dblift-2.2.1}/core/migration/sql/__init__.py +0 -0
  206. {dblift-2.1.1 → dblift-2.2.1}/core/migration/sql/execution_statement.py +0 -0
  207. {dblift-2.1.1 → dblift-2.2.1}/core/migration/sql/sql_analyzer.py +0 -0
  208. {dblift-2.1.1 → dblift-2.2.1}/core/migration/sql/sql_execution_service.py +0 -0
  209. {dblift-2.1.1 → dblift-2.2.1}/core/migration/sql/statement_splitter.py +0 -0
  210. {dblift-2.1.1 → dblift-2.2.1}/core/migration/state/__init__.py +0 -0
  211. {dblift-2.1.1 → dblift-2.2.1}/core/migration/state/migration_data_service.py +0 -0
  212. {dblift-2.1.1 → dblift-2.2.1}/core/migration/state/migration_display_state.py +0 -0
  213. {dblift-2.1.1 → dblift-2.2.1}/core/migration/state/migration_formatter.py +0 -0
  214. {dblift-2.1.1 → dblift-2.2.1}/core/migration/state/migration_state.py +0 -0
  215. {dblift-2.1.1 → dblift-2.2.1}/core/migration/state/migration_state_manager.py +0 -0
  216. {dblift-2.1.1 → dblift-2.2.1}/core/migration/state/migration_state_service.py +0 -0
  217. {dblift-2.1.1 → dblift-2.2.1}/core/migration/ui/__init__.py +0 -0
  218. {dblift-2.1.1 → dblift-2.2.1}/core/migration/ui/display_formatters.py +0 -0
  219. {dblift-2.1.1 → dblift-2.2.1}/core/migration/ui/migration_analyzer.py +0 -0
  220. {dblift-2.1.1 → dblift-2.2.1}/core/migration/ui/migration_ui.py +0 -0
  221. {dblift-2.1.1 → dblift-2.2.1}/core/migration/ui/table_renderer.py +0 -0
  222. {dblift-2.1.1 → dblift-2.2.1}/core/migration/version_utils.py +0 -0
  223. {dblift-2.1.1 → dblift-2.2.1}/core/normalization/__init__.py +0 -0
  224. {dblift-2.1.1 → dblift-2.2.1}/core/normalization/dependency_resolver.py +0 -0
  225. {dblift-2.1.1 → dblift-2.2.1}/core/normalization/identifier_normalizer.py +0 -0
  226. {dblift-2.1.1 → dblift-2.2.1}/core/normalization/object_orderer.py +0 -0
  227. {dblift-2.1.1 → dblift-2.2.1}/core/normalization/type_constants.py +0 -0
  228. {dblift-2.1.1 → dblift-2.2.1}/core/normalization/type_mapper.py +0 -0
  229. {dblift-2.1.1 → dblift-2.2.1}/core/normalization/type_mappings.py +0 -0
  230. {dblift-2.1.1 → dblift-2.2.1}/core/normalization/type_normalizer.py +0 -0
  231. {dblift-2.1.1 → dblift-2.2.1}/core/seams/__init__.py +0 -0
  232. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/__init__.py +0 -0
  233. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/_base_parse_result.py +0 -0
  234. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/_base_sql_column.py +0 -0
  235. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/_base_sql_constraint.py +0 -0
  236. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/_base_sql_object.py +0 -0
  237. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/_base_sql_statement.py +0 -0
  238. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/base.py +0 -0
  239. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/constraint_validator.py +0 -0
  240. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/database_link.py +0 -0
  241. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/dialect.py +0 -0
  242. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/linked_server.py +0 -0
  243. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/module.py +0 -0
  244. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/partition.py +0 -0
  245. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/table_canonicalizer.py +0 -0
  246. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/table_options.py +0 -0
  247. {dblift-2.1.1 → dblift-2.2.1}/core/sql_model/view_options.py +0 -0
  248. {dblift-2.1.1 → dblift-2.2.1}/core/sql_parser/__init__.py +0 -0
  249. {dblift-2.1.1 → dblift-2.2.1}/core/sql_parser/_partition_handler.py +0 -0
  250. {dblift-2.1.1 → dblift-2.2.1}/core/sql_parser/_sqlglot_builders.py +0 -0
  251. {dblift-2.1.1 → dblift-2.2.1}/core/sql_parser/base_statement_parser.py +0 -0
  252. {dblift-2.1.1 → dblift-2.2.1}/core/sql_parser/base_tokenizer.py +0 -0
  253. {dblift-2.1.1 → dblift-2.2.1}/core/sql_parser/common/__init__.py +0 -0
  254. {dblift-2.1.1 → dblift-2.2.1}/core/sql_parser/common/base_parser.py +0 -0
  255. {dblift-2.1.1 → dblift-2.2.1}/core/sql_parser/dialects/__init__.py +0 -0
  256. {dblift-2.1.1 → dblift-2.2.1}/core/sql_parser/dialects/base_config.py +0 -0
  257. {dblift-2.1.1 → dblift-2.2.1}/core/sql_parser/enhanced_regex_parser.py +0 -0
  258. {dblift-2.1.1 → dblift-2.2.1}/core/sql_parser/hybrid_parser.py +0 -0
  259. {dblift-2.1.1 → dblift-2.2.1}/core/sql_parser/parser_context.py +0 -0
  260. {dblift-2.1.1 → dblift-2.2.1}/core/sql_parser/parser_factory.py +0 -0
  261. {dblift-2.1.1 → dblift-2.2.1}/core/sql_parser/parser_interface.py +0 -0
  262. {dblift-2.1.1 → dblift-2.2.1}/core/sql_parser/sqlglot_parser.py +0 -0
  263. {dblift-2.1.1 → dblift-2.2.1}/core/sql_parser/tokens.py +0 -0
  264. {dblift-2.1.1 → dblift-2.2.1}/core/sql_parser/unified_regex_parser.py +0 -0
  265. {dblift-2.1.1 → dblift-2.2.1}/core/sql_validator/_checksum_validator.py +0 -0
  266. {dblift-2.1.1 → dblift-2.2.1}/core/sql_validator/_flyway_compatibility.py +0 -0
  267. {dblift-2.1.1 → dblift-2.2.1}/core/sql_validator/_migration_filter.py +0 -0
  268. {dblift-2.1.1 → dblift-2.2.1}/core/sql_validator/_sql_syntax_validator.py +0 -0
  269. {dblift-2.1.1 → dblift-2.2.1}/core/sql_validator/_strict_mode_validator.py +0 -0
  270. {dblift-2.1.1 → dblift-2.2.1}/core/state/sql_script_formatter.py +0 -0
  271. {dblift-2.1.1 → dblift-2.2.1}/core/state/sql_statement.py +0 -0
  272. {dblift-2.1.1 → dblift-2.2.1}/core/utils/__init__.py +0 -0
  273. {dblift-2.1.1 → dblift-2.2.1}/core/utils/database_url_parser.py +0 -0
  274. {dblift-2.1.1 → dblift-2.2.1}/core/utils/metadata_helpers.py +0 -0
  275. {dblift-2.1.1 → dblift-2.2.1}/core/utils/row_access.py +0 -0
  276. {dblift-2.1.1 → dblift-2.2.1}/core/utils/string_utils.py +0 -0
  277. {dblift-2.1.1 → dblift-2.2.1}/core/utils/url_masking.py +0 -0
  278. {dblift-2.1.1 → dblift-2.2.1}/db/__init__.py +0 -0
  279. {dblift-2.1.1 → dblift-2.2.1}/db/base_provider.py +0 -0
  280. {dblift-2.1.1 → dblift-2.2.1}/db/constants.py +0 -0
  281. {dblift-2.1.1 → dblift-2.2.1}/db/error.py +0 -0
  282. {dblift-2.1.1 → dblift-2.2.1}/db/error_handler.py +0 -0
  283. {dblift-2.1.1 → dblift-2.2.1}/db/exceptions.py +0 -0
  284. {dblift-2.1.1 → dblift-2.2.1}/db/native_connection_manager.py +0 -0
  285. {dblift-2.1.1 → dblift-2.2.1}/db/object_naming.py +0 -0
  286. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/__init__.py +0 -0
  287. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/base_history_manager.py +0 -0
  288. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/base_locking_manager.py +0 -0
  289. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/base_query_executor.py +0 -0
  290. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/base_schema_operations.py +0 -0
  291. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/base_snapshot_manager.py +0 -0
  292. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/base_undo_manager.py +0 -0
  293. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/__init__.py +0 -0
  294. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/config.py +0 -0
  295. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/cosmosdb/__init__.py +0 -0
  296. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/cosmosdb/_sdk.py +0 -0
  297. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/cosmosdb/connection_manager.py +0 -0
  298. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/cosmosdb/history_manager.py +0 -0
  299. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/cosmosdb/locking_manager.py +0 -0
  300. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/cosmosdb/schema_operations.py +0 -0
  301. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/introspection/__init__.py +0 -0
  302. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/parser/__init__.py +0 -0
  303. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/parser/cosmosdb_regex_parser.py +0 -0
  304. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/plugin.py +0 -0
  305. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/provider.py +0 -0
  306. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/sdk_translator/__init__.py +0 -0
  307. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/sdk_translator/_executor.py +0 -0
  308. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/sdk_translator/_executors.py +0 -0
  309. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/sdk_translator/_parsing.py +0 -0
  310. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/sdk_translator/_script_generation.py +0 -0
  311. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/sdk_translator/_translator.py +0 -0
  312. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/cosmosdb/sdk_translator/_translators.py +0 -0
  313. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/db2/__init__.py +0 -0
  314. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/db2/config.py +0 -0
  315. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/db2/db2/__init__.py +0 -0
  316. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/db2/db2/history_manager.py +0 -0
  317. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/db2/db2/locking_manager.py +0 -0
  318. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/db2/introspection/__init__.py +0 -0
  319. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/db2/parser/__init__.py +0 -0
  320. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/db2/parser/db2_regex_parser.py +0 -0
  321. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/db2/parser/parser_config.py +0 -0
  322. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/db2/plugin.py +0 -0
  323. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/db2/sqlalchemy_url.py +0 -0
  324. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/mariadb/__init__.py +0 -0
  325. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/mariadb/plugin.py +0 -0
  326. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/mariadb/provider.py +0 -0
  327. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/mariadb/quirks.py +0 -0
  328. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/mysql/__init__.py +0 -0
  329. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/mysql/config.py +0 -0
  330. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/mysql/introspection/__init__.py +0 -0
  331. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/mysql/mysql/__init__.py +0 -0
  332. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/mysql/mysql/history_manager.py +0 -0
  333. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/mysql/mysql/locking_manager.py +0 -0
  334. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/mysql/mysql/schema_operations.py +0 -0
  335. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/mysql/parser/__init__.py +0 -0
  336. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/mysql/parser/mysql_regex_parser.py +0 -0
  337. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/mysql/parser/mysql_statement_parser.py +0 -0
  338. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/mysql/parser/mysql_tokenizer.py +0 -0
  339. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/mysql/parser/parser_config.py +0 -0
  340. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/mysql/plugin.py +0 -0
  341. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/mysql/provider.py +0 -0
  342. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/mysql/sqlalchemy_url.py +0 -0
  343. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/__init__.py +0 -0
  344. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/config.py +0 -0
  345. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/introspection/__init__.py +0 -0
  346. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/introspection/oracle_utils.py +0 -0
  347. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/oracle/__init__.py +0 -0
  348. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/oracle/dbms_output.py +0 -0
  349. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/oracle/history_manager.py +0 -0
  350. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/oracle/locking_manager.py +0 -0
  351. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/oracle/schema_operations.py +0 -0
  352. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/parser/__init__.py +0 -0
  353. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/parser/_comments.py +0 -0
  354. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/parser/_object_extractor.py +0 -0
  355. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/parser/_plsql_block.py +0 -0
  356. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/parser/_sqlplus.py +0 -0
  357. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/parser/_statement_splitter.py +0 -0
  358. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/parser/oracle_parser.py +0 -0
  359. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/parser/oracle_statement_parser.py +0 -0
  360. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/parser/oracle_tokenizer.py +0 -0
  361. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/parser/parser_config.py +0 -0
  362. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/parser/sqlplus_context.py +0 -0
  363. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/plugin.py +0 -0
  364. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/provider.py +0 -0
  365. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/oracle/sqlalchemy_url.py +0 -0
  366. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/postgresql/__init__.py +0 -0
  367. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/postgresql/_provider_query_executor.py +0 -0
  368. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/postgresql/config.py +0 -0
  369. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/postgresql/introspection/__init__.py +0 -0
  370. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/postgresql/parser/__init__.py +0 -0
  371. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/postgresql/parser/parser_config.py +0 -0
  372. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/postgresql/parser/postgresql_regex_parser.py +0 -0
  373. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/postgresql/parser/postgresql_statement_parser.py +0 -0
  374. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/postgresql/parser/postgresql_tokenizer.py +0 -0
  375. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/postgresql/plugin.py +0 -0
  376. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/postgresql/postgresql/__init__.py +0 -0
  377. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/postgresql/postgresql/history_manager.py +0 -0
  378. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/postgresql/postgresql/locking_manager.py +0 -0
  379. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/postgresql/postgresql/schema_operations.py +0 -0
  380. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/postgresql/provider.py +0 -0
  381. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/postgresql/sqlalchemy_url.py +0 -0
  382. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlite/__init__.py +0 -0
  383. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlite/config.py +0 -0
  384. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlite/introspection/__init__.py +0 -0
  385. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlite/parser/__init__.py +0 -0
  386. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlite/parser/parser_config.py +0 -0
  387. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlite/parser/sqlite_regex_parser.py +0 -0
  388. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlite/plugin.py +0 -0
  389. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlite/provider.py +0 -0
  390. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlite/sqlalchemy_url.py +0 -0
  391. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlite/sqlite/__init__.py +0 -0
  392. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlite/sqlite/connection_manager.py +0 -0
  393. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlite/sqlite/history_manager.py +0 -0
  394. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlite/sqlite/locking_manager.py +0 -0
  395. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlite/sqlite/query_executor.py +0 -0
  396. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlite/sqlite/schema_operations.py +0 -0
  397. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlserver/__init__.py +0 -0
  398. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlserver/config.py +0 -0
  399. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlserver/introspection/__init__.py +0 -0
  400. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlserver/parser/__init__.py +0 -0
  401. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlserver/parser/parser_config.py +0 -0
  402. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlserver/parser/sqlserver_regex_parser.py +0 -0
  403. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlserver/parser/sqlserver_statement_parser.py +0 -0
  404. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlserver/parser/sqlserver_tokenizer.py +0 -0
  405. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlserver/parser/tsql_batch_separator.py +0 -0
  406. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlserver/plugin.py +0 -0
  407. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlserver/provider.py +0 -0
  408. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlserver/sqlserver/__init__.py +0 -0
  409. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlserver/sqlserver/history_manager.py +0 -0
  410. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlserver/sqlserver/locking_manager.py +0 -0
  411. {dblift-2.1.1 → dblift-2.2.1}/db/plugins/sqlserver/sqlserver/schema_operations.py +0 -0
  412. {dblift-2.1.1 → dblift-2.2.1}/db/provider_capabilities.py +0 -0
  413. {dblift-2.1.1 → dblift-2.2.1}/db/provider_interfaces.py +0 -0
  414. {dblift-2.1.1 → dblift-2.2.1}/db/provider_registry.py +0 -0
  415. {dblift-2.1.1 → dblift-2.2.1}/db/sqlalchemy_provider.py +0 -0
  416. {dblift-2.1.1 → dblift-2.2.1}/db/value_utils.py +0 -0
  417. {dblift-2.1.1 → dblift-2.2.1}/dblift.egg-info/dependency_links.txt +0 -0
  418. {dblift-2.1.1 → dblift-2.2.1}/dblift.egg-info/entry_points.txt +0 -0
  419. {dblift-2.1.1 → dblift-2.2.1}/dblift.egg-info/requires.txt +0 -0
  420. {dblift-2.1.1 → dblift-2.2.1}/dblift.egg-info/top_level.txt +0 -0
  421. {dblift-2.1.1 → dblift-2.2.1}/integrations/__init__.py +0 -0
  422. {dblift-2.1.1 → dblift-2.2.1}/integrations/django/__init__.py +0 -0
  423. {dblift-2.1.1 → dblift-2.2.1}/integrations/django/_client.py +0 -0
  424. {dblift-2.1.1 → dblift-2.2.1}/integrations/django/_engine.py +0 -0
  425. {dblift-2.1.1 → dblift-2.2.1}/integrations/django/apps.py +0 -0
  426. {dblift-2.1.1 → dblift-2.2.1}/integrations/django/checks.py +0 -0
  427. {dblift-2.1.1 → dblift-2.2.1}/integrations/django/management/__init__.py +0 -0
  428. {dblift-2.1.1 → dblift-2.2.1}/integrations/django/management/commands/__init__.py +0 -0
  429. {dblift-2.1.1 → dblift-2.2.1}/integrations/django/management/commands/dblift_info.py +0 -0
  430. {dblift-2.1.1 → dblift-2.2.1}/integrations/django/management/commands/dblift_migrate.py +0 -0
  431. {dblift-2.1.1 → dblift-2.2.1}/integrations/django/management/commands/dblift_validate.py +0 -0
  432. {dblift-2.1.1 → dblift-2.2.1}/integrations/fastapi.py +0 -0
  433. {dblift-2.1.1 → dblift-2.2.1}/integrations/flask.py +0 -0
  434. {dblift-2.1.1 → dblift-2.2.1}/integrations/opentelemetry.py +0 -0
  435. {dblift-2.1.1 → dblift-2.2.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dblift
3
- Version: 2.1.1
3
+ Version: 2.2.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
@@ -0,0 +1,16 @@
1
+ """Public API for DBLift library integration.
2
+
3
+ This module provides a clean Python API for using DBLift programmatically,
4
+ enabling integration with IDEs, CI/CD pipelines, and other development tools.
5
+ """
6
+
7
+ from api.client import DBLiftClient
8
+ from api.events import EventEmitter, EventType
9
+ from api.migrations import MigrationContext
10
+
11
+ __all__ = [ # noqa: F822
12
+ "DBLiftClient",
13
+ "EventEmitter",
14
+ "EventType",
15
+ "MigrationContext",
16
+ ]
@@ -1,4 +1,8 @@
1
- """Private operation helpers for OSS :mod:`api.client`."""
1
+ """Private operation helpers for :mod:`api.client`.
2
+
3
+ Keep large operation bodies out of ``DBLiftClient`` so the public client class
4
+ stays readable while preserving the same public methods and behavior.
5
+ """
2
6
 
3
7
  from __future__ import annotations
4
8
 
@@ -19,7 +23,7 @@ def _heuristic_statement_count_from_sql(sql_text: str) -> int:
19
23
 
20
24
 
21
25
  def _apply_sql_script_warning_scan(
22
- result: GenerateUndoScriptResult,
26
+ result: Union[Any, GenerateUndoScriptResult],
23
27
  sql_text: str,
24
28
  ) -> None:
25
29
  """Set manual-review flag and collect per-line warnings from generated SQL text."""
@@ -1,7 +1,6 @@
1
1
  """Main client for programmatic access to DBLift."""
2
2
 
3
3
  from functools import wraps
4
- from importlib import import_module
5
4
  from pathlib import Path
6
5
  from types import TracebackType
7
6
  from typing import (
@@ -25,10 +24,7 @@ from api._client_factory import (
25
24
  normalize_migrations_dirs,
26
25
  resolve_config_or_raise,
27
26
  )
28
- from api._client_operations import (
29
- generate_undo_script_operation,
30
- generate_undo_scripts_operation,
31
- )
27
+ from api._client_operations import generate_undo_script_operation, generate_undo_scripts_operation
32
28
  from api.events import EventEmitter, EventType, use_client_emitter
33
29
  from config import DbliftConfig
34
30
  from core.logger.results import (
@@ -44,6 +40,7 @@ from core.logger.results import (
44
40
  )
45
41
  from core.migration.executor.migration_executor import MigrationExecutor
46
42
  from core.seams.event_listeners import attach_registered_listeners
43
+ from core.seams.feature_loading import load_feature_extensions
47
44
  from db.base_provider import BaseProvider
48
45
  from db.provider_interfaces import ConnectionProvider, TransactionalProvider
49
46
 
@@ -119,6 +116,13 @@ class DBLiftClient:
119
116
  log_file: Optional log file path; omit to keep ``config`` values
120
117
  **kwargs: Additional configuration options
121
118
  """
119
+ # Feature registrations from installed add-on packages must load for
120
+ # every client construction path, not just CLI startup — otherwise the
121
+ # runtime-check and tier-resolver seams would silently no-op for
122
+ # API-only usage. Idempotent (module-level once-flag), so double-loading
123
+ # with the CLI's own call is harmless.
124
+ load_feature_extensions()
125
+
122
126
  # Resolve config before logger so defaults come from merged config (e.g. from file).
123
127
  config = resolve_config_or_raise(provider, config)
124
128
 
@@ -43,7 +43,9 @@ if _builtin_conflicts:
43
43
  _COMMAND_HANDLERS.update(_extension_handlers)
44
44
  del _extension_handlers, _builtin_conflicts
45
45
 
46
- _AVAILABLE_COMMANDS = list(_COMMAND_HANDLERS.keys()) + ["db"] + list(load_terminal_commands())
46
+ _AVAILABLE_COMMANDS = (
47
+ list(_COMMAND_HANDLERS.keys()) + ["db", "config"] + list(load_terminal_commands())
48
+ )
47
49
 
48
50
 
49
51
  def execute_single_command(
@@ -35,15 +35,37 @@ _SUBCOMMAND_BOOLEAN_FLAGS = frozenset(
35
35
  "--clean-disabled",
36
36
  "--clean-enabled",
37
37
  "--dry-run",
38
+ "--generate-sql",
39
+ "--ignore-unmanaged",
40
+ "--include-drops",
41
+ "--keep-container",
42
+ "--managed-only",
38
43
  "--mark-as-executed",
44
+ "--no-performance",
39
45
  "--show-sql",
46
+ "--rehearse-rollback",
47
+ "--skip-replay",
40
48
  "--skip-validation",
49
+ "--skip-validate-sql",
50
+ "--split-by-type",
41
51
  "--strict",
52
+ "--unmanaged-only",
42
53
  "--validate-only",
43
54
  }
44
55
  )
45
56
 
46
57
 
58
+ def _command_handler_attr(command: Optional[str], attr_name: str, default: Any = None) -> Any:
59
+ if not command:
60
+ return default
61
+ from cli._command_handlers import _COMMAND_HANDLERS
62
+
63
+ handler = _COMMAND_HANDLERS.get(command)
64
+ if handler is None:
65
+ return default
66
+ return getattr(handler, attr_name, default)
67
+
68
+
47
69
  def _extract_commands_from_argv(
48
70
  argv_list: List[str],
49
71
  available_commands: List[str],
@@ -257,16 +279,21 @@ def _load_and_merge_config(args: argparse.Namespace, log: Any) -> Any:
257
279
  db_overrides["schema"] = args.database_schema
258
280
 
259
281
  if db_overrides:
260
- # Resolve secret URIs in CLI overrides.
261
- from config.secrets._resolver import resolve_secret_refs
282
+ command = getattr(args, "command", None)
283
+ commands_list = getattr(args, "commands_list", None) or ([command] if command else [])
284
+ is_offline = len(commands_list) == 1 and bool(
285
+ _command_handler_attr(command, "_dblift_skip_secret_resolution", False)
286
+ )
287
+ if not is_offline:
288
+ from config.secrets._resolver import resolve_secret_refs
262
289
 
263
- try:
264
- db_overrides = resolve_secret_refs({"database": db_overrides}, config.secrets).get(
265
- "database", db_overrides
266
- )
267
- except SecretsResolutionError as e:
268
- print(f"Error: {e}", file=sys.stderr)
269
- sys.exit(1)
290
+ try:
291
+ db_overrides = resolve_secret_refs({"database": db_overrides}, config.secrets).get(
292
+ "database", db_overrides
293
+ )
294
+ except SecretsResolutionError as e:
295
+ print(f"Error: {e}", file=sys.stderr)
296
+ sys.exit(1)
270
297
  config.database = ConfigBuilder.merge_database_overrides(config.database, db_overrides)
271
298
 
272
299
  if log:
@@ -321,7 +348,7 @@ def _validate_db_config(
321
348
  if commands and commands[0] == "db":
322
349
  return
323
350
 
324
- migration_commands = [
351
+ migration_commands = {
325
352
  "migrate",
326
353
  "undo",
327
354
  "clean",
@@ -330,7 +357,9 @@ def _validate_db_config(
330
357
  "repair",
331
358
  "import-flyway",
332
359
  "baseline",
333
- ]
360
+ }
361
+ if _command_handler_attr(args.command, "_dblift_validate_db_config", False):
362
+ migration_commands.add(args.command)
334
363
  if args.command not in migration_commands:
335
364
  return
336
365
 
@@ -13,7 +13,8 @@ dispatch in ``cli/main.py`` re-derive the same predicate:
13
13
  else:
14
14
  ctx.log.info(payload) # routed through ConsoleLog
15
15
 
16
- That duplication has already caused banner-routing regressions. ADR-0005 added the
16
+ That duplication has already caused two regressions (PR 158 banner fix
17
+ + PR-01 machine-format scope). ADR-0005 added the
17
18
  `MACHINE_READABLE_FORMATS` set as a single source of truth; this
18
19
  module does the same for the *routing* decision itself.
19
20
 
@@ -106,6 +106,57 @@ def _make_history_table_parent() -> argparse.ArgumentParser:
106
106
  return p
107
107
 
108
108
 
109
+ def _add_registry_flags(parser: argparse.ArgumentParser) -> None:
110
+ """Emit a --flag for every registry property that lacks one.
111
+
112
+ Skips properties that are cli_only, cli_exempt, nested (database.*), or
113
+ already covered by a legacy flag recorded in cli_aliases. Ensures any NEW
114
+ persistent property added to the registry automatically gets a CLI flag,
115
+ so the CLI surface can never silently drift from config/env again.
116
+ """
117
+ from config.property_registry import PROPERTY_REGISTRY
118
+
119
+ deferred_specs = {"max_snapshots", "snapshot_table"}
120
+
121
+ # Collect option strings across the WHOLE tree (root + every subparser), not
122
+ # just the root parser. Many registry properties (e.g. --tags,
123
+ # --target-version, --snapshot-table) intentionally live only on specific
124
+ # subcommands; a root-only ``existing`` set would treat them as missing and
125
+ # emit a duplicate root flag, colliding with the subparser dest. This helper
126
+ # therefore runs AFTER subparsers are registered so the tree walk sees them.
127
+ existing: set[str] = set()
128
+
129
+ def _collect(p: argparse.ArgumentParser) -> None:
130
+ for action in p._actions:
131
+ existing.update(action.option_strings)
132
+ choices = getattr(action, "choices", None)
133
+ if isinstance(choices, dict):
134
+ for sub in choices.values():
135
+ if isinstance(sub, argparse.ArgumentParser):
136
+ _collect(sub)
137
+
138
+ _collect(parser)
139
+ for spec in PROPERTY_REGISTRY:
140
+ if spec.cli_only or spec.cli_exempt or "." in spec.name:
141
+ continue
142
+ if spec.name in deferred_specs:
143
+ continue
144
+ if spec.cli_aliases:
145
+ continue # legacy flag (e.g. --table, --strict) already provides the surface
146
+ if spec.cli in existing:
147
+ continue
148
+ if spec.type == "bool":
149
+ parser.add_argument(
150
+ spec.cli, dest=spec.name, action="store_true", default=None, help=spec.help
151
+ )
152
+ elif spec.type == "int":
153
+ parser.add_argument(spec.cli, dest=spec.name, type=int, default=None, help=spec.help)
154
+ elif spec.type == "float":
155
+ parser.add_argument(spec.cli, dest=spec.name, type=float, default=None, help=spec.help)
156
+ else:
157
+ parser.add_argument(spec.cli, dest=spec.name, default=None, help=spec.help)
158
+
159
+
109
160
  def _make_snapshot_table_parent() -> argparse.ArgumentParser:
110
161
  """Parent parser for explicit snapshot storage commands."""
111
162
  p = argparse.ArgumentParser(add_help=False)
@@ -155,7 +206,7 @@ def _make_filter_parent() -> argparse.ArgumentParser:
155
206
 
156
207
  # NOTE: ``--target-version`` is intentionally NOT extracted into a parent
157
208
  # parser. Its help text is genuinely command-specific (migrate / undo /
158
- # diff each describe a different intent) and unifying it would degrade
209
+ # validate each describe a different intent) and unifying it would degrade
159
210
  # `--help` output. Each subparser adds it explicitly in
160
211
  # ``_add_diff_and_target_options`` so the user-facing string stays
161
212
  # accurate. See Bugbot review on PR-09.
@@ -185,13 +236,12 @@ def _add_baseline_options(baseline_parser: argparse.ArgumentParser) -> None:
185
236
 
186
237
 
187
238
  def _add_diff_and_target_options(
188
- diff_parser: argparse.ArgumentParser | None,
189
239
  migrate_parser: argparse.ArgumentParser,
190
240
  undo_parser: argparse.ArgumentParser,
191
241
  validate_parser: argparse.ArgumentParser,
192
242
  clean_parser: argparse.ArgumentParser,
193
243
  ) -> None:
194
- """Configure diff/migrate/undo/validate/clean subcommand-specific options.
244
+ """Configure migrate/undo/validate/clean subcommand-specific options.
195
245
 
196
246
  ``--target-version`` is added per-command (rather than via a shared
197
247
  parent parser) because each command has a meaningfully different
@@ -243,6 +293,21 @@ def _add_diff_and_target_options(
243
293
  )
244
294
 
245
295
 
296
+ def _register_builtin_command_parsers(
297
+ parser: argparse.ArgumentParser,
298
+ ) -> list[argparse.ArgumentParser]:
299
+ """Register first-party command parsers that remain in the OSS CLI."""
300
+ subparser_actions = [
301
+ action for action in parser._actions if isinstance(action, argparse._SubParsersAction)
302
+ ]
303
+ if not subparser_actions:
304
+ return []
305
+
306
+ registered: list[argparse.ArgumentParser] = []
307
+
308
+ return registered
309
+
310
+
246
311
  def create_parser(
247
312
  exit_on_error: bool = True, suppress_errors: bool = False
248
313
  ) -> argparse.ArgumentParser:
@@ -307,6 +372,11 @@ def create_parser(
307
372
  ),
308
373
  )
309
374
  parser.add_argument("--dry-run", action="store_true", help="Dry run mode")
375
+ parser.add_argument(
376
+ "--installed-by",
377
+ dest="installed_by",
378
+ help="Value recorded in the installed_by column (default: database username)",
379
+ )
310
380
  parser.add_argument("--log-dir", default="logs", help="Log directory")
311
381
  parser.add_argument("--log-format", default="text", help="Log format (text, json, html)")
312
382
  parser.add_argument(
@@ -389,10 +459,10 @@ def create_parser(
389
459
  default="flyway_schema_history",
390
460
  help="Source Flyway schema history table name (default: flyway_schema_history)",
391
461
  )
392
- builtin_extension_parsers: list[argparse.ArgumentParser] = []
462
+ builtin_extension_parsers = _register_builtin_command_parsers(parser)
393
463
  # Configure arguments via extracted functions
394
464
  _add_baseline_options(baseline_parser)
395
- _add_diff_and_target_options(None, migrate_parser, undo_parser, validate_parser, clean_parser)
465
+ _add_diff_and_target_options(migrate_parser, undo_parser, validate_parser, clean_parser)
396
466
  # info --format option (JSON output for scripting)
397
467
  info_parser.add_argument(
398
468
  "--format",
@@ -404,7 +474,21 @@ def create_parser(
404
474
  db_parser = subparsers.add_parser("db", help="Database utility commands")
405
475
  db_subparsers = db_parser.add_subparsers(dest="db_command", required=True)
406
476
  setup_db_utils_parser(db_subparsers)
477
+ # Configuration introspection: `dblift config --list` prints every persistent
478
+ # property and its three surfaces (config key / env var / CLI flag). Distinct
479
+ # from the global `--config <path>` option — a subcommand named ``config`` and
480
+ # an optional ``--config`` flag do not collide in argparse.
481
+ config_parser = subparsers.add_parser("config", help="Inspect dblift configuration")
482
+ config_parser.add_argument(
483
+ "--list",
484
+ action="store_true",
485
+ help="List all properties and how to set them (config key / env var / CLI flag)",
486
+ )
407
487
  import_module("cli.extensions").load_command_extensions(parser)
488
+ # Emit registry-derived flags LAST, after every subparser (built-in and
489
+ # extension) is registered, so the tree walk in _add_registry_flags can see
490
+ # subcommand-only flags and skip them instead of shadowing them on the root.
491
+ _add_registry_flags(parser)
408
492
  if suppress_errors:
409
493
  all_subparsers = [
410
494
  migrate_parser,
@@ -0,0 +1 @@
1
+ """First-party CLI command handlers that own their own dispatch."""
@@ -0,0 +1,48 @@
1
+ """``dblift config --list`` — print every persistent property and its surfaces."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, Dict, List
6
+
7
+ from config.property_registry import PROPERTY_REGISTRY, PropertySpec
8
+ from core.logger.console import render_records_table
9
+
10
+
11
+ def _cli_display(spec: PropertySpec) -> str:
12
+ """The real CLI flag for a property: '(none)' if cli-exempt, the legacy
13
+ alias if one is registered, else the derived flag."""
14
+ if spec.cli_exempt:
15
+ return "(none)"
16
+ if spec.cli_aliases:
17
+ return str(spec.cli_aliases[0])
18
+ return spec.cli
19
+
20
+
21
+ def build_property_table() -> List[Dict[str, str]]:
22
+ """Return one row per registry property with its config key, env var, CLI flag, and default."""
23
+ rows: List[Dict[str, str]] = []
24
+ for spec in PROPERTY_REGISTRY:
25
+ rows.append(
26
+ {
27
+ "name": spec.name,
28
+ "config": spec.name,
29
+ "env": spec.env,
30
+ "cli": _cli_display(spec),
31
+ "default": "" if spec.default is None else str(spec.default),
32
+ }
33
+ )
34
+ return rows
35
+
36
+
37
+ def run_config_command(args: Any) -> int:
38
+ """Print the property/env/CLI surface table for ``dblift config --list``; return 0."""
39
+ rows = build_property_table()
40
+ table = render_records_table(
41
+ [("PROPERTY", "left"), ("ENV VAR", "left"), ("CLI FLAG", "left")],
42
+ [[r["name"], r["env"], r["cli"]] for r in rows],
43
+ title="dblift configuration properties",
44
+ )
45
+ print(
46
+ table
47
+ ) # lint: allow-print config --list self-documentation (pre-CommandOutput short-circuit)
48
+ return 0
@@ -12,11 +12,9 @@ from dataclasses import dataclass, field
12
12
  from pathlib import Path
13
13
  from typing import Any, Dict, List, Optional
14
14
 
15
- from core.features import FeatureTier
16
-
17
- # Flyway-compatible migration filename patterns used to skip non-migration
18
- # SQL files when scanning a directory (e.g. leftover temp files, schema
19
- # dumps) so only intentional migration scripts are
15
+ # Flyway-compatible migration filename patterns — used by SQL-file validation to
16
+ # skip non-migration SQL files when scanning a directory (e.g. leftover
17
+ # temp files, schema dumps) so only intentional migration scripts are
20
18
  # checked. Explicitly-listed files are always validated regardless of name.
21
19
  _MIGRATION_FILENAME_RE = re.compile(
22
20
  r"^[VRUBvrub][\d_.]*__.*\.sql$",
@@ -61,9 +59,21 @@ class CliCommandContext:
61
59
  # Migration configuration
62
60
  placeholders: Dict[str, Any] = field(default_factory=dict)
63
61
  dir_recursive_map: Dict[Path, bool] = field(default_factory=dict)
64
- # License tier for feature-level gates. execute_single_command supplies
65
- # the real CLI-resolved tier; the default keeps direct handler tests terse.
66
- license_tier: FeatureTier = FeatureTier.ENTERPRISE
62
+ # License tier for feature-level gates. Opaque to OSS (see
63
+ # core.seams.tier_resolver) execute_single_command supplies the real
64
+ # CLI-resolved tier; paid-tier handler tests must pass their own tier
65
+ # explicitly since OSS no longer has a permissive default to fall back on.
66
+ license_tier: Any = None
67
+
68
+
69
+ @dataclass
70
+ class ConfigOnlyClient:
71
+ """Config-only stand-in for commands that do not need a live provider."""
72
+
73
+ config: Any
74
+
75
+
76
+ ValidateSqlConfigClient = ConfigOnlyClient
67
77
 
68
78
 
69
79
  def _set_command_completed(log: Any, result: Any, command_type: str) -> None:
@@ -92,7 +102,7 @@ def emit_rendered_output(
92
102
  ) -> None:
93
103
  """Dispatch a rendered command output to machine channel, logger, and/or file.
94
104
 
95
- Used by command handlers that follow the same machine/human/file
105
+ Shared by extension report handlers that follow the same machine/human/file
96
106
  dispatch pattern once the command-specific rendering is done.
97
107
  """
98
108
  if command_output.is_machine_format:
@@ -111,7 +121,7 @@ def emit_rendered_output(
111
121
 
112
122
 
113
123
  def _extract_version_filters(args: Any) -> tuple[Any, Any, Any, Any, Any]:
114
- """Extract version/tag filter arguments common to migrate, undo, validate, info, diff handlers.
124
+ """Extract version/tag filter arguments common to filtered migration handlers.
115
125
 
116
126
  Returns:
117
127
  Tuple (target_version, versions, exclude_versions, tags, exclude_tags),
@@ -50,13 +50,9 @@ from cli._config_helpers import ( # noqa: F401
50
50
  _validate_log_format_for_cli,
51
51
  )
52
52
  from cli._output import CommandOutput, from_args
53
- from cli._parser_setup import ( # noqa: F401
54
- _add_baseline_options,
55
- _add_diff_and_target_options,
56
- create_parser,
57
- parse_with_selective_errors,
58
- )
53
+ from cli._parser_setup import create_parser, parse_with_selective_errors
59
54
  from cli.extensions import load_terminal_commands
55
+ from core.seams.feature_loading import load_feature_extensions
60
56
 
61
57
  # Module-level placeholder; main() uses a local 'log' variable (no global declaration)
62
58
  log = None
@@ -102,6 +98,13 @@ _GLOBAL_ONLY_ARGS: List[str] = [
102
98
  "--quiet",
103
99
  "-q",
104
100
  "--no-progress",
101
+ # Root-only value flags. They live only on the root parser, so — like the
102
+ # other root-only value flags above — they must be classified global or the
103
+ # argv preprocessor relocates them past the subcommand token and the
104
+ # subparser rejects them as "unrecognized arguments". Covered by
105
+ # tests/unit/cli/test_global_only_args_completeness.py.
106
+ "--installed-by",
107
+ "--max-snapshots",
105
108
  ]
106
109
 
107
110
  # Tool-level flag aliases for subcommands that take their own version-like
@@ -154,6 +157,7 @@ def main() -> None:
154
157
  from core.logger.console import install_rich_traceback
155
158
 
156
159
  install_rich_traceback()
160
+ load_feature_extensions()
157
161
 
158
162
  ctx = _parse_argv_and_load_config(sys.argv[1:])
159
163
  command_output = _setup_logging_and_output(ctx)
@@ -227,12 +231,22 @@ def _parse_argv_and_load_config(argv: List[str]) -> _CliContext:
227
231
  if not commands and hasattr(args, "command"):
228
232
  commands = [args.command]
229
233
 
234
+ # `dblift config --list` is offline self-documentation: it reads only the
235
+ # property registry, so it short-circuits here — before any config/db load —
236
+ # exactly like the `db` subcommand path below. Listing is the command's only
237
+ # behaviour today, so it runs whether or not --list was passed.
238
+ if commands and commands[0] == "config":
239
+ from cli.commands.config_command import run_config_command
240
+
241
+ sys.exit(run_config_command(args))
242
+
230
243
  log = LogFactory.get_log("Dblift")
231
244
  parser = create_parser()
232
245
  # Validate log format before any config load so bogus --log-format fails with argparse
233
246
  # UX (and so db/* commands are covered — _validate_db_config skips early for "db").
234
247
  _validate_log_format_for_cli(args, parser)
235
- # Attach the full command list so load_config can see chained invocations.
248
+ # Attach the full command list so config loading can distinguish
249
+ # single-command config-only flows from chained invocations.
236
250
  args.commands_list = commands
237
251
  config = None if commands[0] == "db" else _load_and_merge_config(args, log)
238
252
  _validate_db_config(args, config, parser, commands)
@@ -258,6 +272,15 @@ def _build_terminal_args(
258
272
  return args
259
273
 
260
274
 
275
+ def _command_handler_attr(command: Optional[str], attr_name: str, default: Any = None) -> Any:
276
+ if not command:
277
+ return default
278
+ handler = _COMMAND_HANDLERS.get(command)
279
+ if handler is None:
280
+ return default
281
+ return getattr(handler, attr_name, default)
282
+
283
+
261
284
  def _setup_logging_and_output(ctx: _CliContext) -> CommandOutput:
262
285
  """Phase 3: configure logging, build :class:`CommandOutput`.
263
286
 
@@ -287,12 +310,26 @@ def _setup_logging_and_output(ctx: _CliContext) -> CommandOutput:
287
310
  assert ctx.config is not None
288
311
  ctx.log = _configure_logging(ctx.args, ctx.config, ctx.parser)
289
312
 
313
+ _apply_configured_output_format(ctx)
314
+
290
315
  # Banner routing is centralised in :class:`cli._output.CommandOutput`
291
316
  # (ADR-0008 supersedes ADR-0005's suppression approach). Machine
292
317
  # mode routes the banner to stderr; human mode keeps it on stdout.
293
318
  return from_args(ctx.args)
294
319
 
295
320
 
321
+ def _apply_configured_output_format(ctx: _CliContext) -> None:
322
+ """Use handler-provided config defaults before top-level banner routing."""
323
+ if len(ctx.commands) != 1 or getattr(ctx.args, "format", None):
324
+ return
325
+ resolver = _command_handler_attr(ctx.commands[0], "_dblift_configured_output_format")
326
+ if not callable(resolver):
327
+ return
328
+ output_format = resolver(ctx.args, ctx.config)
329
+ if output_format:
330
+ ctx.args.format = output_format
331
+
332
+
296
333
  def _dispatch_command(ctx: _CliContext, command_output: CommandOutput) -> int:
297
334
  """Phase 4: build full workflow context and run the command loop.
298
335
 
@@ -316,7 +353,6 @@ def _dispatch_command(ctx: _CliContext, command_output: CommandOutput) -> int:
316
353
  ctx.log.debug(f"Using placeholders: {placeholders}")
317
354
 
318
355
  ctx.config.journal_enabled = True
319
- ctx.config.journal_dir = None
320
356
  if getattr(ctx.args, "strict", False):
321
357
  ctx.config.strict_mode = True
322
358
  ctx.log.info(
@@ -344,6 +380,13 @@ def _dispatch_command(ctx: _CliContext, command_output: CommandOutput) -> int:
344
380
  # in base_command does not re-emit it (it also has no format awareness).
345
381
  if main_header:
346
382
  base_command._console_main_header_printed = True # type: ignore[attr-defined]
383
+ for command in ctx.commands:
384
+ handler = _COMMAND_HANDLERS.get(command)
385
+ if handler is None:
386
+ continue
387
+ command_module = sys.modules.get(handler.__module__)
388
+ if command_module is not None:
389
+ command_module._console_main_header_printed = True # type: ignore[attr-defined]
347
390
 
348
391
  for cmd_index, command in enumerate(ctx.commands):
349
392
  if len(ctx.commands) > 1 and cmd_index > 0:
@@ -199,9 +199,9 @@ def _apply_url_overrides(cls: Type["BaseDatabaseConfig"], data: Dict[str, Any])
199
199
  if url_lower.startswith("jdbc:"):
200
200
  raise ValueError("Legacy database URLs are no longer supported; use a SQLAlchemy URL")
201
201
  # _allow_incomplete is set when the URL could not be parsed (e.g. an
202
- # unresolved secret URI in offline mode). Skip hydration/inference so
203
- # an unresolved secret URI doesn't mutate fields before a connection
204
- # is opened.
202
+ # unresolved secret URI in offline mode). Skip hydration/inference so that
203
+ # `dblift plan` with `database.url: vault://...` doesn't mutate fields from
204
+ # the secret URI before a connection is opened.
205
205
  if data.get("_allow_incomplete"):
206
206
  return
207
207
  if ProviderRegistry.is_native_dialect(db_type):