snowflake-data-migration-orchestrator 1.3.3__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_migration_orchestrator-1.3.3/.coveragerc +23 -0
- snowflake_data_migration_orchestrator-1.3.3/.dockerignore +18 -0
- snowflake_data_migration_orchestrator-1.3.3/.env.example +13 -0
- snowflake_data_migration_orchestrator-1.3.3/.gitignore +207 -0
- snowflake_data_migration_orchestrator-1.3.3/CONTRIBUTING.md +73 -0
- snowflake_data_migration_orchestrator-1.3.3/Dockerfile +30 -0
- snowflake_data_migration_orchestrator-1.3.3/Jenkinsfile-push-image +235 -0
- snowflake_data_migration_orchestrator-1.3.3/PKG-INFO +352 -0
- snowflake_data_migration_orchestrator-1.3.3/README.md +319 -0
- snowflake_data_migration_orchestrator-1.3.3/docs/checksum-computation.md +220 -0
- snowflake_data_migration_orchestrator-1.3.3/docs/diagrams/module-dependencies.mmd +16 -0
- snowflake_data_migration_orchestrator-1.3.3/docs/diagrams/module-dependencies.png +0 -0
- snowflake_data_migration_orchestrator-1.3.3/docs/incremental-sync.md +211 -0
- snowflake_data_migration_orchestrator-1.3.3/docs/public/example-workflows/example-workflow-config-redshift-unload.json +39 -0
- snowflake_data_migration_orchestrator-1.3.3/docs/public/example-workflows/example-workflow-config.json +44 -0
- snowflake_data_migration_orchestrator-1.3.3/docs/schema-migrations.md +694 -0
- snowflake_data_migration_orchestrator-1.3.3/docs/scopes.md +30 -0
- snowflake_data_migration_orchestrator-1.3.3/docs/task-model.md +117 -0
- snowflake_data_migration_orchestrator-1.3.3/docs/user-guide.md +229 -0
- snowflake_data_migration_orchestrator-1.3.3/pyproject.toml +171 -0
- snowflake_data_migration_orchestrator-1.3.3/ruff.toml +103 -0
- snowflake_data_migration_orchestrator-1.3.3/scripts/build-wheel.sh +100 -0
- snowflake_data_migration_orchestrator-1.3.3/scripts/create-workflow.sh +54 -0
- snowflake_data_migration_orchestrator-1.3.3/scripts/upload-orchestrator.sh +45 -0
- snowflake_data_migration_orchestrator-1.3.3/scripts/validate_imports.py +342 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/__about__.py +1 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/__init__.py +6 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/__main__.py +56 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/file-formats/csv_file_format.sql +5 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/file-formats/parquet_file_format.sql +4 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/table-metadata/partition_metadata.sql +14 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/table-metadata/partition_metadata_id_sequence.sql +3 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/table-metadata/procedures/copy_partition_metadata.sql +44 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/table-metadata/procedures/copy_table_metadata.sql +36 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/table-metadata/procedures/find_existing_table_metadata.sql +21 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/table-metadata/procedures/get_partition_metadata.sql +36 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/table-metadata/procedures/get_table_configuration.sql +16 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/table-metadata/procedures/insert_partition_metadata.sql +20 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/table-metadata/procedures/insert_table_metadata.sql +18 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/table-metadata/table_metadata.sql +10 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/table-metadata/table_metadata_id_sequence.sql +3 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/table-metadata/views/data_migration_error.sql +31 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/table-metadata/views/table_progress.sql +15 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/table-metadata/views/table_progress_with_example_error.sql +24 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/task-queue/data_migration_schema.sql +4 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/task-queue/procedures/check_tasks.sql +20 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/task-queue/procedures/complete_task.sql +24 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/task-queue/procedures/copy_parquet_into_table.sql +43 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/task-queue/procedures/create_table.sql +70 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/task-queue/procedures/expire_leases.sql +30 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/task-queue/procedures/fail_task.sql +35 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/task-queue/procedures/has_workflow_started.sql +14 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/task-queue/procedures/pull_tasks.sql +51 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/task-queue/procedures/push_task_text.sql +35 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/task-queue/procedures/push_task_variant.sql +48 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/task-queue/procedures/refresh_leases.sql +18 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/task-queue/procedures/unblock_tasks.sql +46 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/task-queue/schema_migration_table.sql +7 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/task-queue/snowconvert_ai_database.sql +4 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/task-queue/task_id_sequence.sql +2 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/task-queue/task_queue.sql +34 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/task-queue/task_results.sql +3 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/workflows/example-workflow.json +17 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/workflows/procedures/complete_workflows.sql +42 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/workflows/procedures/get_pending_workflows.sql +61 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/assets/scripts/workflows/workflow.sql +16 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/__init__.py +6 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/connection_manager.py +161 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/constants/__init__.py +12 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/constants/file_formats.py +6 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/constants/priorities.py +13 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/exceptions/__init__.py +6 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/exceptions/queueing_error.py +27 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/exceptions/unsupported_payload_kind_error.py +32 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/observability/__init__.py +1 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/observability/logging_config.py +184 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/observability/telemetry_lifecycle.py +113 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/orchestrator_affinity.py +19 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/snowflake_account.py +4 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/stored_procedure_calls.py +17 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/tasks/__init__.py +20 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/tasks/constants/__init__.py +1 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/tasks/constants/task_columns.py +7 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/tasks/executor_type.py +13 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/tasks/queues/__init__.py +12 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/tasks/queues/base_task_queue.py +332 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/tasks/queues/table_task_queue.py +481 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/tasks/snowflake_query_task.py +31 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/tasks/task.py +94 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/tasks/task_builder.py +58 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/tasks/task_status.py +16 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/warehouse.py +128 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/workflows/__init__.py +12 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/workflows/base_workflow_initializer.py +48 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/workflows/stored_procedures_calls.py +6 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/workflows/workflow.py +54 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/workflows/workflow_columns.py +15 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_core/workflows/workflow_status.py +13 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_orchestrator/__init__.py +6 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_orchestrator/exceptions/__init__.py +6 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_orchestrator/exceptions/unsupported_workflow_type_error.py +25 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_orchestrator/orchestrator.py +362 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_orchestrator/schema/__init__.py +7 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_orchestrator/schema/migrations/__init__.py +11 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_orchestrator/schema/migrations/base_migration.py +68 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_orchestrator/schema/migrations/migration_0001_initial.py +184 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_orchestrator/schema/run_schema_migrations.py +30 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_orchestrator/schema/schema_manager.py +257 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_orchestrator/worker_context.py +33 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_orchestrator/workflows/__init__.py +7 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_orchestrator/workflows/workflow_initializer_factory.py +110 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/cloud_orchestrator/workflows/workflow_type.py +26 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/commands/__init__.py +4 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/commands/create_data_migration_workflow.py +172 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/commands/start.py +164 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/__init__.py +6 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/config/__init__.py +26 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/config/configuration_parser.py +592 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/config/configuration_properties_keys.py +36 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/config/extraction_strategy.py +34 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/config/sync_strategy.py +53 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/config/table_configuration.py +170 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/config/workflow_configuration_schema.py +147 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/constants/__init__.py +1 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/constants/metadata.py +20 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/constants/priorities.py +22 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/constants/stages.py +5 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/dashboard/__init__.py +8 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/dashboard/app.py +453 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/dashboard/environment.yml +6 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/dashboard/streamlit_deployer.py +143 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/data_migration_workflow_initializer.py +656 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/exceptions/__init__.py +10 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/exceptions/table_not_found_error.py +65 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/exceptions/unsupported_extraction_strategy_error.py +29 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/platforms/__init__.py +80 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/platforms/base_platform.py +197 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/platforms/base_query_builder.py +484 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/platforms/platform_registry.py +131 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/platforms/postgresql/__init__.py +25 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/platforms/postgresql/platform.py +85 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/platforms/postgresql/query_builder.py +228 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/platforms/redshift/__init__.py +1 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/platforms/redshift/checksum.py +208 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/platforms/redshift/platform.py +85 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/platforms/redshift/query_builder.py +361 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/platforms/snowflake/__init__.py +14 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/platforms/snowflake/query_builder.py +190 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/platforms/sqlserver/__init__.py +25 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/platforms/sqlserver/checksum.py +230 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/platforms/sqlserver/platform.py +98 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/platforms/sqlserver/query_builder.py +248 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/platforms/sqlserver/type_mappings.py +53 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/scope.py +225 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/services/__init__.py +1 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/services/batch_size_calculator.py +70 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/services/schema_validator.py +333 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/strategies/WIP_unload_infrastructure_setup.py +206 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/__init__.py +10 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/checksum_task_creator.py +141 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/handlers/__init__.py +1 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/handlers/base_task_handler.py +75 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/handlers/checksum_models.py +58 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/handlers/clear_partition_data_handler.py +183 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/handlers/compare_partition_checksum_handler.py +276 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/handlers/complete_partition_migration_handler.py +266 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/handlers/create_partition_tasks_handler.py +438 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/handlers/deduplicate_partition_data_handler.py +347 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/handlers/partition_boundary_generator.py +264 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/handlers/partition_calculator.py +93 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/handlers/partition_reuse_service.py +243 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/handlers/partition_strategy_handler.py +433 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/handlers/process_checksum_result_handler.py +362 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/handlers/staged_data_handler.py +1010 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/handlers/synchronization_config_service.py +140 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/handlers/table_configuration_service.py +378 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/handlers/workflow_config_service.py +166 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/handlers/workflow_progress_service.py +162 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/models/__init__.py +5 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/models/partition_migration_status.py +28 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/models/synchronization_data.py +207 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/models/task_payload.py +444 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/models/task_payload_kind.py +75 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/task_chain_creator.py +367 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/task_handler_factory.py +167 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/tasks/task_payload_mapper.py +43 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/utils/__init__.py +1 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/utils/stage_utils.py +617 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_cloud/utils/type_mapping_loader.py +1103 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_core/__init__.py +1 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_core/queries/__init__.py +14 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_core/queries/table_metadata.py +467 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_core/queries/target_schema_queries.py +154 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_core/type_mappings/__init__.py +50 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_core/type_mappings/default_mappings.py +62 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_core/type_mappings/models.py +128 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_core/type_mappings/postgresql_default_mappings.py +148 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_core/type_mappings/redshift_default_mappings.py +110 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/data_migration_core/type_mappings/sqlserver_default_mappings.py +58 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/utils/__init__.py +7 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/utils/base_registry.py +110 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/utils/datetime_utils.py +104 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/utils/lru_cache.py +154 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/utils/snowflake_schema.py +81 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/utils/sql_utils.py +285 -0
- snowflake_data_migration_orchestrator-1.3.3/src/data_migration_orchestrator/utils/table_utils.py +249 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/__init__.py +0 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/platforms/__init__.py +1 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/platforms/postgresql/__init__.py +0 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/platforms/postgresql/test_metadata_queries.py +258 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/platforms/redshift/__init__.py +1 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/platforms/redshift/test_metadata_queries.py +303 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/platforms/redshift/test_platform.py +228 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/platforms/redshift/test_query_builder.py +482 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/platforms/redshift/test_type_mappings.py +294 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/platforms/sqlserver/__init__.py +0 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/platforms/sqlserver/test_query_builder.py +408 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/platforms/test_base_platform.py +258 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/platforms/test_platform_registry.py +167 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_base_task_queue.py +352 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_checksum_query_builder.py +106 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_complete_partition_migration_handler.py +196 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_configuration_parser.py +1086 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_create_data_migration_workflow.py +259 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_create_partition_tasks_handler.py +52 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_datetime_utils.py +163 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_deduplicate_partition_data_handler.py +289 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_incremental_sync_watermark.py +275 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_orchestrator.py +369 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_partition_boundary_generator.py +410 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_partition_strategy_handler.py +257 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_schema_validator.py +119 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_scope.py +485 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_sql_utils.py +316 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_stage_utils.py +128 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_staged_data_handler_partition_status.py +483 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_table_configuration.py +110 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_table_not_found_error.py +139 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_table_task_queue.py +536 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_table_utils.py +306 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_task_chain_creator.py +221 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_task_columns.py +49 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_task_payloads.py +312 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_type_mappings.py +1961 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_workflow_configuration_schema.py +296 -0
- snowflake_data_migration_orchestrator-1.3.3/tests/test_workflow_progress_service.py +303 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
[run]
|
|
2
|
+
source = src
|
|
3
|
+
omit =
|
|
4
|
+
*/__init__.py
|
|
5
|
+
*/__about__.py
|
|
6
|
+
|
|
7
|
+
[report]
|
|
8
|
+
exclude_lines =
|
|
9
|
+
pragma: no cover
|
|
10
|
+
def __repr__
|
|
11
|
+
raise NotImplementedError
|
|
12
|
+
if __name__ == .__main__.:
|
|
13
|
+
pass
|
|
14
|
+
raise ImportError
|
|
15
|
+
|
|
16
|
+
[html]
|
|
17
|
+
directory = tests/outcome/unit-coverage-html
|
|
18
|
+
|
|
19
|
+
[xml]
|
|
20
|
+
output = tests/outcome/unit-coverage.xml
|
|
21
|
+
|
|
22
|
+
[json]
|
|
23
|
+
output = tests/outcome/unit-coverage.json
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Snowflake Connection Configuration
|
|
2
|
+
# Copy this file to .env and fill in your actual values
|
|
3
|
+
|
|
4
|
+
# Required: Basic Snowflake credentials
|
|
5
|
+
SNOWFLAKE_ACCOUNT=your_account
|
|
6
|
+
SNOWFLAKE_USER=your_user
|
|
7
|
+
SNOWFLAKE_PASSWORD=your_password
|
|
8
|
+
|
|
9
|
+
# Optional: Connection settings
|
|
10
|
+
SNOWFLAKE_WAREHOUSE=your_warehouse
|
|
11
|
+
SNOWFLAKE_DATABASE=your_database
|
|
12
|
+
SNOWFLAKE_SCHEMA=your_schema
|
|
13
|
+
SNOWFLAKE_ROLE=your_role
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# DS_Store
|
|
2
|
+
.DS_Store
|
|
3
|
+
**/.DS_Store
|
|
4
|
+
|
|
5
|
+
# version
|
|
6
|
+
!__version__.py
|
|
7
|
+
!**/__version__.py
|
|
8
|
+
|
|
9
|
+
# Byte-compiled / optimized / DLL files
|
|
10
|
+
__pycache__/
|
|
11
|
+
*.py[cod]
|
|
12
|
+
*$py.class
|
|
13
|
+
|
|
14
|
+
# C extensions
|
|
15
|
+
*.so
|
|
16
|
+
|
|
17
|
+
# Sphinx documentation
|
|
18
|
+
docs/build/
|
|
19
|
+
docs/source/**/_autosummary
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# Distribution / packaging
|
|
23
|
+
.Python
|
|
24
|
+
build/
|
|
25
|
+
develop-eggs/
|
|
26
|
+
dist/
|
|
27
|
+
downloads/
|
|
28
|
+
eggs/
|
|
29
|
+
.eggs/
|
|
30
|
+
lib/
|
|
31
|
+
lib64/
|
|
32
|
+
parts/
|
|
33
|
+
sdist/
|
|
34
|
+
var/
|
|
35
|
+
wheels/
|
|
36
|
+
share/python-wheels/
|
|
37
|
+
*.egg-info/
|
|
38
|
+
.installed.cfg
|
|
39
|
+
*.egg
|
|
40
|
+
MANIFEST
|
|
41
|
+
|
|
42
|
+
# PyInstaller
|
|
43
|
+
# Usually these files are written by a python script from a template
|
|
44
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
45
|
+
*.manifest
|
|
46
|
+
*.spec
|
|
47
|
+
|
|
48
|
+
# Installer logs
|
|
49
|
+
pip-log.txt
|
|
50
|
+
pip-delete-this-directory.txt
|
|
51
|
+
|
|
52
|
+
# Unit test / coverage reports
|
|
53
|
+
htmlcov/
|
|
54
|
+
.tox/
|
|
55
|
+
.nox/
|
|
56
|
+
.coverage
|
|
57
|
+
.coverage.*
|
|
58
|
+
.cache
|
|
59
|
+
nosetests.xml
|
|
60
|
+
coverage.xml
|
|
61
|
+
*.cover
|
|
62
|
+
*.py,cover
|
|
63
|
+
.hypothesis/
|
|
64
|
+
.pytest_cache/
|
|
65
|
+
cover/
|
|
66
|
+
|
|
67
|
+
# pytest outcome
|
|
68
|
+
*/tests/outcome/
|
|
69
|
+
tests/outcome/**
|
|
70
|
+
test-results.xml
|
|
71
|
+
|
|
72
|
+
# Translations
|
|
73
|
+
*.mo
|
|
74
|
+
*.pot
|
|
75
|
+
|
|
76
|
+
# Django stuff:
|
|
77
|
+
*.log
|
|
78
|
+
logs/
|
|
79
|
+
local_settings.py
|
|
80
|
+
db.sqlite3
|
|
81
|
+
db.sqlite3-journal
|
|
82
|
+
|
|
83
|
+
# Flask stuff:
|
|
84
|
+
instance/
|
|
85
|
+
.webassets-cache
|
|
86
|
+
|
|
87
|
+
# Scrapy stuff:
|
|
88
|
+
.scrapy
|
|
89
|
+
|
|
90
|
+
# Sphinx documentation
|
|
91
|
+
docs/_build/
|
|
92
|
+
|
|
93
|
+
# PyBuilder
|
|
94
|
+
.pybuilder/
|
|
95
|
+
target/
|
|
96
|
+
|
|
97
|
+
# Jupyter Notebook
|
|
98
|
+
.ipynb_checkpoints
|
|
99
|
+
|
|
100
|
+
# IPython
|
|
101
|
+
profile_default/
|
|
102
|
+
ipython_config.py
|
|
103
|
+
|
|
104
|
+
# pyenv
|
|
105
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
106
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
107
|
+
.python-version
|
|
108
|
+
|
|
109
|
+
# pipenv
|
|
110
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
111
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
112
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
113
|
+
# install all needed dependencies.
|
|
114
|
+
#Pipfile.lock
|
|
115
|
+
|
|
116
|
+
# UV
|
|
117
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
118
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
119
|
+
# commonly ignored for libraries.
|
|
120
|
+
#uv.lock
|
|
121
|
+
|
|
122
|
+
# poetry
|
|
123
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
124
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
125
|
+
# commonly ignored for libraries.
|
|
126
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
127
|
+
#poetry.lock
|
|
128
|
+
|
|
129
|
+
# pdm
|
|
130
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
131
|
+
#pdm.lock
|
|
132
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
133
|
+
# in version control.
|
|
134
|
+
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
|
135
|
+
.pdm.toml
|
|
136
|
+
.pdm-python
|
|
137
|
+
.pdm-build/
|
|
138
|
+
|
|
139
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
140
|
+
__pypackages__/
|
|
141
|
+
|
|
142
|
+
# Celery stuff
|
|
143
|
+
celerybeat-schedule
|
|
144
|
+
celerybeat.pid
|
|
145
|
+
|
|
146
|
+
# SageMath parsed files
|
|
147
|
+
*.sage.py
|
|
148
|
+
|
|
149
|
+
# Environments
|
|
150
|
+
.env
|
|
151
|
+
.venv
|
|
152
|
+
env/
|
|
153
|
+
venv/
|
|
154
|
+
ENV/
|
|
155
|
+
env.bak/
|
|
156
|
+
venv.bak/
|
|
157
|
+
|
|
158
|
+
# Spyder project settings
|
|
159
|
+
.spyderproject
|
|
160
|
+
.spyproject
|
|
161
|
+
|
|
162
|
+
# Rope project settings
|
|
163
|
+
.ropeproject
|
|
164
|
+
|
|
165
|
+
# mkdocs documentation
|
|
166
|
+
/site
|
|
167
|
+
|
|
168
|
+
# mypy
|
|
169
|
+
.mypy_cache/
|
|
170
|
+
.dmypy.json
|
|
171
|
+
dmypy.json
|
|
172
|
+
|
|
173
|
+
# Pyre type checker
|
|
174
|
+
.pyre/
|
|
175
|
+
|
|
176
|
+
# pytype static type analyzer
|
|
177
|
+
.pytype/
|
|
178
|
+
|
|
179
|
+
# Cython debug symbols
|
|
180
|
+
cython_debug/
|
|
181
|
+
|
|
182
|
+
# PyCharm
|
|
183
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
184
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
185
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
186
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
187
|
+
.idea/
|
|
188
|
+
|
|
189
|
+
# PyPI configuration file
|
|
190
|
+
.pypirc
|
|
191
|
+
|
|
192
|
+
# ruff cache
|
|
193
|
+
.ruff_cache
|
|
194
|
+
|
|
195
|
+
# Requirements file generated by pip-compile
|
|
196
|
+
requirements.txt
|
|
197
|
+
|
|
198
|
+
# Data Exchange Agent
|
|
199
|
+
data-exchange-agent/src/mocked_api/*
|
|
200
|
+
.vscode
|
|
201
|
+
|
|
202
|
+
# Rye lock files (not committed for library projects)
|
|
203
|
+
requirements.lock
|
|
204
|
+
requirements-dev.lock
|
|
205
|
+
|
|
206
|
+
# Temporary files
|
|
207
|
+
temp/
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# CONTRIBUTING
|
|
2
|
+
|
|
3
|
+
## Code Organization
|
|
4
|
+
Data Migration Orchestrator is organized in these main modules:
|
|
5
|
+
- `utils`: Utils that can be imported from anywhere.
|
|
6
|
+
- `cloud_core`: Core for Cloud operations, which includes definitions for Workflows and Tasks.
|
|
7
|
+
- `data_migration_core`: Core for Data Migration, which includes platform-agnostic logic.
|
|
8
|
+
- `data_migration_cloud`: Workflows Initializers, Task, and Task Handlers for Data Migration Workflows.
|
|
9
|
+
- `cloud_orchestrator`: The Orchestrator itself, which consumes the other modules to support the execution of Workflows of any kind.
|
|
10
|
+
|
|
11
|
+
These modules follow a layered architecture with strict import rules. An arrow from module A to module B means that A can import from B. Colors represent the architecture layers:
|
|
12
|
+
- 🔵 **Blue**: Orchestration layer (`cloud_orchestrator`)
|
|
13
|
+
- 🟢 **Green**: Migration logic layer (`data_migration_cloud`)
|
|
14
|
+
- 🟠 **Orange**: Core components layer (`cloud_core`, `data_migration_core`)
|
|
15
|
+
- 🟣 **Purple**: Foundation layer (`utils`)
|
|
16
|
+
|
|
17
|
+

|
|
18
|
+
|
|
19
|
+
## Type Errors, Lint Errors, Import Errors & Tests
|
|
20
|
+
We try to keep a high bar for code quality in this project. This includes having a linter and type-safe code. These commands can help you navigate the codebase and check that your work is fulfilling those expectations:
|
|
21
|
+
- Check (and fix) linter errors: `ruff check --fix`
|
|
22
|
+
- Check that you're not violating the rules of the dependencies between the main modules described in [Code Organization](#code-organization): `./scripts/validate_imports.py`
|
|
23
|
+
- Check type safety: `hatch run types:check-ty`
|
|
24
|
+
- Run all tests: `hatch run test:unit`
|
|
25
|
+
|
|
26
|
+
## Keeping Documentation up to Date
|
|
27
|
+
When adding/modifying features, we should be careful with updating the corresponding documentation (including this file, the README.md and the files in the `docs` directory). This is particularly relevant for the `user-guide.md`.
|
|
28
|
+
There are also Cursor rules that we should keep synchronized with the docs (including this doc).
|
|
29
|
+
|
|
30
|
+
## Development Patterns
|
|
31
|
+
### Task Model
|
|
32
|
+
In the **Data Migration Orchestrator** we distribute work by converting workflows into sequences of many tasks:
|
|
33
|
+
- Distributing the work in tasks help us achieve fault-tolerance, distribute the workload across several workers, and have "resumability".
|
|
34
|
+
- These tasks can have successors/predecessors and be executed by different components of the architecture.
|
|
35
|
+
- We strive for tasks to be idempotent, retryable, and moderately "quick" to execute. This might not always be achievable.
|
|
36
|
+
- No specific executor is assigned to a task, although a specific executor type will be assigned depending on the kind of the task.
|
|
37
|
+
- Each task has a payload that depends on the kind of the task. There are no guarantees on the time at which a task will be executed. Because of that, we can't assume that a sucessor task will be executed immediately after its predecessor (hours/days could have passed since).
|
|
38
|
+
|
|
39
|
+
When adding features to the Orchestrator, consider this task model. For more information, you can visit the `task-model.md` document.
|
|
40
|
+
|
|
41
|
+
### Creating/Queuing Tasks
|
|
42
|
+
Create tasks using the `TaskBuilder` class and then queue them using the `TaskQueue`. When creating sequences of dependent tasks, you can use the `push_task_chain` method of the `TaskQueue`.
|
|
43
|
+
|
|
44
|
+
### Manipulating Stage Paths
|
|
45
|
+
We constantly are putting data/metadata into files in different paths of stages and then reading that data/metadata (or copying it into tables). For example, the default internal stage is `SNOWCONVERT_AI.DATA_MIGRATION.TASK_RESULTS` and we normally upload metadata/data of the tables we're moving.
|
|
46
|
+
|
|
47
|
+
We try to avoid passing stage paths through task payloads. Instead, we try to have a standardize pattern for stage paths. For example, if you want to access the path at which the schema information for a table was uploaded, then it might look something like this: `<stage-id>/workflows/<workflow-id>/table/<table-metadata-id>/schema/`.
|
|
48
|
+
|
|
49
|
+
### Scopes
|
|
50
|
+
Scopes are described in detail in the `scopes.md` doc. Those are useful for understanding what is the purpose of each task and to what "domain" it applies.
|
|
51
|
+
|
|
52
|
+
When creating scopes, we should use the `ScopeBuilder`. There are other helper functions that can be used when creating scopes (specially if the scope is very commonly created).
|
|
53
|
+
|
|
54
|
+
### Changing Configuration
|
|
55
|
+
When changing configuration models (by adding or modifying properties or configuration sections) or configuration behavior, we should update the corresponding documentation (the `user-guide.md` and also the examples of configuration).
|
|
56
|
+
|
|
57
|
+
### Schema Migrations
|
|
58
|
+
When changing the schema (tables in the `SNOWCONVERT_AI.DATA_MIGRATION` schema, for example), we should do it through schema migrations. Check the `schema-migrations.md` doc for more information about this topic.
|
|
59
|
+
|
|
60
|
+
## Anti-patterns
|
|
61
|
+
1. We want to avoid having duplicated dataclasses (or dataclasses that are almost equivalent) without a good reason.
|
|
62
|
+
2. We do not want to rely too much on magic strings. In cases where we are dealing with categories/kinds, we should prefer to create a `StrEnum`.
|
|
63
|
+
3. We want to avoid "carrying" too much information across tasks, particularly if you are sending a piece of information that is not meant for a task, but rather for a future task that might be created by the immediate task you are creating. We should strive to read configuration values from the TABLE_METADATA configuration column, for example. This also applies to the PARTITION_METADATA synchronization data, for example.
|
|
64
|
+
4. We want to avoid using `Any` if possible. In general, we try to keep the code as type-safe as possible.
|
|
65
|
+
5. We want to avoid complex types without a meaningful name. For example, types like `dict[str, dict[str, str]]` might be complex to understand when reading the code. A type alias or a dedicated class can help here.
|
|
66
|
+
6. Let's not make non-deterministic tests, or unit tests that can take a lot of time. Running all tests should be matter of less than 10 seconds.
|
|
67
|
+
|
|
68
|
+
## How to add a new platform?
|
|
69
|
+
### Basic Integration
|
|
70
|
+
TODO
|
|
71
|
+
|
|
72
|
+
### Optimizations
|
|
73
|
+
TODO
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Use Python 3.11 slim image
|
|
2
|
+
FROM python:3.11-slim
|
|
3
|
+
|
|
4
|
+
# Set working directory
|
|
5
|
+
WORKDIR /app
|
|
6
|
+
|
|
7
|
+
# Copy shared directory from parent context (required by pyproject.toml force-include)
|
|
8
|
+
COPY shared /shared
|
|
9
|
+
|
|
10
|
+
# Copy project files
|
|
11
|
+
COPY data-migration-orchestrator/pyproject.toml data-migration-orchestrator/README.md ./
|
|
12
|
+
COPY data-migration-orchestrator/src/ ./src/
|
|
13
|
+
|
|
14
|
+
# Install the package and dependencies
|
|
15
|
+
RUN pip install --no-cache-dir -e .
|
|
16
|
+
# TODO(SNOW-2860314): move dependency installation before the part in which we copy the source code to leverage Docker layer caching
|
|
17
|
+
|
|
18
|
+
# Set the Python path
|
|
19
|
+
ENV PYTHONPATH=/app/src
|
|
20
|
+
|
|
21
|
+
# Disable Python output buffering to see logs in real-time
|
|
22
|
+
ENV PYTHONUNBUFFERED=1
|
|
23
|
+
|
|
24
|
+
# Create non-root user and pre-create writable dirs
|
|
25
|
+
RUN groupadd --system appgroup && useradd --system --gid appgroup appuser \
|
|
26
|
+
&& mkdir -p /app/logs && chown appuser:appgroup /app/logs
|
|
27
|
+
USER appuser
|
|
28
|
+
|
|
29
|
+
# Run the main module
|
|
30
|
+
CMD ["python", "-u", "-m", "data_migration_orchestrator"]
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
@Library('pipeline-utils')
|
|
2
|
+
|
|
3
|
+
import com.snowflake.DevEnvUtils
|
|
4
|
+
|
|
5
|
+
String prodServerUrl = 'ci-prod-200'
|
|
6
|
+
String devServerUrl = 'sql-001'
|
|
7
|
+
String prodArtifactoryRepo = 'internal-production-docker-data_migration-local'
|
|
8
|
+
String devArtifactoryRepo = 'internal-development-docker-data_migration-local'
|
|
9
|
+
Boolean isProdServer
|
|
10
|
+
Boolean isDevServer
|
|
11
|
+
String artifactoryRepo
|
|
12
|
+
String imageName = 'data-migration-orchestrator'
|
|
13
|
+
String version
|
|
14
|
+
String imageTagAmd64
|
|
15
|
+
String imageTagArm64
|
|
16
|
+
|
|
17
|
+
pipeline {
|
|
18
|
+
agent {
|
|
19
|
+
label 'small-node-snowos'
|
|
20
|
+
}
|
|
21
|
+
options {
|
|
22
|
+
skipDefaultCheckout()
|
|
23
|
+
}
|
|
24
|
+
stages {
|
|
25
|
+
stage("Detect Environment") {
|
|
26
|
+
steps {
|
|
27
|
+
script {
|
|
28
|
+
isProdServer = env.JENKINS_URL?.contains(prodServerUrl) ?: false
|
|
29
|
+
isDevServer = env.JENKINS_URL?.contains(devServerUrl) ?: false
|
|
30
|
+
|
|
31
|
+
if (isProdServer) {
|
|
32
|
+
echo "Running on PRODUCTION server: ${env.JENKINS_URL}"
|
|
33
|
+
artifactoryRepo = prodArtifactoryRepo
|
|
34
|
+
} else if (isDevServer) {
|
|
35
|
+
echo "Running on DEV server: ${env.JENKINS_URL}"
|
|
36
|
+
artifactoryRepo = devArtifactoryRepo
|
|
37
|
+
} else {
|
|
38
|
+
error("Unknown server: ${env.JENKINS_URL}. Expected ${prodServerUrl} or ${devServerUrl}")
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
echo "Using Artifactory repository: ${artifactoryRepo}"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
stage("Checkout") {
|
|
47
|
+
steps {
|
|
48
|
+
script {
|
|
49
|
+
checkout([
|
|
50
|
+
$class: 'GitSCM',
|
|
51
|
+
branches: scm.branches,
|
|
52
|
+
extensions: [],
|
|
53
|
+
userRemoteConfigs: [[
|
|
54
|
+
url: scm.userRemoteConfigs[0].url,
|
|
55
|
+
credentialsId: 'jenkins-snowflake-github-app-2-emu'
|
|
56
|
+
]]
|
|
57
|
+
])
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
stage("Set Environment") {
|
|
63
|
+
steps {
|
|
64
|
+
script {
|
|
65
|
+
echo "Extracting version from __version__.py..."
|
|
66
|
+
version = sh(
|
|
67
|
+
script: "grep -oP '__version__\\s*=\\s*\"\\K[^\"]+' __version__.py",
|
|
68
|
+
returnStdout: true
|
|
69
|
+
).trim()
|
|
70
|
+
|
|
71
|
+
// Set image tags
|
|
72
|
+
imageTagAmd64 = "${imageName}:${version}"
|
|
73
|
+
imageTagArm64 = "${imageName}-arm64:${version}"
|
|
74
|
+
|
|
75
|
+
echo "Environment validation passed."
|
|
76
|
+
echo "Version from __version__.py: ${version}"
|
|
77
|
+
echo "Image tag (AMD64): ${imageTagAmd64}"
|
|
78
|
+
echo "Image tag (ARM64): ${imageTagArm64}"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
stage("Build Docker Images") {
|
|
84
|
+
steps {
|
|
85
|
+
script {
|
|
86
|
+
sh """
|
|
87
|
+
echo "=== Setting up Docker Buildx for multi-platform builds ==="
|
|
88
|
+
# Install QEMU emulation for ARM64 builds
|
|
89
|
+
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
|
|
90
|
+
|
|
91
|
+
# Create and use a new buildx builder instance for multi-platform support
|
|
92
|
+
docker buildx create --name multiplatform-builder --use --bootstrap
|
|
93
|
+
|
|
94
|
+
echo "=== Building Docker Image (AMD64) ==="
|
|
95
|
+
docker buildx build --platform linux/amd64 --load \
|
|
96
|
+
-t "${imageTagAmd64}" \
|
|
97
|
+
-f "data-migration-orchestrator/Dockerfile" \
|
|
98
|
+
.
|
|
99
|
+
echo "=== Docker Build Complete (AMD64) ==="
|
|
100
|
+
|
|
101
|
+
echo "=== Building Docker Image (ARM64) ==="
|
|
102
|
+
docker buildx build --platform linux/arm64 --load \
|
|
103
|
+
-t "${imageTagArm64}" \
|
|
104
|
+
-f "data-migration-orchestrator/Dockerfile" \
|
|
105
|
+
.
|
|
106
|
+
echo "=== Docker Build Complete (ARM64) ==="
|
|
107
|
+
"""
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
stage("Validate Local Images") {
|
|
113
|
+
steps {
|
|
114
|
+
script {
|
|
115
|
+
// Function to check if image exists locally
|
|
116
|
+
def checkLocalImageExists = { imageTag ->
|
|
117
|
+
return sh(
|
|
118
|
+
script: "docker images --format '{{.Repository}}:{{.Tag}}' | grep -q '^${imageTag}\$'",
|
|
119
|
+
returnStatus: true
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
echo "Validating Docker images exist..."
|
|
124
|
+
def imageExistsAmd64 = checkLocalImageExists(imageTagAmd64)
|
|
125
|
+
def imageExistsArm64 = checkLocalImageExists(imageTagArm64)
|
|
126
|
+
|
|
127
|
+
if (imageExistsAmd64 != 0) {
|
|
128
|
+
error("Docker image '${imageTagAmd64}' not found. Please ensure the image was built and tagged correctly.")
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (imageExistsArm64 != 0) {
|
|
132
|
+
error("Docker image '${imageTagArm64}' not found. Please ensure the ARM64 image was built and tagged correctly.")
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
echo "All images validated successfully. Available Docker images:"
|
|
136
|
+
sh "docker images | grep ${imageName}"
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
stage("Check Artifactory Repository") {
|
|
142
|
+
steps {
|
|
143
|
+
script {
|
|
144
|
+
new DevEnvUtils().withSfCli {
|
|
145
|
+
echo "Authenticating with OCI registry..."
|
|
146
|
+
sh "sf artifact oci auth"
|
|
147
|
+
echo "Authentication complete."
|
|
148
|
+
|
|
149
|
+
// Function to check if image exists in remote repository
|
|
150
|
+
def checkRemoteImageExists = { imagePath ->
|
|
151
|
+
return sh(
|
|
152
|
+
script: """
|
|
153
|
+
sf artifact container-images exists \\
|
|
154
|
+
--repository ${artifactoryRepo} \\
|
|
155
|
+
--name ${imagePath} \\
|
|
156
|
+
--tag ${version}
|
|
157
|
+
""",
|
|
158
|
+
returnStatus: true
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
echo "Checking if AMD64 image already exists in remote repository..."
|
|
163
|
+
def remoteImageExistsAmd64 = checkRemoteImageExists(imageName)
|
|
164
|
+
|
|
165
|
+
if (remoteImageExistsAmd64 == 0) {
|
|
166
|
+
error("Image '${imageName}:${version}' already exists in repository '${artifactoryRepo}'. Cannot push duplicate version.")
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
echo "Checking if ARM64 image already exists in remote repository..."
|
|
170
|
+
def remoteImageExistsArm64 = checkRemoteImageExists("${imageName}-arm64")
|
|
171
|
+
|
|
172
|
+
if (remoteImageExistsArm64 == 0) {
|
|
173
|
+
error("Image '${imageName}-arm64:${version}' already exists in repository '${artifactoryRepo}'. Cannot push duplicate version.")
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
echo "All images validated - none exist in remote repository. Ready to push."
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
stage("Push AMD64 Image to Artifactory") {
|
|
183
|
+
steps {
|
|
184
|
+
script {
|
|
185
|
+
new DevEnvUtils().withSfCli {
|
|
186
|
+
echo "Pushing AMD64 image to repository: ${artifactoryRepo}"
|
|
187
|
+
|
|
188
|
+
sh """
|
|
189
|
+
sf artifact container-images push \\
|
|
190
|
+
--image ${imageTagAmd64} \\
|
|
191
|
+
--name ${imageName} \\
|
|
192
|
+
--repository ${artifactoryRepo} \\
|
|
193
|
+
--tag ${version}
|
|
194
|
+
"""
|
|
195
|
+
echo "AMD64 image push complete."
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
stage("Push ARM64 Image to Artifactory") {
|
|
202
|
+
steps {
|
|
203
|
+
script {
|
|
204
|
+
new DevEnvUtils().withSfCli {
|
|
205
|
+
echo "Pushing ARM64 image to repository: ${artifactoryRepo}"
|
|
206
|
+
|
|
207
|
+
sh """
|
|
208
|
+
sf artifact container-images push \\
|
|
209
|
+
--image ${imageTagArm64} \\
|
|
210
|
+
--name ${imageName}-arm64 \\
|
|
211
|
+
--repository ${artifactoryRepo} \\
|
|
212
|
+
--tag ${version}
|
|
213
|
+
"""
|
|
214
|
+
echo "ARM64 image push complete."
|
|
215
|
+
|
|
216
|
+
echo "All images pushed successfully to Artifactory!"
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
post {
|
|
223
|
+
always {
|
|
224
|
+
script {
|
|
225
|
+
// Clean up the buildx builder
|
|
226
|
+
sh """
|
|
227
|
+
echo "=== Cleaning up Docker Buildx ==="
|
|
228
|
+
docker buildx rm multiplatform-builder || true
|
|
229
|
+
echo "=== Buildx cleanup complete ==="
|
|
230
|
+
"""
|
|
231
|
+
}
|
|
232
|
+
cleanWs()
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|