dblift 2.2.2__tar.gz → 2.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (442) hide show
  1. {dblift-2.2.2 → dblift-2.3.0}/PKG-INFO +5 -2
  2. {dblift-2.2.2 → dblift-2.3.0}/core/migration/commands/repair_command.py +17 -1
  3. dblift-2.3.0/db/plugins/duckdb/__init__.py +12 -0
  4. dblift-2.3.0/db/plugins/duckdb/config.py +81 -0
  5. dblift-2.3.0/db/plugins/duckdb/parser/__init__.py +5 -0
  6. dblift-2.3.0/db/plugins/duckdb/parser/duckdb_regex_parser.py +180 -0
  7. dblift-2.3.0/db/plugins/duckdb/parser/parser_config.py +203 -0
  8. dblift-2.3.0/db/plugins/duckdb/plugin.py +22 -0
  9. dblift-2.3.0/db/plugins/duckdb/provider.py +368 -0
  10. dblift-2.3.0/db/plugins/duckdb/quirks.py +96 -0
  11. dblift-2.3.0/db/plugins/duckdb/sqlalchemy_url.py +30 -0
  12. {dblift-2.2.2 → dblift-2.3.0}/db/sqlalchemy_provider.py +6 -0
  13. {dblift-2.2.2 → dblift-2.3.0}/dblift.egg-info/PKG-INFO +5 -2
  14. {dblift-2.2.2 → dblift-2.3.0}/dblift.egg-info/SOURCES.txt +9 -0
  15. {dblift-2.2.2 → dblift-2.3.0}/dblift.egg-info/entry_points.txt +1 -0
  16. {dblift-2.2.2 → dblift-2.3.0}/dblift.egg-info/requires.txt +5 -1
  17. {dblift-2.2.2 → dblift-2.3.0}/pyproject.toml +4 -2
  18. {dblift-2.2.2 → dblift-2.3.0}/LICENSE +0 -0
  19. {dblift-2.2.2 → dblift-2.3.0}/README.md +0 -0
  20. {dblift-2.2.2 → dblift-2.3.0}/api/__init__.py +0 -0
  21. {dblift-2.2.2 → dblift-2.3.0}/api/_cli_support.py +0 -0
  22. {dblift-2.2.2 → dblift-2.3.0}/api/_client_factory.py +0 -0
  23. {dblift-2.2.2 → dblift-2.3.0}/api/_client_operations.py +0 -0
  24. {dblift-2.2.2 → dblift-2.3.0}/api/_engine_config.py +0 -0
  25. {dblift-2.2.2 → dblift-2.3.0}/api/async_client.py +0 -0
  26. {dblift-2.2.2 → dblift-2.3.0}/api/client.py +0 -0
  27. {dblift-2.2.2 → dblift-2.3.0}/api/events.py +0 -0
  28. {dblift-2.2.2 → dblift-2.3.0}/api/migrations.py +0 -0
  29. {dblift-2.2.2 → dblift-2.3.0}/api/py.typed +0 -0
  30. {dblift-2.2.2 → dblift-2.3.0}/cli/__init__.py +0 -0
  31. {dblift-2.2.2 → dblift-2.3.0}/cli/_command_handlers.py +0 -0
  32. {dblift-2.2.2 → dblift-2.3.0}/cli/_config_helpers.py +0 -0
  33. {dblift-2.2.2 → dblift-2.3.0}/cli/_constants.py +0 -0
  34. {dblift-2.2.2 → dblift-2.3.0}/cli/_output.py +0 -0
  35. {dblift-2.2.2 → dblift-2.3.0}/cli/_parser_setup.py +0 -0
  36. {dblift-2.2.2 → dblift-2.3.0}/cli/commands/__init__.py +0 -0
  37. {dblift-2.2.2 → dblift-2.3.0}/cli/commands/config_command.py +0 -0
  38. {dblift-2.2.2 → dblift-2.3.0}/cli/db_utils.py +0 -0
  39. {dblift-2.2.2 → dblift-2.3.0}/cli/extensions.py +0 -0
  40. {dblift-2.2.2 → dblift-2.3.0}/cli/handlers/__init__.py +0 -0
  41. {dblift-2.2.2 → dblift-2.3.0}/cli/handlers/_shared.py +0 -0
  42. {dblift-2.2.2 → dblift-2.3.0}/cli/handlers/baseline.py +0 -0
  43. {dblift-2.2.2 → dblift-2.3.0}/cli/handlers/clean.py +0 -0
  44. {dblift-2.2.2 → dblift-2.3.0}/cli/handlers/import_flyway.py +0 -0
  45. {dblift-2.2.2 → dblift-2.3.0}/cli/handlers/info.py +0 -0
  46. {dblift-2.2.2 → dblift-2.3.0}/cli/handlers/migrate.py +0 -0
  47. {dblift-2.2.2 → dblift-2.3.0}/cli/handlers/repair.py +0 -0
  48. {dblift-2.2.2 → dblift-2.3.0}/cli/handlers/undo.py +0 -0
  49. {dblift-2.2.2 → dblift-2.3.0}/cli/handlers/validate.py +0 -0
  50. {dblift-2.2.2 → dblift-2.3.0}/cli/main.py +0 -0
  51. {dblift-2.2.2 → dblift-2.3.0}/config/__init__.py +0 -0
  52. {dblift-2.2.2 → dblift-2.3.0}/config/_credential_masking.py +0 -0
  53. {dblift-2.2.2 → dblift-2.3.0}/config/_subclasses/__init__.py +0 -0
  54. {dblift-2.2.2 → dblift-2.3.0}/config/_subclasses/dummy_config.py +0 -0
  55. {dblift-2.2.2 → dblift-2.3.0}/config/_url_builder_mixin.py +0 -0
  56. {dblift-2.2.2 → dblift-2.3.0}/config/config_builder.py +0 -0
  57. {dblift-2.2.2 → dblift-2.3.0}/config/database_config.py +0 -0
  58. {dblift-2.2.2 → dblift-2.3.0}/config/dblift_config.py +0 -0
  59. {dblift-2.2.2 → dblift-2.3.0}/config/errors.py +0 -0
  60. {dblift-2.2.2 → dblift-2.3.0}/config/property_registry.py +0 -0
  61. {dblift-2.2.2 → dblift-2.3.0}/config/secrets/__init__.py +0 -0
  62. {dblift-2.2.2 → dblift-2.3.0}/config/secrets/_cache.py +0 -0
  63. {dblift-2.2.2 → dblift-2.3.0}/config/secrets/_provider_base.py +0 -0
  64. {dblift-2.2.2 → dblift-2.3.0}/config/secrets/_registry.py +0 -0
  65. {dblift-2.2.2 → dblift-2.3.0}/config/secrets/_resolver.py +0 -0
  66. {dblift-2.2.2 → dblift-2.3.0}/config/secrets/_secrets_config.py +0 -0
  67. {dblift-2.2.2 → dblift-2.3.0}/core/__init__.py +0 -0
  68. {dblift-2.2.2 → dblift-2.3.0}/core/constants.py +0 -0
  69. {dblift-2.2.2 → dblift-2.3.0}/core/dialect_boundary.py +0 -0
  70. {dblift-2.2.2 → dblift-2.3.0}/core/exceptions.py +0 -0
  71. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/__init__.py +0 -0
  72. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/_column_enricher.py +0 -0
  73. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/_partition_enricher.py +0 -0
  74. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/_schema_orchestrator.py +0 -0
  75. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/_utils.py +0 -0
  76. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/_vendor_property_applier.py +0 -0
  77. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/base_introspector.py +0 -0
  78. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/extractors/__init__.py +0 -0
  79. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/extractors/base_extractor.py +0 -0
  80. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/extractors/column_extractor.py +0 -0
  81. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/extractors/constraint_extractor.py +0 -0
  82. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/extractors/index_extractor.py +0 -0
  83. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/extractors/misc_extractor.py +0 -0
  84. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/extractors/procedure_extractor.py +0 -0
  85. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/extractors/sequence_extractor.py +0 -0
  86. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/extractors/table_extractor.py +0 -0
  87. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/extractors/trigger_extractor.py +0 -0
  88. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/extractors/view_extractor.py +0 -0
  89. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/introspector_factory.py +0 -0
  90. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/result.py +0 -0
  91. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/schema_introspector.py +0 -0
  92. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/vendor_queries_base.py +0 -0
  93. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/vendor_queries_factory.py +0 -0
  94. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/vendor_queries_protocols.py +0 -0
  95. {dblift-2.2.2 → dblift-2.3.0}/core/introspection/version_detector.py +0 -0
  96. {dblift-2.2.2 → dblift-2.3.0}/core/logger/__init__.py +0 -0
  97. {dblift-2.2.2 → dblift-2.3.0}/core/logger/_base.py +0 -0
  98. {dblift-2.2.2 → dblift-2.3.0}/core/logger/_factory.py +0 -0
  99. {dblift-2.2.2 → dblift-2.3.0}/core/logger/_formatters.py +0 -0
  100. {dblift-2.2.2 → dblift-2.3.0}/core/logger/_levels.py +0 -0
  101. {dblift-2.2.2 → dblift-2.3.0}/core/logger/_multi.py +0 -0
  102. {dblift-2.2.2 → dblift-2.3.0}/core/logger/_null.py +0 -0
  103. {dblift-2.2.2 → dblift-2.3.0}/core/logger/console.py +0 -0
  104. {dblift-2.2.2 → dblift-2.3.0}/core/logger/formatters/__init__.py +0 -0
  105. {dblift-2.2.2 → dblift-2.3.0}/core/logger/formatters/_formatter_impl.py +0 -0
  106. {dblift-2.2.2 → dblift-2.3.0}/core/logger/formatters/factory.py +0 -0
  107. {dblift-2.2.2 → dblift-2.3.0}/core/logger/formatters/formatter.py +0 -0
  108. {dblift-2.2.2 → dblift-2.3.0}/core/logger/formatters/htmlformatter.py +0 -0
  109. {dblift-2.2.2 → dblift-2.3.0}/core/logger/formatters/jsonformatter.py +0 -0
  110. {dblift-2.2.2 → dblift-2.3.0}/core/logger/log.py +0 -0
  111. {dblift-2.2.2 → dblift-2.3.0}/core/logger/results.py +0 -0
  112. {dblift-2.2.2 → dblift-2.3.0}/core/logger/templates/oldreport.html +0 -0
  113. {dblift-2.2.2 → dblift-2.3.0}/core/logger/templates/report.html +0 -0
  114. {dblift-2.2.2 → dblift-2.3.0}/core/migration/__init__.py +0 -0
  115. {dblift-2.2.2 → dblift-2.3.0}/core/migration/_type_match.py +0 -0
  116. {dblift-2.2.2 → dblift-2.3.0}/core/migration/clean_summary.py +0 -0
  117. {dblift-2.2.2 → dblift-2.3.0}/core/migration/commands/__init__.py +0 -0
  118. {dblift-2.2.2 → dblift-2.3.0}/core/migration/commands/_script_events.py +0 -0
  119. {dblift-2.2.2 → dblift-2.3.0}/core/migration/commands/base_command.py +0 -0
  120. {dblift-2.2.2 → dblift-2.3.0}/core/migration/commands/baseline_command.py +0 -0
  121. {dblift-2.2.2 → dblift-2.3.0}/core/migration/commands/clean_command.py +0 -0
  122. {dblift-2.2.2 → dblift-2.3.0}/core/migration/commands/import_flyway_command.py +0 -0
  123. {dblift-2.2.2 → dblift-2.3.0}/core/migration/commands/info_command.py +0 -0
  124. {dblift-2.2.2 → dblift-2.3.0}/core/migration/commands/migrate_command.py +0 -0
  125. {dblift-2.2.2 → dblift-2.3.0}/core/migration/commands/undo_command.py +0 -0
  126. {dblift-2.2.2 → dblift-2.3.0}/core/migration/commands/validate_command.py +0 -0
  127. {dblift-2.2.2 → dblift-2.3.0}/core/migration/encoding.py +0 -0
  128. {dblift-2.2.2 → dblift-2.3.0}/core/migration/executor/__init__.py +0 -0
  129. {dblift-2.2.2 → dblift-2.3.0}/core/migration/executor/execution_engine.py +0 -0
  130. {dblift-2.2.2 → dblift-2.3.0}/core/migration/executor/migration_executor.py +0 -0
  131. {dblift-2.2.2 → dblift-2.3.0}/core/migration/executor/migration_helpers.py +0 -0
  132. {dblift-2.2.2 → dblift-2.3.0}/core/migration/executor/placeholder_manager.py +0 -0
  133. {dblift-2.2.2 → dblift-2.3.0}/core/migration/executor/transaction_policy.py +0 -0
  134. {dblift-2.2.2 → dblift-2.3.0}/core/migration/executors/__init__.py +0 -0
  135. {dblift-2.2.2 → dblift-2.3.0}/core/migration/executors/base_executor.py +0 -0
  136. {dblift-2.2.2 → dblift-2.3.0}/core/migration/executors/executor_factory.py +0 -0
  137. {dblift-2.2.2 → dblift-2.3.0}/core/migration/executors/python_executor.py +0 -0
  138. {dblift-2.2.2 → dblift-2.3.0}/core/migration/executors/sql_executor.py +0 -0
  139. {dblift-2.2.2 → dblift-2.3.0}/core/migration/formats/__init__.py +0 -0
  140. {dblift-2.2.2 → dblift-2.3.0}/core/migration/formats/format_detector.py +0 -0
  141. {dblift-2.2.2 → dblift-2.3.0}/core/migration/formats/migration_format.py +0 -0
  142. {dblift-2.2.2 → dblift-2.3.0}/core/migration/history/__init__.py +0 -0
  143. {dblift-2.2.2 → dblift-2.3.0}/core/migration/history/migration_history_manager.py +0 -0
  144. {dblift-2.2.2 → dblift-2.3.0}/core/migration/journals/__init__.py +0 -0
  145. {dblift-2.2.2 → dblift-2.3.0}/core/migration/journals/migration_journal.py +0 -0
  146. {dblift-2.2.2 → dblift-2.3.0}/core/migration/migration.py +0 -0
  147. {dblift-2.2.2 → dblift-2.3.0}/core/migration/placeholders/__init__.py +0 -0
  148. {dblift-2.2.2 → dblift-2.3.0}/core/migration/placeholders/placeholder_service.py +0 -0
  149. {dblift-2.2.2 → dblift-2.3.0}/core/migration/rules/__init__.py +0 -0
  150. {dblift-2.2.2 → dblift-2.3.0}/core/migration/rules/migration_rules.py +0 -0
  151. {dblift-2.2.2 → dblift-2.3.0}/core/migration/scripting/__init__.py +0 -0
  152. {dblift-2.2.2 → dblift-2.3.0}/core/migration/scripting/migration_script_manager.py +0 -0
  153. {dblift-2.2.2 → dblift-2.3.0}/core/migration/scripting/undo_script_generator/__init__.py +0 -0
  154. {dblift-2.2.2 → dblift-2.3.0}/core/migration/scripting/undo_script_generator/_ddl_reversers.py +0 -0
  155. {dblift-2.2.2 → dblift-2.3.0}/core/migration/scripting/undo_script_generator/_dml_reversers.py +0 -0
  156. {dblift-2.2.2 → dblift-2.3.0}/core/migration/scripting/undo_script_generator/_extractors.py +0 -0
  157. {dblift-2.2.2 → dblift-2.3.0}/core/migration/scripting/undo_script_generator/_generator.py +0 -0
  158. {dblift-2.2.2 → dblift-2.3.0}/core/migration/scripting/undo_script_generator/_helpers.py +0 -0
  159. {dblift-2.2.2 → dblift-2.3.0}/core/migration/scripting/undo_script_generator/_models.py +0 -0
  160. {dblift-2.2.2 → dblift-2.3.0}/core/migration/scripting/undo_script_generator/_reversers.py +0 -0
  161. {dblift-2.2.2 → dblift-2.3.0}/core/migration/sql/__init__.py +0 -0
  162. {dblift-2.2.2 → dblift-2.3.0}/core/migration/sql/execution_statement.py +0 -0
  163. {dblift-2.2.2 → dblift-2.3.0}/core/migration/sql/sql_analyzer.py +0 -0
  164. {dblift-2.2.2 → dblift-2.3.0}/core/migration/sql/sql_execution_service.py +0 -0
  165. {dblift-2.2.2 → dblift-2.3.0}/core/migration/sql/statement_splitter.py +0 -0
  166. {dblift-2.2.2 → dblift-2.3.0}/core/migration/state/__init__.py +0 -0
  167. {dblift-2.2.2 → dblift-2.3.0}/core/migration/state/migration_data_service.py +0 -0
  168. {dblift-2.2.2 → dblift-2.3.0}/core/migration/state/migration_display_state.py +0 -0
  169. {dblift-2.2.2 → dblift-2.3.0}/core/migration/state/migration_formatter.py +0 -0
  170. {dblift-2.2.2 → dblift-2.3.0}/core/migration/state/migration_state.py +0 -0
  171. {dblift-2.2.2 → dblift-2.3.0}/core/migration/state/migration_state_manager.py +0 -0
  172. {dblift-2.2.2 → dblift-2.3.0}/core/migration/state/migration_state_service.py +0 -0
  173. {dblift-2.2.2 → dblift-2.3.0}/core/migration/ui/__init__.py +0 -0
  174. {dblift-2.2.2 → dblift-2.3.0}/core/migration/ui/data_collector.py +0 -0
  175. {dblift-2.2.2 → dblift-2.3.0}/core/migration/ui/display_formatters.py +0 -0
  176. {dblift-2.2.2 → dblift-2.3.0}/core/migration/ui/migration_analyzer.py +0 -0
  177. {dblift-2.2.2 → dblift-2.3.0}/core/migration/ui/migration_ui.py +0 -0
  178. {dblift-2.2.2 → dblift-2.3.0}/core/migration/ui/table_renderer.py +0 -0
  179. {dblift-2.2.2 → dblift-2.3.0}/core/migration/version_utils.py +0 -0
  180. {dblift-2.2.2 → dblift-2.3.0}/core/normalization/__init__.py +0 -0
  181. {dblift-2.2.2 → dblift-2.3.0}/core/normalization/dependency_resolver.py +0 -0
  182. {dblift-2.2.2 → dblift-2.3.0}/core/normalization/identifier_normalizer.py +0 -0
  183. {dblift-2.2.2 → dblift-2.3.0}/core/normalization/object_orderer.py +0 -0
  184. {dblift-2.2.2 → dblift-2.3.0}/core/normalization/type_constants.py +0 -0
  185. {dblift-2.2.2 → dblift-2.3.0}/core/normalization/type_mapper.py +0 -0
  186. {dblift-2.2.2 → dblift-2.3.0}/core/normalization/type_mappings.py +0 -0
  187. {dblift-2.2.2 → dblift-2.3.0}/core/normalization/type_normalizer.py +0 -0
  188. {dblift-2.2.2 → dblift-2.3.0}/core/seams/__init__.py +0 -0
  189. {dblift-2.2.2 → dblift-2.3.0}/core/seams/capabilities.py +0 -0
  190. {dblift-2.2.2 → dblift-2.3.0}/core/seams/event_listeners.py +0 -0
  191. {dblift-2.2.2 → dblift-2.3.0}/core/seams/feature_loading.py +0 -0
  192. {dblift-2.2.2 → dblift-2.3.0}/core/seams/introspection.py +0 -0
  193. {dblift-2.2.2 → dblift-2.3.0}/core/seams/license_info.py +0 -0
  194. {dblift-2.2.2 → dblift-2.3.0}/core/seams/runtime_checks.py +0 -0
  195. {dblift-2.2.2 → dblift-2.3.0}/core/seams/sql_generators.py +0 -0
  196. {dblift-2.2.2 → dblift-2.3.0}/core/seams/tier_resolver.py +0 -0
  197. {dblift-2.2.2 → dblift-2.3.0}/core/sql_generator/__init__.py +0 -0
  198. {dblift-2.2.2 → dblift-2.3.0}/core/sql_generator/alter/__init__.py +0 -0
  199. {dblift-2.2.2 → dblift-2.3.0}/core/sql_generator/alter/alter_generator_factory.py +0 -0
  200. {dblift-2.2.2 → dblift-2.3.0}/core/sql_generator/alter/base_alter_generator.py +0 -0
  201. {dblift-2.2.2 → dblift-2.3.0}/core/sql_generator/alter_generator.py +0 -0
  202. {dblift-2.2.2 → dblift-2.3.0}/core/sql_generator/base_generator.py +0 -0
  203. {dblift-2.2.2 → dblift-2.3.0}/core/sql_generator/basic_table_ddl_generator.py +0 -0
  204. {dblift-2.2.2 → dblift-2.3.0}/core/sql_generator/dependency_analyzer.py +0 -0
  205. {dblift-2.2.2 → dblift-2.3.0}/core/sql_generator/diff_converters/__init__.py +0 -0
  206. {dblift-2.2.2 → dblift-2.3.0}/core/sql_generator/diff_converters/base_converter.py +0 -0
  207. {dblift-2.2.2 → dblift-2.3.0}/core/sql_generator/formatter.py +0 -0
  208. {dblift-2.2.2 → dblift-2.3.0}/core/sql_generator/generator_factory.py +0 -0
  209. {dblift-2.2.2 → dblift-2.3.0}/core/sql_generator/options.py +0 -0
  210. {dblift-2.2.2 → dblift-2.3.0}/core/sql_generator/script_organizer.py +0 -0
  211. {dblift-2.2.2 → dblift-2.3.0}/core/sql_generator/sql_generator.py +0 -0
  212. {dblift-2.2.2 → dblift-2.3.0}/core/sql_generator/sql_statement.py +0 -0
  213. {dblift-2.2.2 → dblift-2.3.0}/core/sql_generator/table_ddl_render.py +0 -0
  214. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/__init__.py +0 -0
  215. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/_base_parse_result.py +0 -0
  216. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/_base_sql_column.py +0 -0
  217. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/_base_sql_constraint.py +0 -0
  218. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/_base_sql_object.py +0 -0
  219. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/_base_sql_statement.py +0 -0
  220. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/base.py +0 -0
  221. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/constraint_validator.py +0 -0
  222. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/database_link.py +0 -0
  223. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/dialect.py +0 -0
  224. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/event.py +0 -0
  225. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/extension.py +0 -0
  226. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/foreign_data_wrapper.py +0 -0
  227. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/foreign_server.py +0 -0
  228. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/index.py +0 -0
  229. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/linked_server.py +0 -0
  230. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/module.py +0 -0
  231. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/package.py +0 -0
  232. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/partition.py +0 -0
  233. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/procedure.py +0 -0
  234. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/sequence.py +0 -0
  235. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/synonym.py +0 -0
  236. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/table.py +0 -0
  237. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/table_canonicalizer.py +0 -0
  238. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/table_options.py +0 -0
  239. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/trigger.py +0 -0
  240. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/user_defined_type.py +0 -0
  241. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/view.py +0 -0
  242. {dblift-2.2.2 → dblift-2.3.0}/core/sql_model/view_options.py +0 -0
  243. {dblift-2.2.2 → dblift-2.3.0}/core/sql_parser/__init__.py +0 -0
  244. {dblift-2.2.2 → dblift-2.3.0}/core/sql_parser/_partition_handler.py +0 -0
  245. {dblift-2.2.2 → dblift-2.3.0}/core/sql_parser/_sqlglot_builders.py +0 -0
  246. {dblift-2.2.2 → dblift-2.3.0}/core/sql_parser/base_statement_parser.py +0 -0
  247. {dblift-2.2.2 → dblift-2.3.0}/core/sql_parser/base_tokenizer.py +0 -0
  248. {dblift-2.2.2 → dblift-2.3.0}/core/sql_parser/common/__init__.py +0 -0
  249. {dblift-2.2.2 → dblift-2.3.0}/core/sql_parser/common/base_parser.py +0 -0
  250. {dblift-2.2.2 → dblift-2.3.0}/core/sql_parser/dialects/__init__.py +0 -0
  251. {dblift-2.2.2 → dblift-2.3.0}/core/sql_parser/dialects/base_config.py +0 -0
  252. {dblift-2.2.2 → dblift-2.3.0}/core/sql_parser/enhanced_regex_parser.py +0 -0
  253. {dblift-2.2.2 → dblift-2.3.0}/core/sql_parser/hybrid_parser.py +0 -0
  254. {dblift-2.2.2 → dblift-2.3.0}/core/sql_parser/parser_context.py +0 -0
  255. {dblift-2.2.2 → dblift-2.3.0}/core/sql_parser/parser_factory.py +0 -0
  256. {dblift-2.2.2 → dblift-2.3.0}/core/sql_parser/parser_interface.py +0 -0
  257. {dblift-2.2.2 → dblift-2.3.0}/core/sql_parser/sqlglot_parser.py +0 -0
  258. {dblift-2.2.2 → dblift-2.3.0}/core/sql_parser/tokens.py +0 -0
  259. {dblift-2.2.2 → dblift-2.3.0}/core/sql_parser/unified_regex_parser.py +0 -0
  260. {dblift-2.2.2 → dblift-2.3.0}/core/sql_validator/__init__.py +0 -0
  261. {dblift-2.2.2 → dblift-2.3.0}/core/sql_validator/_checksum_validator.py +0 -0
  262. {dblift-2.2.2 → dblift-2.3.0}/core/sql_validator/_flyway_compatibility.py +0 -0
  263. {dblift-2.2.2 → dblift-2.3.0}/core/sql_validator/_migration_filter.py +0 -0
  264. {dblift-2.2.2 → dblift-2.3.0}/core/sql_validator/_sql_syntax_validator.py +0 -0
  265. {dblift-2.2.2 → dblift-2.3.0}/core/sql_validator/_strict_mode_validator.py +0 -0
  266. {dblift-2.2.2 → dblift-2.3.0}/core/sql_validator/migration_validator.py +0 -0
  267. {dblift-2.2.2 → dblift-2.3.0}/core/state/sql_script_formatter.py +0 -0
  268. {dblift-2.2.2 → dblift-2.3.0}/core/state/sql_statement.py +0 -0
  269. {dblift-2.2.2 → dblift-2.3.0}/core/utils/__init__.py +0 -0
  270. {dblift-2.2.2 → dblift-2.3.0}/core/utils/database_url_parser.py +0 -0
  271. {dblift-2.2.2 → dblift-2.3.0}/core/utils/metadata_helpers.py +0 -0
  272. {dblift-2.2.2 → dblift-2.3.0}/core/utils/row_access.py +0 -0
  273. {dblift-2.2.2 → dblift-2.3.0}/core/utils/string_utils.py +0 -0
  274. {dblift-2.2.2 → dblift-2.3.0}/core/utils/url_masking.py +0 -0
  275. {dblift-2.2.2 → dblift-2.3.0}/db/__init__.py +0 -0
  276. {dblift-2.2.2 → dblift-2.3.0}/db/base_provider.py +0 -0
  277. {dblift-2.2.2 → dblift-2.3.0}/db/base_quirks.py +0 -0
  278. {dblift-2.2.2 → dblift-2.3.0}/db/constants.py +0 -0
  279. {dblift-2.2.2 → dblift-2.3.0}/db/dml_analysis.py +0 -0
  280. {dblift-2.2.2 → dblift-2.3.0}/db/error.py +0 -0
  281. {dblift-2.2.2 → dblift-2.3.0}/db/error_handler.py +0 -0
  282. {dblift-2.2.2 → dblift-2.3.0}/db/exceptions.py +0 -0
  283. {dblift-2.2.2 → dblift-2.3.0}/db/native_connection_manager.py +0 -0
  284. {dblift-2.2.2 → dblift-2.3.0}/db/object_naming.py +0 -0
  285. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/__init__.py +0 -0
  286. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/base_history_manager.py +0 -0
  287. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/base_locking_manager.py +0 -0
  288. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/base_query_executor.py +0 -0
  289. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/base_schema_operations.py +0 -0
  290. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/base_snapshot_manager.py +0 -0
  291. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/base_undo_manager.py +0 -0
  292. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/__init__.py +0 -0
  293. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/config.py +0 -0
  294. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/cosmosdb/__init__.py +0 -0
  295. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/cosmosdb/_sdk.py +0 -0
  296. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/cosmosdb/connection_manager.py +0 -0
  297. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/cosmosdb/history_manager.py +0 -0
  298. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/cosmosdb/locking_manager.py +0 -0
  299. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/cosmosdb/query_executor.py +0 -0
  300. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/cosmosdb/schema_operations.py +0 -0
  301. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/introspection/__init__.py +0 -0
  302. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/parser/__init__.py +0 -0
  303. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/parser/cosmosdb_regex_parser.py +0 -0
  304. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/plugin.py +0 -0
  305. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/provider.py +0 -0
  306. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/quirks.py +0 -0
  307. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/sdk_translator/__init__.py +0 -0
  308. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/sdk_translator/_executor.py +0 -0
  309. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/sdk_translator/_executors.py +0 -0
  310. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/sdk_translator/_parsing.py +0 -0
  311. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/sdk_translator/_script_generation.py +0 -0
  312. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/sdk_translator/_translator.py +0 -0
  313. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/cosmosdb/sdk_translator/_translators.py +0 -0
  314. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/db2/__init__.py +0 -0
  315. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/db2/config.py +0 -0
  316. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/db2/db2/__init__.py +0 -0
  317. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/db2/db2/history_manager.py +0 -0
  318. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/db2/db2/locking_manager.py +0 -0
  319. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/db2/db2/schema_operations.py +0 -0
  320. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/db2/introspection/__init__.py +0 -0
  321. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/db2/parser/__init__.py +0 -0
  322. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/db2/parser/db2_regex_parser.py +0 -0
  323. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/db2/parser/parser_config.py +0 -0
  324. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/db2/plugin.py +0 -0
  325. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/db2/provider.py +0 -0
  326. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/db2/quirks.py +0 -0
  327. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/db2/sqlalchemy_url.py +0 -0
  328. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/mariadb/__init__.py +0 -0
  329. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/mariadb/plugin.py +0 -0
  330. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/mariadb/provider.py +0 -0
  331. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/mariadb/quirks.py +0 -0
  332. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/mysql/__init__.py +0 -0
  333. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/mysql/config.py +0 -0
  334. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/mysql/introspection/__init__.py +0 -0
  335. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/mysql/mysql/__init__.py +0 -0
  336. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/mysql/mysql/history_manager.py +0 -0
  337. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/mysql/mysql/locking_manager.py +0 -0
  338. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/mysql/mysql/schema_operations.py +0 -0
  339. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/mysql/parser/__init__.py +0 -0
  340. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/mysql/parser/mysql_regex_parser.py +0 -0
  341. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/mysql/parser/mysql_statement_parser.py +0 -0
  342. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/mysql/parser/mysql_tokenizer.py +0 -0
  343. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/mysql/parser/parser_config.py +0 -0
  344. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/mysql/plugin.py +0 -0
  345. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/mysql/provider.py +0 -0
  346. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/mysql/quirks.py +0 -0
  347. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/mysql/sqlalchemy_url.py +0 -0
  348. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/__init__.py +0 -0
  349. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/config.py +0 -0
  350. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/introspection/__init__.py +0 -0
  351. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/introspection/oracle_utils.py +0 -0
  352. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/oracle/__init__.py +0 -0
  353. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/oracle/dbms_output.py +0 -0
  354. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/oracle/history_manager.py +0 -0
  355. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/oracle/locking_manager.py +0 -0
  356. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/oracle/schema_operations.py +0 -0
  357. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/parser/__init__.py +0 -0
  358. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/parser/_comments.py +0 -0
  359. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/parser/_object_extractor.py +0 -0
  360. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/parser/_plsql_block.py +0 -0
  361. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/parser/_sqlplus.py +0 -0
  362. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/parser/_statement_splitter.py +0 -0
  363. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/parser/oracle_parser.py +0 -0
  364. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/parser/oracle_statement_parser.py +0 -0
  365. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/parser/oracle_tokenizer.py +0 -0
  366. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/parser/parser_config.py +0 -0
  367. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/parser/sqlplus_context.py +0 -0
  368. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/plugin.py +0 -0
  369. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/provider.py +0 -0
  370. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/quirks.py +0 -0
  371. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/oracle/sqlalchemy_url.py +0 -0
  372. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/postgresql/__init__.py +0 -0
  373. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/postgresql/_provider_query_executor.py +0 -0
  374. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/postgresql/config.py +0 -0
  375. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/postgresql/introspection/__init__.py +0 -0
  376. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/postgresql/parser/__init__.py +0 -0
  377. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/postgresql/parser/parser_config.py +0 -0
  378. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/postgresql/parser/postgresql_regex_parser.py +0 -0
  379. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/postgresql/parser/postgresql_statement_parser.py +0 -0
  380. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/postgresql/parser/postgresql_tokenizer.py +0 -0
  381. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/postgresql/plugin.py +0 -0
  382. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/postgresql/postgresql/__init__.py +0 -0
  383. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/postgresql/postgresql/history_manager.py +0 -0
  384. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/postgresql/postgresql/locking_manager.py +0 -0
  385. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/postgresql/postgresql/schema_operations.py +0 -0
  386. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/postgresql/provider.py +0 -0
  387. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/postgresql/quirks.py +0 -0
  388. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/postgresql/sqlalchemy_url.py +0 -0
  389. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlite/__init__.py +0 -0
  390. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlite/config.py +0 -0
  391. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlite/introspection/__init__.py +0 -0
  392. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlite/parser/__init__.py +0 -0
  393. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlite/parser/parser_config.py +0 -0
  394. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlite/parser/sqlite_regex_parser.py +0 -0
  395. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlite/plugin.py +0 -0
  396. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlite/provider.py +0 -0
  397. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlite/quirks.py +0 -0
  398. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlite/sqlalchemy_url.py +0 -0
  399. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlite/sqlite/__init__.py +0 -0
  400. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlite/sqlite/connection_manager.py +0 -0
  401. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlite/sqlite/history_manager.py +0 -0
  402. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlite/sqlite/locking_manager.py +0 -0
  403. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlite/sqlite/query_executor.py +0 -0
  404. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlite/sqlite/schema_operations.py +0 -0
  405. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlserver/__init__.py +0 -0
  406. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlserver/config.py +0 -0
  407. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlserver/introspection/__init__.py +0 -0
  408. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlserver/parser/__init__.py +0 -0
  409. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlserver/parser/parser_config.py +0 -0
  410. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlserver/parser/sqlserver_regex_parser.py +0 -0
  411. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlserver/parser/sqlserver_statement_parser.py +0 -0
  412. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlserver/parser/sqlserver_tokenizer.py +0 -0
  413. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlserver/parser/tsql_batch_separator.py +0 -0
  414. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlserver/plugin.py +0 -0
  415. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlserver/provider.py +0 -0
  416. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlserver/quirks.py +0 -0
  417. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlserver/sqlalchemy_url.py +0 -0
  418. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlserver/sqlserver/__init__.py +0 -0
  419. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlserver/sqlserver/history_manager.py +0 -0
  420. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlserver/sqlserver/locking_manager.py +0 -0
  421. {dblift-2.2.2 → dblift-2.3.0}/db/plugins/sqlserver/sqlserver/schema_operations.py +0 -0
  422. {dblift-2.2.2 → dblift-2.3.0}/db/provider_capabilities.py +0 -0
  423. {dblift-2.2.2 → dblift-2.3.0}/db/provider_interfaces.py +0 -0
  424. {dblift-2.2.2 → dblift-2.3.0}/db/provider_registry.py +0 -0
  425. {dblift-2.2.2 → dblift-2.3.0}/db/value_utils.py +0 -0
  426. {dblift-2.2.2 → dblift-2.3.0}/dblift.egg-info/dependency_links.txt +0 -0
  427. {dblift-2.2.2 → dblift-2.3.0}/dblift.egg-info/top_level.txt +0 -0
  428. {dblift-2.2.2 → dblift-2.3.0}/integrations/__init__.py +0 -0
  429. {dblift-2.2.2 → dblift-2.3.0}/integrations/django/__init__.py +0 -0
  430. {dblift-2.2.2 → dblift-2.3.0}/integrations/django/_client.py +0 -0
  431. {dblift-2.2.2 → dblift-2.3.0}/integrations/django/_engine.py +0 -0
  432. {dblift-2.2.2 → dblift-2.3.0}/integrations/django/apps.py +0 -0
  433. {dblift-2.2.2 → dblift-2.3.0}/integrations/django/checks.py +0 -0
  434. {dblift-2.2.2 → dblift-2.3.0}/integrations/django/management/__init__.py +0 -0
  435. {dblift-2.2.2 → dblift-2.3.0}/integrations/django/management/commands/__init__.py +0 -0
  436. {dblift-2.2.2 → dblift-2.3.0}/integrations/django/management/commands/dblift_info.py +0 -0
  437. {dblift-2.2.2 → dblift-2.3.0}/integrations/django/management/commands/dblift_migrate.py +0 -0
  438. {dblift-2.2.2 → dblift-2.3.0}/integrations/django/management/commands/dblift_validate.py +0 -0
  439. {dblift-2.2.2 → dblift-2.3.0}/integrations/fastapi.py +0 -0
  440. {dblift-2.2.2 → dblift-2.3.0}/integrations/flask.py +0 -0
  441. {dblift-2.2.2 → dblift-2.3.0}/integrations/opentelemetry.py +0 -0
  442. {dblift-2.2.2 → dblift-2.3.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dblift
3
- Version: 2.2.2
3
+ Version: 2.3.0
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
@@ -66,6 +66,9 @@ Requires-Dist: pymssql>=2.3; extra == "sqlserver"
66
66
  Provides-Extra: db2
67
67
  Requires-Dist: ibm_db>=3.2; extra == "db2"
68
68
  Requires-Dist: ibm_db_sa>=0.4; extra == "db2"
69
+ Provides-Extra: duckdb
70
+ Requires-Dist: duckdb>=1.0; extra == "duckdb"
71
+ Requires-Dist: duckdb_engine>=0.13; extra == "duckdb"
69
72
  Provides-Extra: fastapi
70
73
  Requires-Dist: fastapi>=0.100; extra == "fastapi"
71
74
  Provides-Extra: flask
@@ -75,7 +78,7 @@ Requires-Dist: Django>=4.2; extra == "django"
75
78
  Provides-Extra: otel
76
79
  Requires-Dist: opentelemetry-api>=1.20; extra == "otel"
77
80
  Provides-Extra: all
78
- Requires-Dist: dblift[db2,mariadb,mysql,oracle,postgresql,sqlserver]; extra == "all"
81
+ Requires-Dist: dblift[db2,duckdb,mariadb,mysql,oracle,postgresql,sqlserver]; extra == "all"
79
82
  Dynamic: license-file
80
83
 
81
84
  # DBLift — Database release safety for Python teams
@@ -498,7 +498,23 @@ class RepairCommand(BaseCommand):
498
498
  params=[script_name],
499
499
  )
