snowflake-data-validation 1.3.1__tar.gz → 1.3.2__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.
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/PKG-INFO +2 -1
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/pyproject.toml +10 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/__version__.py +1 -1
- snowflake_data_validation-1.3.2/src/snowflake/snowflake_data_validation/common_cli/cli_sync_validation.py +54 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/comparison_orchestrator.py +20 -1
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/executer/executor_factory.py +11 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/extractor/sql_queries_template_generator.py +2 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/orchestration/validation_progress_reporter.py +38 -1
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_chunks_md5_table_template.sql.j2 +1 -1
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/redshift_cli.py +39 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_chunks_md5_table_template.sql.j2 +1 -1
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/snowflake_cli.py +39 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/connector/connector_sql_server.py +70 -8
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_chunks_md5_table_template.sql.j2 +1 -1
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_compute_md5_sql.j2 +10 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/query/query_generator_sqlserver.py +10 -2
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/sqlserver_cli.py +40 -3
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_chunks_md5_table_template.sql.j2 +1 -1
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/teradata_cli.py +40 -3
- snowflake_data_validation-1.3.2/src/snowflake/snowflake_data_validation/utils/configuration_file_synchronizer.py +102 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/constants.py +13 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/validation_database/sqlite_validation_connection.py +82 -54
- snowflake_data_validation-1.3.2/tests/unit/test_configuration_file_synchronizer.py +183 -0
- snowflake_data_validation-1.3.2/tests/unit/test_sqlserver_multi_version_support.py +619 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_validation_progress_reporter.py +41 -12
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/.gitignore +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/LICENSE +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/README.md +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/__main__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/common_cli/cli_partitioning.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/configuration/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/configuration/configuration_loader.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/configuration/model/configuration_model.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/configuration/model/connection_types.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/configuration/model/connections/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/configuration/model/logging_configuration.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/configuration/model/table_configuration.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/configuration/model/validation_configuration.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/configuration/model/view_configuration.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/configuration/singleton.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/connector/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/connector/connector_base.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/connector/connector_factory_base.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/connector/connector_failure_tracker.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/executer/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/executer/async_generation_executor.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/executer/async_validation_executor.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/executer/base_validation_executor.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/executer/extractor_types.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/executer/source_validation_executor.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/executer/sync_validation_executor.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/extractor/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/extractor/metadata_extractor_base.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/main_cli.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/orchestration/console_progress_reporter.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/orchestration/html_report/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/orchestration/html_report/html_report_builder.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/orchestration/html_report/report_metadata.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/orchestration/parallel_execution_engine.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/orchestration/table_metadata_processor.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/orchestration/view_preprocessor.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/query/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/query/query_generator_base.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/connector/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/connector/connector_factory_redshift.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/connector/connector_redshift.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/metadata_extractor_redshift.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/redshift_cte_generator.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_chunk_row_concatenated_insert_template.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_chunk_row_concatenated_table_template.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_chunk_row_md5_insert_template.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_chunk_row_md5_table_template.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_column_metrics_templates.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_columns_cte_template.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_datatypes_normalization_templates.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_extract_chunks_md5_table_template.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_extract_md5_rows_chunk.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_get_columns_metadata.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_insert_chunk_row_md5_template.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_row_count_query.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_table_metadata_query.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/extractor/templates/redshift_to_snowflake_datatypes_mapping_template.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/model/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/model/redshift_credentials_connection.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/query/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/query/query_generator_redshift.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/redshift_arguments_manager.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/script_writer/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/redshift/script_writer/script_writer_redshift.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/script_writer/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/script_writer/script_writer_base.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/connector/connector_factory_snowflake.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/connector/connector_snowflake.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/metadata_extractor_snowflake.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/snowflake_cte_generator.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_chunk_row_concatenated_template.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_chunk_row_md5_template.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_column_metrics_templates.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_columns_cte_template.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_datatypes_normalization_templates.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_extract_chunks_md5_table_template.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_extract_md5_rows_chunk.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_get_case_sensitive_columns.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_get_columns_metadata.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_insert_chunk_row_md5_template.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_row_count_query.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_table_metadata_query.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_temporary_table_from_view_template.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/extractor/templates/snowflake_to_snowflake_datatypes_mapping_template.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/model/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/model/snowflake_credentials_connection.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/model/snowflake_default_connection.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/model/snowflake_named_connection.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/query/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/query/query_generator_snowflake.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/script_writer/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/script_writer/script_writer_snowflake.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/snowflake/snowflake_arguments_manager.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/connector/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/connector/connector_factory_sql_server.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/metadata_extractor_sqlserver.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/sqlserver_cte_generator.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_column_metrics_templates.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_columns_cte_template.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_datatypes_normalization_templates.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_extract_chunks_md5_table_template.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_extract_md5_rows_chunk.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_get_columns_metadata.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_get_temporary_table_internal_identifier_template.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_row_count_query.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_table_metadata_query.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_temporary_table_from_view_template.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/extractor/templates/sqlserver_to_snowflake_datatypes_mapping_template.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/model/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/model/sqlserver_credentials_connection.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/query/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/script_writer/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/script_writer/script_writer_sqlserver.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/sqlserver/sqlserver_arguments_manager.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/table_partitioning_strategy.md +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/connector/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/connector/connector_factory_teradata.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/connector/connector_teradata.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/metadata_extractor_teradata.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_column_metrics_templates.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_columns_cte_template.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_compute_md5_sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_create_row_concatenated.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_create_row_md5.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_datatypes_normalization_templates.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_extract_chunks_md5_table_template.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_extract_md5_rows_chunk.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_get_columns_metadata.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_row_count_query.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_table_metadata_query.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/templates/teradata_to_snowflake_datatypes_mapping_template.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/extractor/teradata_cte_generator.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/model/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/model/teradata_credentials_connection.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/query/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/query/query_generator_teradata.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/script_writer/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/script_writer/script_writer_teradata.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/teradata/teradata_arguments_manager.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/arguments_manager_base.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/arguments_manager_factory.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/base_output_handler.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/column_partitioning_strategy.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/configuration_file_editor.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/configuration_file_generator.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/connection_pool.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/connector_factory.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/console_output_handler.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/context.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/cpu_optimizer.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/helper.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/helpers/helper_database.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/helpers/helper_dataframe.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/helpers/helper_io.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/helpers/helper_misc.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/helpers/helper_query_result.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/helpers/helper_templates.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/logging_config.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/logging_utils.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/model/chunk.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/model/column_metadata.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/model/table_column_metadata.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/model/table_context.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/model/templates_loader_manager.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/progress_reporter.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/row_partitioning_strategy.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/run_context.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/telemetry.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/templates/configuration_file_templates.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/thread_safe_singleton.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/utils/validation_utils.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/data_validator_base.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/metrics_data_validator.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/results_summary_report.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/row_data_validator.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/row_validation_report_buffer.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/schema_data_validator.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/validation_database/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/validation_database/validation_database_connection_base.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/validation_database_manager.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/validation_execution_context.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/src/snowflake/snowflake_data_validation/validation/validation_report_buffer.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/.coveragerc +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/integration/.coveragerc +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/integration/Redshift/test_metadata_extractor_integration.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/integration/test_async_generation_integration.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/integration/test_async_validation_integration.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/integration/test_reference_integration.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/integration/test_source_validation_integration.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/integration/test_sync_validation_integration.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/cli/test_redshift_cli_general.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/cli/test_redshift_cli_generate_validation_scripts.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/cli/test_redshift_cli_get_configuration_files.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/cli/test_redshift_cli_run_async_validation.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/cli/test_redshift_cli_run_validation.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/cli/test_redshift_cli_run_validation_ipc.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/model/test_redshift_credentials_connection.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/query/test_query_generator_redshift.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/script_writer/test_script_writer_redshift.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/test_connector_redshift.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/test_redshift_arguments_manager.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/test_redshift_cte_generator.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Redshift/test_redshift_metrics_templates.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Teradata/test_connector_teradata.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Teradata/test_metadata_extractor_teradata.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Teradata/test_query_generator_teradata.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Teradata/test_teradata_cli.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/Teradata/test_teradata_metrics_validation.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/custom_templates_loader/snowflake_column_metrics_templates.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/custom_templates_loader/snowflake_datatypes_normalization_templates.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/custom_templates_loader/snowflake_table_metadata_query.sql.j2 +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_configuration_loader/test_load_configuration_model/conf.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_configuration_loader/test_load_configuration_model_reading_file_exception/conf.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_helpers/dummy_configuration_file.json +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_helpers/dummy_connection_source_db.toml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_helpers/dummy_datatypes_normalization_template.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_helpers/dummy_datatypes_template.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_helpers/dummy_metrics_template.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_helpers/dummy_metrics_template_datatypes.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_helpers/dummy_template.csv +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_helpers/not_valid_format.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_templates_loader_manager/snowflake_column_metrics_templates.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/assets/test_templates_loader_manager/snowflake_datatypes_normalization_templates.yaml +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_arguments_manager_base.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_arguments_manager_factory.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_column_metadata.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_column_partitioning_strategy.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_comparison_orchestrator.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_configuration_file_editor.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_configuration_loader.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_configuration_model.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_connection_pool.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_connector_failure_tracker.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_connector_snowflake.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_console_progress_reporter.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_cpu_optimizer.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_data_validator.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_executor_factory.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_helper_dataframe.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_helpers.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_html_report_builder.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_logging_config.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_metrics_templates.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_report_metadata.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_row_data_validator.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_row_partitioning_strategy.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_row_validation_report_buffer.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_snowflake_arguments_manager.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_snowflake_cli.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_source_validation_executor.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_sqlite_validation_connection.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_sqlserver_arguments_manager.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_sqlserver_cli.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_table_column_metadata_model.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_table_configuration.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_table_context.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_table_metadata_processor.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_telemetry.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_templates_loader_manager.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_validation_configuration.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_validation_database_connection.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_validation_execution_context.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_validation_report_buffer.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/test_view_configuration.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/utils/__init__.py +0 -0
- {snowflake_data_validation-1.3.1 → snowflake_data_validation-1.3.2}/tests/unit/utils/test_constants.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: snowflake-data-validation
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.2
|
|
4
4
|
Summary: Snowflake Data Validation
|
|
5
5
|
Project-URL: Bug Tracker, https://github.com/snowflakedb/migrations-data-validation/issues
|
|
6
6
|
Project-URL: Source code, https://github.com/snowflakedb/migrations-data-validation/
|
|
@@ -33,6 +33,7 @@ Requires-Dist: pandas>=2.2.3
|
|
|
33
33
|
Requires-Dist: pyarrow>=14.0.0
|
|
34
34
|
Requires-Dist: pydantic-yaml>=1.4.0
|
|
35
35
|
Requires-Dist: pydantic>=2.0
|
|
36
|
+
Requires-Dist: ruamel-yaml>=0.18.0
|
|
36
37
|
Requires-Dist: snowflake-connector-python>=4.0.0
|
|
37
38
|
Requires-Dist: toml>=0.10.2
|
|
38
39
|
Requires-Dist: typer>=0.15.3
|
|
@@ -31,6 +31,7 @@ dependencies = [
|
|
|
31
31
|
"snowflake-connector-python>=4.0.0",
|
|
32
32
|
"pandas>=2.2.3",
|
|
33
33
|
"pyarrow>=14.0.0",
|
|
34
|
+
"ruamel.yaml>=0.18.0",
|
|
34
35
|
"toml>=0.10.2",
|
|
35
36
|
"jinja2>=3.1.6",
|
|
36
37
|
"pydantic>=2.0",
|
|
@@ -111,6 +112,9 @@ packages = [
|
|
|
111
112
|
"src/snowflake",
|
|
112
113
|
]
|
|
113
114
|
|
|
115
|
+
[tool.hatch.build.targets.wheel.force-include]
|
|
116
|
+
"../shared" = "shared"
|
|
117
|
+
|
|
114
118
|
[tool.hatch.build.targets.sdist]
|
|
115
119
|
directory = "dist"
|
|
116
120
|
exclude = ["/.github", "/.idea"]
|
|
@@ -125,8 +129,14 @@ include = [
|
|
|
125
129
|
[tool.hatch.envs.default]
|
|
126
130
|
features = ["development", "sqlserver", "teradata", "redshift"]
|
|
127
131
|
python = "3.12"
|
|
132
|
+
dependencies = [
|
|
133
|
+
"shared @ {root:uri}/../shared",
|
|
134
|
+
]
|
|
128
135
|
|
|
129
136
|
[tool.hatch.envs.test]
|
|
137
|
+
dependencies = [
|
|
138
|
+
"shared @ {root:uri}/../shared",
|
|
139
|
+
]
|
|
130
140
|
|
|
131
141
|
[tool.hatch.envs.test_all]
|
|
132
142
|
template = 'test'
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Copyright 2026 Snowflake Inc.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
9
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
10
|
+
# See the License for the specific language governing permissions and
|
|
11
|
+
# limitations under the License.
|
|
12
|
+
|
|
13
|
+
"""Shared CLI sync validation functions for data validation."""
|
|
14
|
+
|
|
15
|
+
import logging
|
|
16
|
+
|
|
17
|
+
import typer
|
|
18
|
+
|
|
19
|
+
from snowflake.snowflake_data_validation.utils import configuration_file_synchronizer
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
LOGGER = logging.getLogger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def sync_validation_results(
|
|
26
|
+
configuration_file_path: str,
|
|
27
|
+
execution_summary_report_file_path: str,
|
|
28
|
+
) -> None:
|
|
29
|
+
"""Sync the configuration file with the execution summary report.
|
|
30
|
+
|
|
31
|
+
Remove tables and views that passed all validation levels.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
configuration_file_path: Path to the configuration file.
|
|
35
|
+
execution_summary_report_file_path: Path to the execution summary report file.
|
|
36
|
+
|
|
37
|
+
"""
|
|
38
|
+
try:
|
|
39
|
+
configuration_file_synchronizer.sync_configuration_file(
|
|
40
|
+
configuration_file_path=configuration_file_path,
|
|
41
|
+
execution_summary_report_file_path=execution_summary_report_file_path,
|
|
42
|
+
)
|
|
43
|
+
typer.secho(
|
|
44
|
+
"Configuration file updated successfully based on validation results.",
|
|
45
|
+
fg=typer.colors.GREEN,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
LOGGER.info(
|
|
49
|
+
"Configuration file updated successfully based on validation results."
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
except Exception as e:
|
|
53
|
+
typer.secho(f"Error syncing configuration file: {e}", fg=typer.colors.RED)
|
|
54
|
+
LOGGER.error("Error syncing configuration file: %s", e)
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
|
|
16
16
|
import logging
|
|
17
17
|
|
|
18
|
+
from collections.abc import Callable
|
|
19
|
+
|
|
18
20
|
from snowflake.snowflake_data_validation.configuration.model.table_configuration import (
|
|
19
21
|
TableConfiguration,
|
|
20
22
|
)
|
|
@@ -68,6 +70,9 @@ class ComparisonOrchestrator:
|
|
|
68
70
|
connection_pool_manager: ConnectionPoolManager,
|
|
69
71
|
context: Context,
|
|
70
72
|
max_threads: int,
|
|
73
|
+
progress_callback: (
|
|
74
|
+
Callable[[str, list[str], Context | None], None] | None
|
|
75
|
+
) = None,
|
|
71
76
|
):
|
|
72
77
|
"""Initialize the orchestrator.
|
|
73
78
|
|
|
@@ -75,6 +80,10 @@ class ComparisonOrchestrator:
|
|
|
75
80
|
connection_pool_manager: Connection pool manager for threaded processing
|
|
76
81
|
context: Validation context containing configuration and runtime info
|
|
77
82
|
max_threads: Maximum number of threads for parallel table processing
|
|
83
|
+
progress_callback: Optional callback for progress reporting. When
|
|
84
|
+
provided, it replaces the default stdout/pipe-based progress
|
|
85
|
+
reporting in ValidationProgressReporter.
|
|
86
|
+
Signature: (table_name: str, columns: list[str], context: Context | None) -> None
|
|
78
87
|
|
|
79
88
|
"""
|
|
80
89
|
LOGGER.debug("Initializing ComparisonOrchestrator")
|
|
@@ -87,7 +96,9 @@ class ComparisonOrchestrator:
|
|
|
87
96
|
# Initialize orchestration modules
|
|
88
97
|
self.metadata_processor = TableMetadataProcessor()
|
|
89
98
|
self.execution_engine = ParallelExecutionEngine(max_threads=self.max_threads)
|
|
90
|
-
self.progress_reporter = ValidationProgressReporter(
|
|
99
|
+
self.progress_reporter = ValidationProgressReporter(
|
|
100
|
+
progress_callback=progress_callback,
|
|
101
|
+
)
|
|
91
102
|
self.db_manager = ValidationDatabaseManager()
|
|
92
103
|
self.console_progress_reporter = ConsoleProgressReporter(
|
|
93
104
|
output_handler=self.context.output_handler
|
|
@@ -102,11 +113,18 @@ class ComparisonOrchestrator:
|
|
|
102
113
|
def from_validation_environment(
|
|
103
114
|
cls,
|
|
104
115
|
validation_env: ValidationEnvironmentObject,
|
|
116
|
+
progress_callback: (
|
|
117
|
+
Callable[[str, list[str], Context | None], None] | None
|
|
118
|
+
) = None,
|
|
105
119
|
) -> "ComparisonOrchestrator":
|
|
106
120
|
"""Create a ComparisonOrchestrator from a ValidationEnvironmentObject.
|
|
107
121
|
|
|
108
122
|
Args:
|
|
109
123
|
validation_env: ValidationEnvironmentObject instance containing all required components
|
|
124
|
+
progress_callback: Optional callback for progress reporting. When
|
|
125
|
+
provided, it replaces the default stdout/pipe-based progress
|
|
126
|
+
reporting in ValidationProgressReporter.
|
|
127
|
+
Signature: (table_name: str, columns: list[str], context: Context | None) -> None
|
|
110
128
|
|
|
111
129
|
Returns:
|
|
112
130
|
ComparisonOrchestrator: Configured orchestrator ready to run validation
|
|
@@ -140,6 +158,7 @@ class ComparisonOrchestrator:
|
|
|
140
158
|
connection_pool_manager=connection_pool_manager,
|
|
141
159
|
context=validation_env.context,
|
|
142
160
|
max_threads=optimal_max_threads,
|
|
161
|
+
progress_callback=progress_callback,
|
|
143
162
|
)
|
|
144
163
|
|
|
145
164
|
@log
|
|
@@ -65,6 +65,9 @@ from snowflake.snowflake_data_validation.snowflake.query.query_generator_snowfla
|
|
|
65
65
|
from snowflake.snowflake_data_validation.snowflake.script_writer.script_writer_snowflake import (
|
|
66
66
|
ScriptWriterSnowflake,
|
|
67
67
|
)
|
|
68
|
+
from snowflake.snowflake_data_validation.sqlserver.connector.connector_sql_server import (
|
|
69
|
+
ConnectorSqlServer,
|
|
70
|
+
)
|
|
68
71
|
from snowflake.snowflake_data_validation.sqlserver.extractor.metadata_extractor_sqlserver import (
|
|
69
72
|
MetadataExtractorSQLServer,
|
|
70
73
|
)
|
|
@@ -253,6 +256,14 @@ class ExecutorFactory:
|
|
|
253
256
|
query_generator = config.query_generator()
|
|
254
257
|
LOGGER.debug("Created query generator for platform: %s", platform)
|
|
255
258
|
|
|
259
|
+
# Propagate SQL Server version capabilities to the query generator
|
|
260
|
+
if platform == Platform.SQLSERVER and isinstance(connector, ConnectorSqlServer):
|
|
261
|
+
query_generator.supports_string_agg = connector.supports_string_agg
|
|
262
|
+
LOGGER.debug(
|
|
263
|
+
"SQL Server query generator: supports_string_agg=%s",
|
|
264
|
+
connector.supports_string_agg,
|
|
265
|
+
)
|
|
266
|
+
|
|
256
267
|
# Select the appropriate extractor class based on type
|
|
257
268
|
if extractor_type == ExtractorType.METADATA_EXTRACTOR:
|
|
258
269
|
extractor_class = config.metadata_extractor
|
|
@@ -285,6 +285,7 @@ class SQLQueriesTemplateGenerator:
|
|
|
285
285
|
database_name: str,
|
|
286
286
|
schema_name: str,
|
|
287
287
|
table_id: int,
|
|
288
|
+
supports_string_agg: bool = True,
|
|
288
289
|
) -> str:
|
|
289
290
|
template_file = f"{platform}_compute_md5_sql.j2"
|
|
290
291
|
try:
|
|
@@ -305,6 +306,7 @@ class SQLQueriesTemplateGenerator:
|
|
|
305
306
|
fetch=fetch,
|
|
306
307
|
offset=offset,
|
|
307
308
|
table_id=table_id,
|
|
309
|
+
supports_string_agg=supports_string_agg,
|
|
308
310
|
)
|
|
309
311
|
return sql
|
|
310
312
|
except jinja2.exceptions.TemplateNotFound:
|
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
import logging
|
|
17
17
|
import os
|
|
18
18
|
|
|
19
|
+
from collections.abc import Callable
|
|
20
|
+
|
|
19
21
|
import pandas as pd
|
|
20
22
|
|
|
21
23
|
from snowflake.snowflake_data_validation.orchestration.html_report import (
|
|
@@ -74,7 +76,26 @@ def _apply_status_emoji(df: pd.DataFrame, column: str = "STATUS") -> pd.DataFram
|
|
|
74
76
|
|
|
75
77
|
|
|
76
78
|
class ValidationProgressReporter:
|
|
77
|
-
"""Handles progress reporting and validation report management.
|
|
79
|
+
"""Handles progress reporting and validation report management.
|
|
80
|
+
|
|
81
|
+
Accepts an optional custom progress callback at construction time. When
|
|
82
|
+
provided, ``report_progress_for_table`` delegates to the custom callback
|
|
83
|
+
instead of the default stdout/pipe-based ``report_progress()`` mechanism.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
progress_callback: Optional callback invoked for each table.
|
|
87
|
+
Signature: (table_name: str, columns: list[str], context: Context | None) -> None
|
|
88
|
+
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
def __init__(
|
|
92
|
+
self,
|
|
93
|
+
progress_callback: (
|
|
94
|
+
Callable[[str, list[str], Context | None], None] | None
|
|
95
|
+
) = None,
|
|
96
|
+
):
|
|
97
|
+
"""Initialize the reporter with an optional custom progress callback."""
|
|
98
|
+
self._progress_callback = progress_callback
|
|
78
99
|
|
|
79
100
|
@log
|
|
80
101
|
def report_progress_for_table(
|
|
@@ -85,12 +106,28 @@ class ValidationProgressReporter:
|
|
|
85
106
|
) -> None:
|
|
86
107
|
"""Report progress for a specific table.
|
|
87
108
|
|
|
109
|
+
If a custom progress callback was provided at construction, it is
|
|
110
|
+
called instead of the default reporting logic.
|
|
111
|
+
|
|
88
112
|
Args:
|
|
89
113
|
table_name: Name of the table being processed
|
|
90
114
|
column_selection_list: List of columns being validated
|
|
91
115
|
context: Validation context for run_id and run_start_time (optional)
|
|
92
116
|
|
|
93
117
|
"""
|
|
118
|
+
if self._progress_callback is not None:
|
|
119
|
+
try:
|
|
120
|
+
self._progress_callback(table_name, column_selection_list, context)
|
|
121
|
+
except Exception as e:
|
|
122
|
+
LOGGER.warning(
|
|
123
|
+
"Error in custom progress callback for table %s: %s. "
|
|
124
|
+
"This is non-critical and validation will continue.",
|
|
125
|
+
table_name,
|
|
126
|
+
str(e),
|
|
127
|
+
)
|
|
128
|
+
return
|
|
129
|
+
|
|
130
|
+
# Default behaviour: report via stdout/pipe (CLI IPC mode)
|
|
94
131
|
# Only report progress if console output is not enabled
|
|
95
132
|
if (
|
|
96
133
|
context
|
|
@@ -22,6 +22,9 @@ from snowflake.snowflake_data_validation.common_cli.cli_partitioning import (
|
|
|
22
22
|
run_column_partitioning_helper,
|
|
23
23
|
run_row_partitioning_helper,
|
|
24
24
|
)
|
|
25
|
+
from snowflake.snowflake_data_validation.common_cli.cli_sync_validation import (
|
|
26
|
+
sync_validation_results,
|
|
27
|
+
)
|
|
25
28
|
from snowflake.snowflake_data_validation.comparison_orchestrator import (
|
|
26
29
|
ComparisonOrchestrator,
|
|
27
30
|
)
|
|
@@ -692,3 +695,39 @@ def redshift_column_partitioning_helper():
|
|
|
692
695
|
for each table.
|
|
693
696
|
"""
|
|
694
697
|
run_column_partitioning_helper(Platform.REDSHIFT)
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
@redshift_app.command(
|
|
701
|
+
"sync-validation-results",
|
|
702
|
+
help=(
|
|
703
|
+
"Remove from the configuration file the tables and views that passed "
|
|
704
|
+
"all validations levels in the given execution summary report file"
|
|
705
|
+
),
|
|
706
|
+
)
|
|
707
|
+
@handle_validation_errors
|
|
708
|
+
def redshift_sync_validation_results(
|
|
709
|
+
configuration_file_path: Annotated[
|
|
710
|
+
str,
|
|
711
|
+
typer.Option(
|
|
712
|
+
"--configuration-file-path",
|
|
713
|
+
"-cfp",
|
|
714
|
+
help="Path to the configuration file",
|
|
715
|
+
),
|
|
716
|
+
],
|
|
717
|
+
execution_summary_report_file_path: Annotated[
|
|
718
|
+
str,
|
|
719
|
+
typer.Option(
|
|
720
|
+
"--execution-summary-report-file-path",
|
|
721
|
+
"-esrfp",
|
|
722
|
+
help="Path to the execution summary report file",
|
|
723
|
+
),
|
|
724
|
+
],
|
|
725
|
+
):
|
|
726
|
+
"""Sync the configuration file with the execution summary report.
|
|
727
|
+
|
|
728
|
+
Remove tables and views that passed all validation levels.
|
|
729
|
+
"""
|
|
730
|
+
sync_validation_results(
|
|
731
|
+
configuration_file_path=configuration_file_path,
|
|
732
|
+
execution_summary_report_file_path=execution_summary_report_file_path,
|
|
733
|
+
)
|
|
@@ -24,6 +24,9 @@ from snowflake.snowflake_data_validation.common_cli.cli_partitioning import (
|
|
|
24
24
|
run_column_partitioning_helper,
|
|
25
25
|
run_row_partitioning_helper,
|
|
26
26
|
)
|
|
27
|
+
from snowflake.snowflake_data_validation.common_cli.cli_sync_validation import (
|
|
28
|
+
sync_validation_results,
|
|
29
|
+
)
|
|
27
30
|
from snowflake.snowflake_data_validation.comparison_orchestrator import (
|
|
28
31
|
ComparisonOrchestrator,
|
|
29
32
|
)
|
|
@@ -649,3 +652,39 @@ def snowflake_column_partitioning_helper():
|
|
|
649
652
|
for each table.
|
|
650
653
|
"""
|
|
651
654
|
run_column_partitioning_helper(Platform.SNOWFLAKE)
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
@snowflake_app.command(
|
|
658
|
+
"sync-validation-results",
|
|
659
|
+
help=(
|
|
660
|
+
"Remove from the configuration file the tables and views that passed "
|
|
661
|
+
"all validations levels in the given execution summary report file"
|
|
662
|
+
),
|
|
663
|
+
)
|
|
664
|
+
@handle_validation_errors
|
|
665
|
+
def snowflake_sync_validation_results(
|
|
666
|
+
configuration_file_path: Annotated[
|
|
667
|
+
str,
|
|
668
|
+
typer.Option(
|
|
669
|
+
"--configuration-file-path",
|
|
670
|
+
"-cfp",
|
|
671
|
+
help="Path to the configuration file",
|
|
672
|
+
),
|
|
673
|
+
],
|
|
674
|
+
execution_summary_report_file_path: Annotated[
|
|
675
|
+
str,
|
|
676
|
+
typer.Option(
|
|
677
|
+
"--execution-summary-report-file-path",
|
|
678
|
+
"-esrfp",
|
|
679
|
+
help="Path to the execution summary report file",
|
|
680
|
+
),
|
|
681
|
+
],
|
|
682
|
+
):
|
|
683
|
+
"""Sync the configuration file with the execution summary report.
|
|
684
|
+
|
|
685
|
+
Remove tables and views that passed all validation levels.
|
|
686
|
+
"""
|
|
687
|
+
sync_validation_results(
|
|
688
|
+
configuration_file_path=configuration_file_path,
|
|
689
|
+
execution_summary_report_file_path=execution_summary_report_file_path,
|
|
690
|
+
)
|
|
@@ -19,6 +19,10 @@ import struct
|
|
|
19
19
|
|
|
20
20
|
from typing import Literal
|
|
21
21
|
|
|
22
|
+
from shared.sqlserver.constants import SUPPORTED_ODBC_DRIVERS
|
|
23
|
+
from shared.sqlserver.odbc_driver_utils import get_best_sqlserver_driver
|
|
24
|
+
from shared.sqlserver.version_detection import detect_sql_server_version
|
|
25
|
+
|
|
22
26
|
from snowflake.snowflake_data_validation.connector.connector_base import (
|
|
23
27
|
ConnectorBase as BaseConnector,
|
|
24
28
|
)
|
|
@@ -71,7 +75,7 @@ AZURE_SQL_SCOPE = "https://database.windows.net/.default"
|
|
|
71
75
|
|
|
72
76
|
# SQL Server Authentication connection strings
|
|
73
77
|
SQLSERVER_CONNECTION_STRING = (
|
|
74
|
-
"DRIVER={{
|
|
78
|
+
"DRIVER={{{driver}}};"
|
|
75
79
|
"SERVER={server},{port};"
|
|
76
80
|
"DATABASE={database};"
|
|
77
81
|
"UID={user};"
|
|
@@ -81,7 +85,7 @@ SQLSERVER_CONNECTION_STRING = (
|
|
|
81
85
|
)
|
|
82
86
|
|
|
83
87
|
SQLSERVER_CONNECTION_STRING_NAMED = (
|
|
84
|
-
"DRIVER={{
|
|
88
|
+
"DRIVER={{{driver}}};"
|
|
85
89
|
"SERVER={server};"
|
|
86
90
|
"DATABASE={database};"
|
|
87
91
|
"UID={user};"
|
|
@@ -92,7 +96,7 @@ SQLSERVER_CONNECTION_STRING_NAMED = (
|
|
|
92
96
|
|
|
93
97
|
# Windows Authentication connection strings (Trusted Connection)
|
|
94
98
|
SQLSERVER_CONNECTION_STRING_WIN_AUTH = (
|
|
95
|
-
"DRIVER={{
|
|
99
|
+
"DRIVER={{{driver}}};"
|
|
96
100
|
"SERVER={server},{port};"
|
|
97
101
|
"DATABASE={database};"
|
|
98
102
|
"Trusted_Connection=yes;"
|
|
@@ -101,7 +105,7 @@ SQLSERVER_CONNECTION_STRING_WIN_AUTH = (
|
|
|
101
105
|
)
|
|
102
106
|
|
|
103
107
|
SQLSERVER_CONNECTION_STRING_WIN_AUTH_NAMED = (
|
|
104
|
-
"DRIVER={{
|
|
108
|
+
"DRIVER={{{driver}}};"
|
|
105
109
|
"SERVER={server};"
|
|
106
110
|
"DATABASE={database};"
|
|
107
111
|
"Trusted_Connection=yes;"
|
|
@@ -111,7 +115,7 @@ SQLSERVER_CONNECTION_STRING_WIN_AUTH_NAMED = (
|
|
|
111
115
|
|
|
112
116
|
# Azure Entra ID connection strings (token-based authentication)
|
|
113
117
|
SQLSERVER_CONNECTION_STRING_AZURE_TOKEN = (
|
|
114
|
-
"DRIVER={{
|
|
118
|
+
"DRIVER={{{driver}}};"
|
|
115
119
|
"SERVER={server},{port};"
|
|
116
120
|
"DATABASE={database};"
|
|
117
121
|
"TrustServerCertificate={trust_server_certificate};"
|
|
@@ -119,14 +123,13 @@ SQLSERVER_CONNECTION_STRING_AZURE_TOKEN = (
|
|
|
119
123
|
)
|
|
120
124
|
|
|
121
125
|
SQLSERVER_CONNECTION_STRING_AZURE_TOKEN_NAMED = (
|
|
122
|
-
"DRIVER={{
|
|
126
|
+
"DRIVER={{{driver}}};"
|
|
123
127
|
"SERVER={server};"
|
|
124
128
|
"DATABASE={database};"
|
|
125
129
|
"TrustServerCertificate={trust_server_certificate};"
|
|
126
130
|
"Encrypt={encrypt}"
|
|
127
131
|
)
|
|
128
132
|
|
|
129
|
-
|
|
130
133
|
class ConnectorSqlServer(BaseConnector):
|
|
131
134
|
"""Connector for SQL Server database."""
|
|
132
135
|
|
|
@@ -136,6 +139,52 @@ class ConnectorSqlServer(BaseConnector):
|
|
|
136
139
|
self.connection: object | None = None
|
|
137
140
|
self.pyodbc = import_mssql()
|
|
138
141
|
|
|
142
|
+
# SQL Server version detection properties (set after connection)
|
|
143
|
+
self.sql_server_major_version: int | None = None
|
|
144
|
+
self.is_azure_sql_db: bool = False
|
|
145
|
+
self.supports_string_agg: bool = True # Safe default for 2017+
|
|
146
|
+
|
|
147
|
+
def _detect_odbc_driver(self) -> str:
|
|
148
|
+
"""Auto-detect the best available ODBC driver for SQL Server.
|
|
149
|
+
|
|
150
|
+
Delegates to shared.sqlserver.odbc_driver_utils.get_best_sqlserver_driver().
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
str: The name of the detected ODBC driver.
|
|
154
|
+
|
|
155
|
+
Raises:
|
|
156
|
+
ConnectionError: If no compatible ODBC driver is found.
|
|
157
|
+
|
|
158
|
+
"""
|
|
159
|
+
driver = get_best_sqlserver_driver()
|
|
160
|
+
if driver is None:
|
|
161
|
+
raise ConnectionError(
|
|
162
|
+
"No compatible ODBC driver found for SQL Server. "
|
|
163
|
+
"Please install one of the following:\n"
|
|
164
|
+
+ "\n".join(f" - {d}" for d in SUPPORTED_ODBC_DRIVERS[:2])
|
|
165
|
+
+ "\nSee: https://learn.microsoft.com/en-us/sql/connect/odbc/download-odbc-driver-for-sql-server"
|
|
166
|
+
)
|
|
167
|
+
LOGGER.info("Using %s (auto-detected)", driver)
|
|
168
|
+
return driver
|
|
169
|
+
|
|
170
|
+
def _detect_sql_server_version(self) -> None:
|
|
171
|
+
"""Detect the SQL Server version and set capability flags.
|
|
172
|
+
|
|
173
|
+
Delegates to shared.sqlserver.version_detection.detect_sql_server_version().
|
|
174
|
+
Updates instance attributes based on the detected version info.
|
|
175
|
+
|
|
176
|
+
This method is called after connection verification and should not raise
|
|
177
|
+
exceptions — version detection failure defaults to supports_string_agg=True.
|
|
178
|
+
|
|
179
|
+
"""
|
|
180
|
+
if self.connection is None:
|
|
181
|
+
return
|
|
182
|
+
|
|
183
|
+
version_info = detect_sql_server_version(self.connection)
|
|
184
|
+
self.sql_server_major_version = version_info.major_version
|
|
185
|
+
self.is_azure_sql_db = version_info.is_azure_sql_db
|
|
186
|
+
self.supports_string_agg = version_info.supports_string_agg
|
|
187
|
+
|
|
139
188
|
def _get_azure_access_token(
|
|
140
189
|
self,
|
|
141
190
|
mode: SqlServerMode,
|
|
@@ -351,6 +400,9 @@ class ConnectorSqlServer(BaseConnector):
|
|
|
351
400
|
|
|
352
401
|
"""
|
|
353
402
|
try:
|
|
403
|
+
# Auto-detect the ODBC driver
|
|
404
|
+
driver = self._detect_odbc_driver()
|
|
405
|
+
|
|
354
406
|
# Determine if this is a named instance connection
|
|
355
407
|
is_named_instance = (
|
|
356
408
|
re.match(NAMED_INSTANCE_PATTERN_DETAILED, host) is not None
|
|
@@ -362,6 +414,7 @@ class ConnectorSqlServer(BaseConnector):
|
|
|
362
414
|
# Windows Authentication (Trusted Connection)
|
|
363
415
|
if is_named_instance and not is_custom_port:
|
|
364
416
|
self.string_connection = SQLSERVER_CONNECTION_STRING_WIN_AUTH_NAMED.format(
|
|
417
|
+
driver=driver,
|
|
365
418
|
server=host,
|
|
366
419
|
port=port,
|
|
367
420
|
database=database,
|
|
@@ -370,6 +423,7 @@ class ConnectorSqlServer(BaseConnector):
|
|
|
370
423
|
)
|
|
371
424
|
else:
|
|
372
425
|
self.string_connection = SQLSERVER_CONNECTION_STRING_WIN_AUTH.format(
|
|
426
|
+
driver=driver,
|
|
373
427
|
server=host,
|
|
374
428
|
port=port,
|
|
375
429
|
database=database,
|
|
@@ -386,6 +440,7 @@ class ConnectorSqlServer(BaseConnector):
|
|
|
386
440
|
# Azure Entra ID Authentication (token-based)
|
|
387
441
|
if is_named_instance and not is_custom_port:
|
|
388
442
|
self.string_connection = SQLSERVER_CONNECTION_STRING_AZURE_TOKEN_NAMED.format(
|
|
443
|
+
driver=driver,
|
|
389
444
|
server=host,
|
|
390
445
|
port=port,
|
|
391
446
|
database=database,
|
|
@@ -394,6 +449,7 @@ class ConnectorSqlServer(BaseConnector):
|
|
|
394
449
|
)
|
|
395
450
|
else:
|
|
396
451
|
self.string_connection = SQLSERVER_CONNECTION_STRING_AZURE_TOKEN.format(
|
|
452
|
+
driver=driver,
|
|
397
453
|
server=host,
|
|
398
454
|
port=port,
|
|
399
455
|
database=database,
|
|
@@ -426,6 +482,7 @@ class ConnectorSqlServer(BaseConnector):
|
|
|
426
482
|
# SQL Server Authentication (username/password)
|
|
427
483
|
if is_named_instance and not is_custom_port:
|
|
428
484
|
self.string_connection = SQLSERVER_CONNECTION_STRING_NAMED.format(
|
|
485
|
+
driver=driver,
|
|
429
486
|
server=host,
|
|
430
487
|
port=port,
|
|
431
488
|
database=database,
|
|
@@ -436,6 +493,7 @@ class ConnectorSqlServer(BaseConnector):
|
|
|
436
493
|
)
|
|
437
494
|
else:
|
|
438
495
|
self.string_connection = SQLSERVER_CONNECTION_STRING.format(
|
|
496
|
+
driver=driver,
|
|
439
497
|
server=host,
|
|
440
498
|
port=port,
|
|
441
499
|
database=database,
|
|
@@ -457,7 +515,7 @@ class ConnectorSqlServer(BaseConnector):
|
|
|
457
515
|
|
|
458
516
|
@log
|
|
459
517
|
def _verify_connection(self):
|
|
460
|
-
"""Verify the connection by executing a simple test query.
|
|
518
|
+
"""Verify the connection by executing a simple test query and detect server version.
|
|
461
519
|
|
|
462
520
|
Raises:
|
|
463
521
|
ConnectionError: If connection verification fails
|
|
@@ -474,6 +532,10 @@ class ConnectorSqlServer(BaseConnector):
|
|
|
474
532
|
cursor.execute("SELECT 1")
|
|
475
533
|
cursor.fetchone()
|
|
476
534
|
LOGGER.debug("SQL Server connection verified successfully")
|
|
535
|
+
|
|
536
|
+
# Detect SQL Server version after successful verification
|
|
537
|
+
self._detect_sql_server_version()
|
|
538
|
+
|
|
477
539
|
except Exception as e:
|
|
478
540
|
LOGGER.error("Failed to verify SQL Server connection: %s", str(e))
|
|
479
541
|
self.connection = None
|
|
@@ -49,7 +49,17 @@ SELECT
|
|
|
49
49
|
FROM "#ROW_CONCATENATED_{{ chunk_id }}_{{ table_id }}";
|
|
50
50
|
|
|
51
51
|
INSERT INTO "#CHUNKS_MD5_{{ normalized_fully_qualified_name }}_{{ table_id }}"
|
|
52
|
+
{% if supports_string_agg %}
|
|
52
53
|
SELECT
|
|
53
54
|
'{{ chunk_id }}',
|
|
54
55
|
CONVERT(VARCHAR(32), HASHBYTES('MD5', STRING_AGG(CAST(ROW_MD5 AS VARCHAR(MAX)), '')), 2)
|
|
55
56
|
FROM "#ROW_MD5_{{ chunk_id }}_{{ table_id }}";
|
|
57
|
+
{% else %}
|
|
58
|
+
SELECT
|
|
59
|
+
'{{ chunk_id }}',
|
|
60
|
+
CONVERT(VARCHAR(32), HASHBYTES('MD5',
|
|
61
|
+
(SELECT CAST(ROW_MD5 AS VARCHAR(MAX))
|
|
62
|
+
FROM "#ROW_MD5_{{ chunk_id }}_{{ table_id }}"
|
|
63
|
+
FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)')
|
|
64
|
+
), 2);
|
|
65
|
+
{% endif %}
|
|
@@ -36,9 +36,16 @@ LOGGER = logging.getLogger(__name__)
|
|
|
36
36
|
class QueryGeneratorSqlServer(QueryGeneratorBase):
|
|
37
37
|
"""SQL Server-specific implementation of query generator."""
|
|
38
38
|
|
|
39
|
-
def __init__(self):
|
|
40
|
-
"""Initialize the SQL Server query generator.
|
|
39
|
+
def __init__(self, supports_string_agg: bool = True):
|
|
40
|
+
"""Initialize the SQL Server query generator.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
supports_string_agg: Whether the target SQL Server supports STRING_AGG
|
|
44
|
+
(SQL Server 2017+ or Azure SQL DB). Defaults to True.
|
|
45
|
+
|
|
46
|
+
"""
|
|
41
47
|
super().__init__(platform=Platform.SQLSERVER)
|
|
48
|
+
self.supports_string_agg = supports_string_agg
|
|
42
49
|
|
|
43
50
|
def cte_query_generator(
|
|
44
51
|
self,
|
|
@@ -128,6 +135,7 @@ class QueryGeneratorSqlServer(QueryGeneratorBase):
|
|
|
128
135
|
database_name=table_context.database_name,
|
|
129
136
|
schema_name=table_context.schema_name,
|
|
130
137
|
table_id=table_context.id,
|
|
138
|
+
supports_string_agg=self.supports_string_agg,
|
|
131
139
|
)
|
|
132
140
|
|
|
133
141
|
return query
|