500
500
 
501
- if rows_affected > 0:
501
+ row_removed = rows_affected > 0
502
+ if (
503
+ rows_affected < 0
504
+ and not is_non_transactional
505
+ and hasattr(self.provider, "execute_query")
506
+ ):
507
+ # Some DBAPIs report an "unknown" rowcount of -1 for DML
508
+ # (e.g. duckdb_engine), so ``rows_affected > 0`` would wrongly
509
+ # read as "nothing removed". Verify the failed row is gone.
510
+ remaining = self.provider.execute_query(
511
+ f"SELECT 1 FROM {qualified_table} "
512
+ f"WHERE script = ? AND success = {false_literal}",
513
+ [script_name],
514
+ )
515
+ row_removed = not remaining
516
+
517
+ if row_removed:
502
518
  result.failed_migrations_removed = (
503
519
  getattr(result, "failed_migrations_removed", 0) + 1
504
520
  )
@@ -0,0 +1,12 @@
1
+ """DuckDB database provider plugin."""
2
+
3
+ __plugin_name__ = "duckdb"
4
+ __plugin_version__ = "1.0.0"
5
+ __plugin_description__ = "DuckDB database provider (SQLAlchemy via duckdb_engine)"
6
+ __plugin_dialects__ = ["duckdb"]
7
+ __plugin_transport__ = "native"
8
+ __plugin_class__ = "DuckDBProvider"
9
+
10
+ from .provider import DuckDBProvider
11
+
12
+ __all__ = ["DuckDBProvider"]
@@ -0,0 +1,81 @@
1
+ """DuckDB-specific ``BaseDatabaseConfig`` subclass."""
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Any, Dict, Optional
5
+
6
+ from config.database_config import BaseDatabaseConfig, register_database_type
7
+
8
+
9
+ # lint: allow-dialect-string: config type registration
10
+ @register_database_type("duckdb")
11
+ @dataclass
12
+ class DuckDBConfig(BaseDatabaseConfig):
13
+ """Configuration for DuckDB connections.
14
+
15
+ DuckDB is embedded/file-based (like SQLite): no server, no
16
+ credentials, ``"main"`` default schema. Connections resolve to a
17
+ file path (or ``:memory:``) rather than a host/port.
18
+ """
19
+
20
+ # DuckDB specific fields
21
+ path: Optional[str] = None # Path to the DuckDB file (or :memory: for in-memory)
22
+
23
+ def __post_init__(self) -> None:
24
+ """Resolve the file path from path/url/database and apply defaults."""
25
+ super().__post_init__()
26
+
27
+ if not self.path:
28
+ if self.url:
29
+ url = self.url
30
+ if url.startswith("duckdb://"):
31
+ # Match duckdb_engine's URL convention:
32
+ # duckdb:///rel.db (3 slashes) -> relative "rel.db"
33
+ # duckdb:////abs.db (4 slashes) -> absolute "/abs.db"
34
+ # duckdb:///:memory: -> ":memory:"
35
+ self.path = url[len("duckdb://") :]
36
+ if self.path in ("/:memory:", ":memory:"):
37
+ self.path = ":memory:"
38
+ elif self.path.startswith("//"):
39
+ self.path = "/" + self.path.lstrip("/")
40
+ elif self.path.startswith("/"):
41
+ self.path = self.path[1:]
42
+ else:
43
+ self.path = url
44
+ elif self.database:
45
+ self.path = self.database
46
+
47
+ if not self.path:
48
+ raise ValueError(
49
+ "Database path is required for DuckDB (use 'path' or 'database' field)"
50
+ )
51
+
52
+ # DuckDB's default schema is 'main'; no credentials required.
53
+ if not self.schema:
54
+ self.schema = "main"
55
+ if not self.username:
56
+ self.username = ""
57
+ if not self.password:
58
+ self.password = ""
59
+
60
+ def build_connection_string(self) -> str:
61
+ """Build a DuckDB connection string (file path)."""
62
+ return self.path or ""
63
+
64
+ def build_database_url(self) -> str:
65
+ """Build the DuckDB plugin-owned SQLAlchemy URL."""
66
+ from db.provider_registry import ProviderRegistry
67
+
68
+ return ProviderRegistry.build_sqlalchemy_url(self)
69
+
70
+ def to_dict(self) -> Dict[str, Any]:
71
+ """Convert to dictionary with DuckDB specific parameters."""
72
+ result = super().to_dict()
73
+ result["path"] = self.path
74
+ return result
75
+
76
+ def get_connection_props(self) -> Dict[str, str]:
77
+ """Get connection properties for DuckDB connection."""
78
+ props: Dict[str, str] = {}
79
+ if self.path:
80
+ props["path"] = self.path
81
+ return props
@@ -0,0 +1,5 @@
1
+ """DuckDB SQL parser module."""
2
+
3
+ from .duckdb_regex_parser import DuckDBRegexParser
4
+
5
+ __all__ = ["DuckDBRegexParser"]
@@ -0,0 +1,180 @@
1
+ """DuckDB-specific regex-based SQL parser.
2
+
3
+ DuckDB has a non-procedural DDL surface (no stored procedures/PL blocks),
4
+ so statement splitting only needs to respect string literals and comments
5
+ around the ``;`` separator.
6
+ """
7
+
8
+ from typing import Any, Dict, List, Optional
9
+
10
+ from core.sql_model.base import SqlObject, SqlObjectType
11
+ from core.sql_parser.enhanced_regex_parser import EnhancedRegexParser
12
+ from db.plugins.duckdb.parser.parser_config import DuckDBParserConfig
13
+
14
+
15
+ class DuckDBRegexParser(EnhancedRegexParser):
16
+ """DuckDB-specific regex-based SQL parser."""
17
+
18
+ def __init__(self, config: Optional[DuckDBParserConfig] = None):
19
+ """Initialize the DuckDB regex parser."""
20
+ duckdb_config = config or DuckDBParserConfig()
21
+ self.config = duckdb_config # type: ignore[assignment]
22
+ super().__init__(self.config)
23
+
24
+ def split_statements(self, sql_content: str, strict_tokenizer: bool = False) -> List[str]:
25
+ """Split SQL into statements, honouring string literals and comments."""
26
+ if not sql_content or not sql_content.strip():
27
+ return []
28
+
29
+ statements: List[str] = []
30
+ current: List[str] = []
31
+ in_string = False
32
+ in_ident = False # inside a "double-quoted" identifier
33
+ in_block_comment = False
34
+ in_line_comment = False
35
+
36
+ i = 0
37
+ content = sql_content
38
+ length = len(content)
39
+ while i < length:
40
+ char = content[i]
41
+ nxt = content[i + 1] if i + 1 < length else ""
42
+
43
+ if (
44
+ not in_string
45
+ and not in_ident
46
+ and not in_line_comment
47
+ and char == "/"
48
+ and nxt == "*"
49
+ ):
50
+ in_block_comment = True
51
+ current.append(char)
52
+ current.append(nxt)
53
+ i += 2
54
+ continue
55
+ if in_block_comment:
56
+ current.append(char)
57
+ if char == "*" and nxt == "/":
58
+ current.append(nxt)
59
+ in_block_comment = False
60
+ i += 2
61
+ continue
62
+ i += 1
63
+ continue
64
+
65
+ if not in_string and not in_ident and char == "-" and nxt == "-":
66
+ in_line_comment = True
67
+ current.append(char)
68
+ i += 1
69
+ continue
70
+ if in_line_comment:
71
+ current.append(char)
72
+ if char in "\r\n":
73
+ in_line_comment = False
74
+ i += 1
75
+ continue
76
+
77
+ # Double-quoted identifiers may contain ; and comment markers.
78
+ if char == '"' and not in_string and not in_ident:
79
+ in_ident = True
80
+ current.append(char)
81
+ i += 1
82
+ continue
83
+ if in_ident:
84
+ current.append(char)
85
+ if char == '"':
86
+ if nxt == '"': # escaped quote inside identifier
87
+ current.append(nxt)
88
+ i += 2
89
+ continue
90
+ in_ident = False
91
+ i += 1
92
+ continue
93
+
94
+ if char == "'" and not in_string:
95
+ in_string = True
96
+ current.append(char)
97
+ i += 1
98
+ continue
99
+ if in_string:
100
+ current.append(char)
101
+ if char == "'":
102
+ if nxt == "'": # escaped quote
103
+ current.append(nxt)
104
+ i += 2
105
+ continue
106
+ in_string = False
107
+ i += 1
108
+ continue
109
+
110
+ if char == ";":
111
+ current.append(char)
112
+ stmt = "".join(current).strip()
113
+ if stmt:
114
+ statements.append(stmt)
115
+ current = []
116
+ i += 1
117
+ continue
118
+
119
+ current.append(char)
120
+ i += 1
121
+
122
+ final = "".join(current).strip()
123
+ if final:
124
+ statements.append(final)
125
+ return statements
126
+
127
+ def classify_statement(self, statement: str) -> str:
128
+ """Classify a SQL statement as DDL / DML / QUERY / TCL / UNKNOWN."""
129
+ if not statement:
130
+ return "UNKNOWN"
131
+ statement = statement.strip()
132
+ cfg = self.config
133
+ if cfg.is_ddl_statement(statement): # type: ignore[attr-defined]
134
+ return "DDL"
135
+ if cfg.is_dml_statement(statement): # type: ignore[attr-defined]
136
+ return "DML"
137
+ if cfg.is_query_statement(statement): # type: ignore[attr-defined]
138
+ return "QUERY"
139
+ if statement.upper().startswith(("BEGIN", "COMMIT", "ROLLBACK", "ABORT", "START")):
140
+ return "TCL"
141
+ return "UNKNOWN"
142
+
143
+ def extract_objects(
144
+ self, sql_content: str, default_schema: Optional[str] = None
145
+ ) -> List[SqlObject]:
146
+ """Extract database objects from a statement via config object patterns."""
147
+ if not sql_content:
148
+ return []
149
+ objects: List[SqlObject] = []
150
+ statement = sql_content.strip()
151
+ for pattern_name, pattern in self.config.object_patterns.items():
152
+ match = pattern.search(statement)
153
+ if not match:
154
+ continue
155
+ non_none = [g for g in match.groups() if g is not None]
156
+ if not non_none:
157
+ continue
158
+ name = non_none[-1].strip('"')
159
+ schema = non_none[-2].strip('"') if len(non_none) >= 2 else None
160
+ objects.append(
161
+ SqlObject(
162
+ name=name,
163
+ object_type=self._object_type(pattern_name),
164
+ schema=schema or default_schema,
165
+ )
166
+ )
167
+ break
168
+ return objects
169
+
170
+ @staticmethod
171
+ def _object_type(pattern_name: str) -> SqlObjectType:
172
+ mapping: Dict[str, SqlObjectType] = {
173
+ "create_table": SqlObjectType.TABLE,
174
+ "create_view": SqlObjectType.VIEW,
175
+ "create_index": SqlObjectType.INDEX,
176
+ "create_sequence": SqlObjectType.SEQUENCE,
177
+ "alter_table": SqlObjectType.TABLE,
178
+ "drop_table": SqlObjectType.TABLE,
179
+ }
180
+ return mapping.get(pattern_name, SqlObjectType.UNKNOWN)
@@ -0,0 +1,203 @@
1
+ """DuckDB dialect configuration for regex-based parsing.
2
+
3
+ DuckDB SQL is PostgreSQL-like but with a small, non-procedural surface:
4
+ - No stored procedures / no PL blocks (user code lives outside the DB)
5
+ - Real schemas and sequences
6
+ - Double-quoted identifiers (no square brackets)
7
+ """
8
+
9
+ import re
10
+ from typing import Dict, List, Pattern, Set
11
+
12
+ from core.sql_parser.dialects.base_config import DialectConfig
13
+
14
+ _IDENT = r'(?:"[^"]*"|[a-zA-Z_][a-zA-Z0-9_]*)'
15
+ _QUALIFIED = rf"(?:{_IDENT}\.)?{_IDENT}"
16
+
17
+
18
+ class DuckDBParserConfig(DialectConfig):
19
+ """DuckDB dialect configuration for the regex parser framework."""
20
+
21
+ def __init__(self) -> None:
22
+ """Initialize DuckDB dialect configuration."""
23
+ super().__init__() # type: ignore[no-untyped-call]
24
+
25
+ self.identifier_quote_char = '"'
26
+ self.string_quote_char = "'"
27
+ self.supports_bracket_identifiers = False
28
+ self.statement_separator = ";"
29
+ self.line_comment_prefix = "--"
30
+ self.block_comment_start = "/*"
31
+ self.block_comment_end = "*/"
32
+
33
+ self.supports_dollar_quoting = False
34
+ self.supports_copy_statements = True # DuckDB COPY
35
+ self.supports_plpgsql_blocks = False
36
+ self.supports_cte_with_recursive = True
37
+ self.supports_on_conflict = True
38
+ self.supports_returning = True
39
+
40
+ self._compile_patterns()
41
+
42
+ def _compile_patterns(self) -> None:
43
+ def _create(kind: str) -> Pattern[str]:
44
+ return re.compile(
45
+ rf"\s*CREATE\s+(?:OR\s+REPLACE\s+)?{kind}\s+(?:IF\s+NOT\s+EXISTS\s+)?",
46
+ re.IGNORECASE,
47
+ )
48
+
49
+ def _drop(kind: str) -> Pattern[str]:
50
+ return re.compile(rf"\s*DROP\s+{kind}\s+(?:IF\s+EXISTS\s+)?", re.IGNORECASE)
51
+
52
+ self._ddl_patterns = {
53
+ "create_table": _create(r"(?:TEMP(?:ORARY)?\s+)?TABLE"),
54
+ "create_view": _create(r"(?:TEMP(?:ORARY)?\s+)?VIEW"),
55
+ "create_index": re.compile(
56
+ r"\s*CREATE\s+(?:UNIQUE\s+)?INDEX\s+(?:IF\s+NOT\s+EXISTS\s+)?", re.IGNORECASE
57
+ ),
58
+ "create_sequence": _create(r"(?:TEMP(?:ORARY)?\s+)?SEQUENCE"),
59
+ "create_schema": _create(r"SCHEMA"),
60
+ "create_type": _create(r"TYPE"),
61
+ "create_macro": _create(r"(?:TEMP(?:ORARY)?\s+)?MACRO"),
62
+ "alter_table": re.compile(r"\s*ALTER\s+TABLE\s+", re.IGNORECASE),
63
+ "drop_table": _drop("TABLE"),
64
+ "drop_view": _drop("VIEW"),
65
+ "drop_index": _drop("INDEX"),
66
+ "drop_sequence": _drop("SEQUENCE"),
67
+ "drop_schema": _drop("SCHEMA"),
68
+ "drop_type": _drop("TYPE"),
69
+ }
70
+
71
+ self._dml_patterns = {
72
+ "insert": re.compile(
73
+ r"\s*INSERT\s+(?:OR\s+(?:REPLACE|IGNORE)\s+)?INTO\s+", re.IGNORECASE
74
+ ),
75
+ "update": re.compile(r"\s*UPDATE\s+", re.IGNORECASE),
76
+ "delete": re.compile(r"\s*DELETE\s+FROM\s+", re.IGNORECASE),
77
+ "copy": re.compile(r"\s*COPY\s+", re.IGNORECASE),
78
+ }
79
+
80
+ self._query_patterns = {
81
+ "select": re.compile(r"\s*SELECT\s+", re.IGNORECASE),
82
+ "with": re.compile(r"\s*WITH\s+(?:RECURSIVE\s+)?", re.IGNORECASE),
83
+ "values": re.compile(r"\s*VALUES\s+", re.IGNORECASE),
84
+ "explain": re.compile(r"\s*EXPLAIN\s+", re.IGNORECASE),
85
+ }
86
+
87
+ def get_ddl_keywords(self) -> Set[str]:
88
+ return {"CREATE", "ALTER", "DROP", "ATTACH", "DETACH", "PRAGMA"}
89
+
90
+ def get_dml_keywords(self) -> Set[str]:
91
+ return {"INSERT", "UPDATE", "DELETE", "COPY"}
92
+
93
+ def get_query_keywords(self) -> Set[str]:
94
+ return {"SELECT", "WITH", "VALUES", "EXPLAIN"}
95
+
96
+ def get_transaction_keywords(self) -> Set[str]:
97
+ return {"BEGIN", "COMMIT", "ROLLBACK", "ABORT", "TRANSACTION", "START"}
98
+
99
+ def get_identifier_pattern(self) -> re.Pattern[str]:
100
+ return re.compile(_IDENT, re.IGNORECASE)
101
+
102
+ def get_qualified_identifier_pattern(self) -> re.Pattern[str]:
103
+ return re.compile(_QUALIFIED, re.IGNORECASE)
104
+
105
+ def get_string_literal_pattern(self) -> re.Pattern[str]:
106
+ return re.compile(r"'(?:[^']|'')*'", re.IGNORECASE)
107
+
108
+ def get_comment_pattern(self) -> re.Pattern[str]:
109
+ return re.compile(r"(?:--[^\r\n]*|/\*.*?\*/)", re.DOTALL)
110
+
111
+ def get_statement_separator_pattern(self) -> re.Pattern[str]:
112
+ return re.compile(r";")
113
+
114
+ def _matches_any(self, patterns: Dict[str, Pattern[str]], statement: str) -> bool:
115
+ statement = statement.strip()
116
+ return bool(statement) and any(p.match(statement) for p in patterns.values())
117
+
118
+ def is_ddl_statement(self, statement: str) -> bool:
119
+ return self._matches_any(self._ddl_patterns, statement)
120
+
121
+ def is_dml_statement(self, statement: str) -> bool:
122
+ return self._matches_any(self._dml_patterns, statement)
123
+
124
+ def is_query_statement(self, statement: str) -> bool:
125
+ return self._matches_any(self._query_patterns, statement)
126
+
127
+ def get_batch_separator(self) -> str:
128
+ return ";"
129
+
130
+ def supports_block_comments(self) -> bool:
131
+ return True
132
+
133
+ def supports_line_comments(self) -> bool:
134
+ return True
135
+
136
+ def get_block_keywords_for_splitting(self) -> Set[str]:
137
+ # DuckDB DDL is non-procedural; only transaction control uses BEGIN/END.
138
+ return set()
139
+
140
+ def normalize_identifier(self, identifier: str, is_quoted: bool = False) -> str:
141
+ if not identifier:
142
+ return identifier
143
+ if identifier.startswith('"') and identifier.endswith('"'):
144
+ return identifier[1:-1]
145
+ return identifier
146
+
147
+ @property
148
+ def name(self) -> str:
149
+ return "duckdb" # lint: allow-dialect-string: dialect dispatch
150
+
151
+ @property
152
+ def batch_separators(self) -> List[Pattern[str]]:
153
+ return [re.compile(r";")]
154
+
155
+ @property
156
+ def quoted_identifiers(self) -> List[Pattern[str]]:
157
+ return [re.compile(r'"[^"]*"')]
158
+
159
+ @property
160
+ def comment_patterns(self) -> List[Pattern[str]]:
161
+ return [re.compile(r"--[^\r\n]*"), re.compile(r"/\*.*?\*/", re.DOTALL)]
162
+
163
+ @property
164
+ def block_keywords(self) -> List[str]:
165
+ return ["CREATE", "ALTER", "DROP"]
166
+
167
+ @property
168
+ def ddl_patterns(self) -> Dict[str, Pattern[str]]:
169
+ return self._ddl_patterns
170
+
171
+ @property
172
+ def dml_patterns(self) -> Dict[str, Pattern[str]]:
173
+ return self._dml_patterns
174
+
175
+ @property
176
+ def query_patterns(self) -> Dict[str, Pattern[str]]:
177
+ return self._query_patterns
178
+
179
+ @property
180
+ def object_patterns(self) -> Dict[str, Pattern[str]]:
181
+ def _obj(kind: str) -> Pattern[str]:
182
+ return re.compile(
183
+ rf"CREATE\s+(?:OR\s+REPLACE\s+)?{kind}\s+(?:IF\s+NOT\s+EXISTS\s+)?"
184
+ rf"(?:({_IDENT})\.)?({_IDENT})",
185
+ re.IGNORECASE,
186
+ )
187
+
188
+ return {
189
+ "create_table": _obj(r"(?:TEMP(?:ORARY)?\s+)?TABLE"),
190
+ "create_view": _obj(r"(?:TEMP(?:ORARY)?\s+)?VIEW"),
191
+ "create_index": re.compile(
192
+ rf"CREATE\s+(?:UNIQUE\s+)?INDEX\s+(?:IF\s+NOT\s+EXISTS\s+)?"
193
+ rf"(?:({_IDENT})\.)?({_IDENT})",
194
+ re.IGNORECASE,
195
+ ),
196
+ "create_sequence": _obj(r"(?:TEMP(?:ORARY)?\s+)?SEQUENCE"),
197
+ "alter_table": re.compile(
198
+ rf"ALTER\s+TABLE\s+(?:({_IDENT})\.)?({_IDENT})", re.IGNORECASE
199
+ ),
200
+ "drop_table": re.compile(
201
+ rf"DROP\s+TABLE\s+(?:IF\s+EXISTS\s+)?(?:({_IDENT})\.)?({_IDENT})", re.IGNORECASE
202
+ ),
203
+ }
@@ -0,0 +1,22 @@
1
+ """Entry-point declaration for the DuckDB plugin."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from db.plugins.duckdb.config import DuckDBConfig
6
+ from db.plugins.duckdb.provider import DuckDBProvider
7
+ from db.plugins.duckdb.quirks import DuckDBQuirks
8
+ from db.plugins.duckdb.sqlalchemy_url import build_sqlalchemy_url
9
+ from db.provider_registry import PluginInfo
10
+
11
+ PLUGIN: PluginInfo = PluginInfo(
12
+ name="duckdb",
13
+ version="1.0.0",
14
+ description="DuckDB database provider (SQLAlchemy via duckdb_engine)",
15
+ dialects=["duckdb"],
16
+ provider_class=DuckDBProvider,
17
+ transport="native",
18
+ quirks_class=DuckDBQuirks,
19
+ config_class=DuckDBConfig,
20
+ sqlalchemy_url_builder=build_sqlalchemy_url,
21
+ native_driver_module="duckdb",
22
+ )