exness-data-preprocess 1.1.0__tar.gz → 1.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/.gitignore +5 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/.mise.toml +37 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/CHANGELOG.md +12 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/PKG-INFO +1 -1
- exness_data_preprocess-1.2.0/docs/adr/2025-12-10-clickhouse-pydantic-config.md +237 -0
- exness_data_preprocess-1.2.0/docs/adr/diagrams/2025-12-10-clickhouse-pydantic-config-after.dot +21 -0
- exness_data_preprocess-1.2.0/docs/adr/diagrams/2025-12-10-clickhouse-pydantic-config-arch.dot +17 -0
- exness_data_preprocess-1.2.0/docs/adr/diagrams/2025-12-10-clickhouse-pydantic-config-before.dot +20 -0
- exness_data_preprocess-1.2.0/docs/design/2025-12-10-clickhouse-pydantic-config/spec.md +153 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/pyproject.toml +1 -1
- exness_data_preprocess-1.2.0/scripts/generate_dbeaver_config.py +212 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/src/exness_data_preprocess/__init__.py +1 -1
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/src/exness_data_preprocess/clickhouse_client.py +24 -9
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/src/exness_data_preprocess/clickhouse_manager.py +71 -103
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/src/exness_data_preprocess/clickhouse_query_engine.py +53 -59
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/.cz.toml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/.github/workflows/ci.yml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/.github/workflows/pre-commit-autoupdate.yml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/.github/workflows/publish.yml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/.lint-relative-paths-results.txt +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/.pre-commit-config.yaml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/.releaserc.yml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/CLAUDE.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/CONTRIBUTING.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/LICENSE +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/Makefile +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/README.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/cliff-release-notes.toml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/cliff.toml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/DATABASE_SCHEMA.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/EXNESS_DATA_SOURCES.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/MODULE_ARCHITECTURE.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/PRIORITY3_CLEANUP_PLAN.yaml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/README.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/REPOSITORY_REFACTORING_PLAN.yaml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/RESEARCH_PATTERNS.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/TRADING_HOURS_RESEARCH.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/UNIFIED_DUCKDB_PLAN_v2.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/adr/2025-12-09-codebase-pruning.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/adr/2025-12-09-exness-clickhouse-migration.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/adr/2025-12-10-clickhouse-e2e-validation-pipeline.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/CLAUDE_MD_AUDIT_2025-10-16_PASS2.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/CLAUDE_MD_VERIFICATION_CHECKLIST_2025-10-16.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/CLAUDE_MD_VERIFICATION_FINDINGS_2025-10-16.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/DOCUMENTATION_AUDIT_2025-10-15.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/DOCUMENTATION_AUDIT_PASS2_2025-10-15.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/DOCUMENTATION_BEST_PRACTICES_LINE_COUNTS.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/E2E_TESTING_PLAN_v1.0.0.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/EXCHANGE_SESSION_AUDIT_2025-10-17.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/FUNCTIONALITY_VALIDATION_REPORT_2025-10-15.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/FUNCTIONALITY_VALIDATION_REPORT_2025-10-16.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/GAP_DETECTION_COMPARISON.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/GAP_DETECTION_SQL_APPROACH.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/PHASE4_DRY_RUN_CONFIG_PLAN.yaml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/PHASE7_v1.5.0_REFACTORING_PLAN.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/PHASE7_v1.6.0_REFACTORING_PROGRESS.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/PYDANTIC_REFACTORING_PLAN_v0.2.0_COMPLETE.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/PYDANTIC_REFACTORING_STATUS_v0.2.0_COMPLETE.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/REFACTORING_CHECKLIST.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/RESEARCH_PATTERNS_CANONICALIZATION_2025-10-17.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/SCHEMA_v1.6.0_AUDIT_FINDINGS.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/SCHEMA_v1.6.0_MIGRATION_GUIDE.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/SESSION_2025-10-15_SUMMARY.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/UNIFIED_DUCKDB_PLAN_v1.0.0_LEGACY.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/archive/implementation-plan-2024-11-24.yaml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/design/2025-12-09-codebase-pruning/spec.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/design/2025-12-09-exness-clickhouse-migration/spec.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/design/2025-12-10-clickhouse-e2e-validation-pipeline/spec.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/optimization/OPTIMIZATION_OPPORTUNITIES_2025-10-18.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/phases/PHASE2_SESSION_VECTORIZATION_PLAN.yaml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/phases/PHASE3_SQL_GAP_DETECTION_PLAN.yaml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/releases/RELEASE_NOTES.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/releases/RELEASE_NOTES_SHORT.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/HYBRID_SESSION_DETECTION_ANALYSIS.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/compression-benchmarks/README.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/compression-benchmarks/test_all_compression_methods.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/compression-benchmarks/test_delta_encoding_properly.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/compression-benchmarks/test_parquet_compression_methods.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-spread-analysis/01-methodology.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-spread-analysis/02-mode-truncated-analysis.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-spread-analysis/03-hurdle-model-analysis.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-spread-analysis/04-temporal-patterns.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-spread-analysis/05-final-recommendations.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-spread-analysis/README.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-spread-analysis/scripts/reproduction_guide.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-spread-analysis/visualizations/hurdle-model/hurdle_decomposition.png +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/cv_mode_comparison.png +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/distribution_overlay.png +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/signal_quality_comparison.png +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/variance_decomposition.png +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-spread-analysis/visualizations/temporal/concentration_curve.png +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-spread-analysis/visualizations/temporal/percentile_analysis.png +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/01-methodology.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/02-baseline-sep2024.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/03-multiperiod-validation.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/04-discoveries-and-plan-evolution.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/README.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/findings/baseline-sep2024-comprehensive-summary.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/findings/phase2-mean-reversion-report.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/findings/phase3-volatility-model-report.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/findings/phase4-5-statistical-tests-survivorship-report.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/scripts/baseline-sep2024/01_mean_reversion_analysis.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/scripts/baseline-sep2024/02_volatility_model_simple.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/scripts/baseline-sep2024/03_liquidity_crisis_detection.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/scripts/baseline-sep2024/04_regime_detection_analysis.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase1_data_validation.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase2_mean_reversion.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase3_volatility_model.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase4_statistical_tests.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase5_survivorship_bias.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase5_survivorship_bias_v1.0.1.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase6a_interval_analysis.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase6b_price_clustering.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase6c_combined_pattern.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/scripts/reproduction_guide.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/scripts/visualization/diagnostic_burst_decay.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/scripts/visualization/generate_interactive_dashboard.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/scripts/visualization/generate_lightweight_dashboard.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/eurusd-zero-spread-deviations/scripts/visualization/prepare_visualization_data.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/research/gap_detection_implementation_example.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/setup/GITHUB_PYPI_SETUP.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/validation/ARCHITECTURE_AUDIT_2025-10-17.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/validation/ARCHITECTURE_EFFICIENCY_AUDIT_2025-10-18.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/validation/DOCUMENTATION_SURVEY_v1.7.0.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/validation/E2E_VALIDATION_RESULTS_v1.6.0.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/validation/SPIKE_TEST_RESULTS_PHASE1_2025-10-18.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/validation/SPIKE_TEST_RESULTS_PHASE2_2025-10-18.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/validation/WEEKEND_GAP_VALIDATION_SUMMARY.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/docs/validation/WORKSPACE_SURVEY_2025-10-17.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/examples/basic_usage.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/examples/batch_processing.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/package-lock.json +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/package.json +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/src/exness_data_preprocess/clickhouse_base.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/src/exness_data_preprocess/clickhouse_gap_detector.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/src/exness_data_preprocess/clickhouse_ohlc_generator.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/src/exness_data_preprocess/config.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/src/exness_data_preprocess/database_manager.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/src/exness_data_preprocess/downloader.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/src/exness_data_preprocess/exchanges.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/src/exness_data_preprocess/gap_detector.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/src/exness_data_preprocess/models.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/src/exness_data_preprocess/ohlc_generator.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/src/exness_data_preprocess/processor.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/src/exness_data_preprocess/query_engine.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/src/exness_data_preprocess/schema.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/src/exness_data_preprocess/session_detector.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/src/exness_data_preprocess/tick_loader.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/tests/README.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/tests/__init__.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/tests/conftest.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/tests/test_basic.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/tests/test_functional_regression.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/tests/test_models.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/tests/test_processor_pydantic.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.0}/tests/test_types.py +0 -0
|
@@ -9,6 +9,22 @@ PACKAGE_NAME = "exness_data_preprocess"
|
|
|
9
9
|
# Validation temp directory
|
|
10
10
|
VALIDATION_TMP = "./tmp/validation"
|
|
11
11
|
|
|
12
|
+
# ADR: /docs/adr/2025-12-10-clickhouse-pydantic-config.md
|
|
13
|
+
# ClickHouse SSoT Configuration
|
|
14
|
+
# Connection identity
|
|
15
|
+
CLICKHOUSE_NAME = "exness-clickhouse-local"
|
|
16
|
+
CLICKHOUSE_MODE = "local" # "local" or "cloud"
|
|
17
|
+
CLICKHOUSE_TYPE = "dev" # "dev", "test", or "prod"
|
|
18
|
+
# Connection parameters (match existing clickhouse_client.py defaults)
|
|
19
|
+
CLICKHOUSE_HOST = "localhost"
|
|
20
|
+
CLICKHOUSE_PORT = "8123"
|
|
21
|
+
CLICKHOUSE_DATABASE = "exness"
|
|
22
|
+
# Output paths
|
|
23
|
+
DBEAVER_CONFIG_PATH = ".dbeaver/data-sources.json"
|
|
24
|
+
# Cloud credentials (read from .env for security)
|
|
25
|
+
# CLICKHOUSE_USER_READONLY - set in .env
|
|
26
|
+
# CLICKHOUSE_PASSWORD_READONLY - set in .env
|
|
27
|
+
|
|
12
28
|
[tools]
|
|
13
29
|
python = "3.14"
|
|
14
30
|
|
|
@@ -470,3 +486,24 @@ engine.close()
|
|
|
470
486
|
print('✅ OHLC validation passed')
|
|
471
487
|
"
|
|
472
488
|
'''
|
|
489
|
+
|
|
490
|
+
# =============================================================================
|
|
491
|
+
# DBeaver Config Generation
|
|
492
|
+
# ADR: /docs/adr/2025-12-10-clickhouse-pydantic-config.md
|
|
493
|
+
# =============================================================================
|
|
494
|
+
|
|
495
|
+
[tasks.db-client-generate]
|
|
496
|
+
description = "Generate DBeaver config from Pydantic model"
|
|
497
|
+
run = "uv run scripts/generate_dbeaver_config.py --output ${DBEAVER_CONFIG_PATH}"
|
|
498
|
+
|
|
499
|
+
[tasks."db-client:cloud"]
|
|
500
|
+
description = "Generate config for ClickHouse Cloud"
|
|
501
|
+
run = "uv run scripts/generate_dbeaver_config.py --mode cloud --output ${DBEAVER_CONFIG_PATH}"
|
|
502
|
+
|
|
503
|
+
[tasks."db-client:dry-run"]
|
|
504
|
+
description = "Preview generated config without writing"
|
|
505
|
+
run = "uv run scripts/generate_dbeaver_config.py --dry-run"
|
|
506
|
+
|
|
507
|
+
[tasks.dbeaver]
|
|
508
|
+
description = "Launch DBeaver with project workspace"
|
|
509
|
+
run = '"/Applications/DBeaver.app/Contents/MacOS/dbeaver" -data .dbeaver-workspace &'
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
# [1.2.0](https://github.com/terrylica/exness-data-preprocess/compare/v1.1.0...v1.2.0) (2025-12-10)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **clickhouse:** resolve E2E validation bugs in schema and query engine ([5c618f7](https://github.com/terrylica/exness-data-preprocess/commit/5c618f717cadc23097e9fd11d2fed87947ecf25f))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* add DBeaver config generation with CLICKHOUSE_MODE support ([0e97618](https://github.com/terrylica/exness-data-preprocess/commit/0e9761818f137461623f744af92f0b1e98b3a797))
|
|
12
|
+
|
|
1
13
|
# [1.1.0](https://github.com/terrylica/exness-data-preprocess/compare/v1.0.0...v1.1.0) (2025-12-10)
|
|
2
14
|
|
|
3
15
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: exness-data-preprocess
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: Professional Exness forex tick data preprocessing with optimal compression (Parquet Zstd-22) and DuckDB OHLC generation. Provides efficient storage (9% smaller than ZIP) with lossless precision and direct queryability.
|
|
5
5
|
Project-URL: Homepage, https://github.com/terrylica/exness-data-preprocess
|
|
6
6
|
Project-URL: Documentation, https://github.com/terrylica/exness-data-preprocess#readme
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: accepted
|
|
3
|
+
date: 2025-12-10
|
|
4
|
+
decision-maker: Terry Li
|
|
5
|
+
consulted:
|
|
6
|
+
[
|
|
7
|
+
Config-Discovery-Agent,
|
|
8
|
+
ClickHouse-Connection-Agent,
|
|
9
|
+
Skill-Reference-Agent,
|
|
10
|
+
ClickHouse-Pattern-Agent,
|
|
11
|
+
Mise-Pattern-Agent,
|
|
12
|
+
]
|
|
13
|
+
research-method: 9-agent-parallel-dctl
|
|
14
|
+
clarification-iterations: 2
|
|
15
|
+
perspectives: [SSoT-Configuration, DeveloperExperience, BackwardCompatibility]
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# ADR: ClickHouse Pydantic Config Integration
|
|
19
|
+
|
|
20
|
+
**Design Spec**: [Implementation Spec](/docs/design/2025-12-10-clickhouse-pydantic-config/spec.md)
|
|
21
|
+
|
|
22
|
+
## Context and Problem Statement
|
|
23
|
+
|
|
24
|
+
The `exness-data-preprocess` package has ClickHouse integration for tick data storage, but lacks:
|
|
25
|
+
|
|
26
|
+
1. **Database client configuration** - No DBeaver connection config generation
|
|
27
|
+
2. **SSoT for connection parameters** - Environment variables are scattered, not centralized in mise `[env]`
|
|
28
|
+
3. **Inconsistent SSL handling** - Uses `CLICKHOUSE_SECURE` (boolean) instead of canonical `CLICKHOUSE_MODE` (local/cloud) pattern
|
|
29
|
+
|
|
30
|
+
The `clickhouse-pydantic-config` skill from cc-skills provides a canonical pattern for generating DBeaver configs from Pydantic v2 models using mise as SSoT.
|
|
31
|
+
|
|
32
|
+
### Before/After
|
|
33
|
+
|
|
34
|
+
**Before**: Scattered configuration, no DBeaver integration
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
┌────────────────────┐
|
|
38
|
+
│ Code Defaults │
|
|
39
|
+
│ (hardcoded) │ ─┐
|
|
40
|
+
└────────────────────┘ │
|
|
41
|
+
│ │
|
|
42
|
+
│ port=8123 │ db='exness'
|
|
43
|
+
▼ ▼
|
|
44
|
+
┌────────────────────────────────────────┐
|
|
45
|
+
│ clickhouse_client.py │
|
|
46
|
+
└────────────────────────────────────────┘
|
|
47
|
+
▲ ▲
|
|
48
|
+
│ CLICKHOUSE_SECURE │ CLICKHOUSE_HOST
|
|
49
|
+
│ │
|
|
50
|
+
┌────────────────────┐ │
|
|
51
|
+
│ Env Vars │ │
|
|
52
|
+
│ (scattered) │ ─┘
|
|
53
|
+
└────────────────────┘
|
|
54
|
+
┌────────────────────┐
|
|
55
|
+
│ DBeaver │
|
|
56
|
+
│ (manual setup) │
|
|
57
|
+
└────────────────────┘
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
<details>
|
|
61
|
+
<summary>graph-easy source (before.dot)</summary>
|
|
62
|
+
|
|
63
|
+
```dot
|
|
64
|
+
digraph before {
|
|
65
|
+
rankdir=TB;
|
|
66
|
+
env_vars [label="Env Vars\n(scattered)"];
|
|
67
|
+
code_defaults [label="Code Defaults\n(hardcoded)"];
|
|
68
|
+
clickhouse_client [label="clickhouse_client.py"];
|
|
69
|
+
env_vars -> clickhouse_client [label="CLICKHOUSE_SECURE"];
|
|
70
|
+
env_vars -> clickhouse_client [label="CLICKHOUSE_HOST"];
|
|
71
|
+
code_defaults -> clickhouse_client [label="port=8123"];
|
|
72
|
+
code_defaults -> clickhouse_client [label="db='exness'"];
|
|
73
|
+
dbeaver [label="DBeaver\n(manual setup)"];
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
</details>
|
|
78
|
+
|
|
79
|
+
**After**: mise `[env]` as SSoT, DBeaver config generation
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
┌────────────────────────────┐
|
|
83
|
+
│ .mise.toml [env] │
|
|
84
|
+
│ (SSoT) │
|
|
85
|
+
└────────────────────────────┘
|
|
86
|
+
│
|
|
87
|
+
│ CLICKHOUSE_*
|
|
88
|
+
▼
|
|
89
|
+
┌──────────────────────┐ ┌────────────────────────────┐
|
|
90
|
+
│ clickhouse_client.py │ validated config │ ClickHouseConnection │
|
|
91
|
+
│ │ ◀────────────────── │ (Pydantic v2) │
|
|
92
|
+
└──────────────────────┘ └────────────────────────────┘
|
|
93
|
+
│
|
|
94
|
+
│ model fields
|
|
95
|
+
▼
|
|
96
|
+
┌────────────────────────────┐
|
|
97
|
+
│ generate_dbeaver_config.py │
|
|
98
|
+
└────────────────────────────┘
|
|
99
|
+
│
|
|
100
|
+
│ generates
|
|
101
|
+
▼
|
|
102
|
+
┌────────────────────────────┐
|
|
103
|
+
│ .dbeaver/data-sources.json │
|
|
104
|
+
└────────────────────────────┘
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
<details>
|
|
108
|
+
<summary>graph-easy source (after.dot)</summary>
|
|
109
|
+
|
|
110
|
+
```dot
|
|
111
|
+
digraph after {
|
|
112
|
+
rankdir=TB;
|
|
113
|
+
mise_env [label=".mise.toml [env]\n(SSoT)"];
|
|
114
|
+
pydantic [label="ClickHouseConnection\n(Pydantic v2)"];
|
|
115
|
+
clickhouse_client [label="clickhouse_client.py"];
|
|
116
|
+
dbeaver_script [label="generate_dbeaver_config.py"];
|
|
117
|
+
dbeaver_json [label=".dbeaver/data-sources.json"];
|
|
118
|
+
mise_env -> pydantic [label="CLICKHOUSE_*"];
|
|
119
|
+
pydantic -> clickhouse_client [label="validated config"];
|
|
120
|
+
pydantic -> dbeaver_script [label="model fields"];
|
|
121
|
+
dbeaver_script -> dbeaver_json [label="generates"];
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
</details>
|
|
126
|
+
|
|
127
|
+
## Research Summary
|
|
128
|
+
|
|
129
|
+
| Agent Perspective | Key Finding | Confidence |
|
|
130
|
+
| --------------------- | ------------------------------------------------------------------------------------------------------ | ---------- |
|
|
131
|
+
| Config-Discovery | `.mise.toml` has `[env]` section but no CLICKHOUSE\_\* vars; existing `config.py` has Pydantic pattern | High |
|
|
132
|
+
| ClickHouse-Connection | Current code uses `CLICKHOUSE_SECURE` for SSL; port 8123 for HTTP; database default is `exness` | High |
|
|
133
|
+
| Skill-Reference | Canonical model uses `CLICKHOUSE_MODE` (local/cloud) with mode-aware validation; scripts at `scripts/` | High |
|
|
134
|
+
| ClickHouse-Pattern | Three skills form a chain: cloud-management → pydantic-config → architect | High |
|
|
135
|
+
| Mise-Pattern | SSoT pattern: `[env]` section → scripts read via `os.environ.get()` with defaults | High |
|
|
136
|
+
|
|
137
|
+
## Decision Log
|
|
138
|
+
|
|
139
|
+
| Decision Area | Options Evaluated | Chosen | Rationale |
|
|
140
|
+
| ---------------- | --------------------------------------- | ------------------------------------ | --------------------------------------------- |
|
|
141
|
+
| SSL Config | CLICKHOUSE_SECURE vs CLICKHOUSE_MODE | Hybrid (MODE + SECURE fallback) | Backward compatibility for existing scripts |
|
|
142
|
+
| Script Location | inline mise task, src/ module, scripts/ | `scripts/generate_dbeaver_config.py` | Canonical pattern from cc-skills |
|
|
143
|
+
| Database Default | `default` vs `exness` | `exness` | Match existing codebase convention |
|
|
144
|
+
| Connection Scope | Single mode vs Both local+cloud | Single per invocation | Canonical pattern; `--mode` flag for override |
|
|
145
|
+
|
|
146
|
+
### Trade-offs Accepted
|
|
147
|
+
|
|
148
|
+
| Trade-off | Choice | Accepted Cost |
|
|
149
|
+
| -------------- | -------------- | -------------------------------------- |
|
|
150
|
+
| MODE vs SECURE | Hybrid support | Slightly more complex connection logic |
|
|
151
|
+
| PEP 723 script | Standalone | Script not part of installed package |
|
|
152
|
+
|
|
153
|
+
## Decision Drivers
|
|
154
|
+
|
|
155
|
+
- **SSoT Principle**: All configurable values should live in `.mise.toml` `[env]` section
|
|
156
|
+
- **Developer Experience**: Zero-friction local setup, DBeaver integration
|
|
157
|
+
- **Backward Compatibility**: Existing `CLICKHOUSE_SECURE` users should not break
|
|
158
|
+
- **Canonical Conformity**: Follow cc-skills patterns exactly
|
|
159
|
+
|
|
160
|
+
## Considered Options
|
|
161
|
+
|
|
162
|
+
- **Option A**: Full migration to CLICKHOUSE_MODE only
|
|
163
|
+
- Breaks existing scripts using CLICKHOUSE_SECURE
|
|
164
|
+
|
|
165
|
+
- **Option B**: Keep CLICKHOUSE_SECURE only, skip MODE
|
|
166
|
+
- Deviates from canonical cc-skills pattern
|
|
167
|
+
|
|
168
|
+
- **Option C**: Hybrid - CLICKHOUSE_MODE primary, CLICKHOUSE_SECURE fallback ← Selected
|
|
169
|
+
- Best of both worlds: canonical pattern + backward compatibility
|
|
170
|
+
|
|
171
|
+
## Decision Outcome
|
|
172
|
+
|
|
173
|
+
Chosen option: **Option C (Hybrid)**, because it adopts the canonical `CLICKHOUSE_MODE` pattern from cc-skills while maintaining backward compatibility for any existing automation using `CLICKHOUSE_SECURE`.
|
|
174
|
+
|
|
175
|
+
## Synthesis
|
|
176
|
+
|
|
177
|
+
**Convergent findings**: All agents agreed on using mise `[env]` as SSoT, scripts at `scripts/`, and Pydantic v2 models.
|
|
178
|
+
|
|
179
|
+
**Divergent findings**: Existing code uses `CLICKHOUSE_SECURE`; canonical skill uses `CLICKHOUSE_MODE`.
|
|
180
|
+
|
|
181
|
+
**Resolution**: Implement hybrid support - MODE takes precedence when set, SECURE as fallback for backward compatibility.
|
|
182
|
+
|
|
183
|
+
## Consequences
|
|
184
|
+
|
|
185
|
+
### Positive
|
|
186
|
+
|
|
187
|
+
- DBeaver config generation with zero manual setup
|
|
188
|
+
- mise `[env]` becomes SSoT for all ClickHouse connection parameters
|
|
189
|
+
- Follows canonical cc-skills pattern for maintainability
|
|
190
|
+
- Backward compatible with existing CLICKHOUSE_SECURE usage
|
|
191
|
+
|
|
192
|
+
### Negative
|
|
193
|
+
|
|
194
|
+
- Slightly more complex SSL detection logic in `clickhouse_client.py`
|
|
195
|
+
- Additional script file to maintain (`scripts/generate_dbeaver_config.py`)
|
|
196
|
+
|
|
197
|
+
## Architecture
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
┌──────────────────────┐ ┌────────────────────────────┐ ┌──────────────────────┐ ┌───────────────────┐
|
|
201
|
+
│ .mise.toml │ env vars │ scripts/ │ instantiate │ ClickHouseConnection │ serialize │ .dbeaver/ │
|
|
202
|
+
│ [env] + [tasks] │ ──────────▶ │ generate_dbeaver_config.py │ ─────────────▶ │ Pydantic Model │ ───────────▶ │ data-sources.json │
|
|
203
|
+
└──────────────────────┘ └────────────────────────────┘ └──────────────────────┘ └───────────────────┘
|
|
204
|
+
│
|
|
205
|
+
│ env vars
|
|
206
|
+
▼
|
|
207
|
+
┌──────────────────────┐
|
|
208
|
+
│ clickhouse_client.py │
|
|
209
|
+
│ (MODE fallback) │
|
|
210
|
+
└──────────────────────┘
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
<details>
|
|
214
|
+
<summary>graph-easy source</summary>
|
|
215
|
+
|
|
216
|
+
```dot
|
|
217
|
+
digraph arch {
|
|
218
|
+
rankdir=LR;
|
|
219
|
+
mise [label=".mise.toml\n[env] + [tasks]"];
|
|
220
|
+
script [label="scripts/\ngenerate_dbeaver_config.py"];
|
|
221
|
+
model [label="ClickHouseConnection\nPydantic Model"];
|
|
222
|
+
client [label="clickhouse_client.py\n(MODE fallback)"];
|
|
223
|
+
dbeaver [label=".dbeaver/\ndata-sources.json"];
|
|
224
|
+
mise -> script [label="env vars"];
|
|
225
|
+
mise -> client [label="env vars"];
|
|
226
|
+
script -> model [label="instantiate"];
|
|
227
|
+
model -> dbeaver [label="serialize"];
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
</details>
|
|
232
|
+
|
|
233
|
+
## References
|
|
234
|
+
|
|
235
|
+
- [clickhouse-pydantic-config skill](/Users/terryli/eon/cc-skills/plugins/devops-tools/skills/clickhouse-pydantic-config/)
|
|
236
|
+
- [mise-configuration skill](/Users/terryli/eon/cc-skills/plugins/itp/skills/mise-configuration/)
|
|
237
|
+
- [ADR: mise env centralized config](/docs/adr/2025-12-08-mise-env-centralized-config.md) (if exists)
|
exness_data_preprocess-1.2.0/docs/adr/diagrams/2025-12-10-clickhouse-pydantic-config-after.dot
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// After: mise [env] as SSoT, DBeaver config generation
|
|
2
|
+
digraph after {
|
|
3
|
+
rankdir=TB;
|
|
4
|
+
|
|
5
|
+
// SSoT
|
|
6
|
+
mise_env [label=".mise.toml [env]\n(SSoT)"];
|
|
7
|
+
|
|
8
|
+
// Pydantic Model
|
|
9
|
+
pydantic [label="ClickHouseConnection\n(Pydantic v2)"];
|
|
10
|
+
|
|
11
|
+
// Consumers
|
|
12
|
+
clickhouse_client [label="clickhouse_client.py"];
|
|
13
|
+
dbeaver_script [label="generate_dbeaver_config.py"];
|
|
14
|
+
dbeaver_json [label=".dbeaver/data-sources.json"];
|
|
15
|
+
|
|
16
|
+
// Relationships
|
|
17
|
+
mise_env -> pydantic [label="CLICKHOUSE_*"];
|
|
18
|
+
pydantic -> clickhouse_client [label="validated config"];
|
|
19
|
+
pydantic -> dbeaver_script [label="model fields"];
|
|
20
|
+
dbeaver_script -> dbeaver_json [label="generates"];
|
|
21
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Architecture: Config flow from mise to DBeaver
|
|
2
|
+
digraph arch {
|
|
3
|
+
rankdir=LR;
|
|
4
|
+
|
|
5
|
+
// Layers
|
|
6
|
+
mise [label=".mise.toml\n[env] + [tasks]"];
|
|
7
|
+
script [label="scripts/\ngenerate_dbeaver_config.py"];
|
|
8
|
+
model [label="ClickHouseConnection\nPydantic Model"];
|
|
9
|
+
client [label="clickhouse_client.py\n(MODE fallback)"];
|
|
10
|
+
dbeaver [label=".dbeaver/\ndata-sources.json"];
|
|
11
|
+
|
|
12
|
+
// Flow
|
|
13
|
+
mise -> script [label="env vars"];
|
|
14
|
+
mise -> client [label="env vars"];
|
|
15
|
+
script -> model [label="instantiate"];
|
|
16
|
+
model -> dbeaver [label="serialize"];
|
|
17
|
+
}
|
exness_data_preprocess-1.2.0/docs/adr/diagrams/2025-12-10-clickhouse-pydantic-config-before.dot
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Before: Scattered configuration, no DBeaver integration
|
|
2
|
+
digraph before {
|
|
3
|
+
rankdir=TB;
|
|
4
|
+
|
|
5
|
+
// Sources
|
|
6
|
+
env_vars [label="Env Vars\n(scattered)"];
|
|
7
|
+
code_defaults [label="Code Defaults\n(hardcoded)"];
|
|
8
|
+
|
|
9
|
+
// Consumer
|
|
10
|
+
clickhouse_client [label="clickhouse_client.py"];
|
|
11
|
+
|
|
12
|
+
// Relationships
|
|
13
|
+
env_vars -> clickhouse_client [label="CLICKHOUSE_SECURE"];
|
|
14
|
+
env_vars -> clickhouse_client [label="CLICKHOUSE_HOST"];
|
|
15
|
+
code_defaults -> clickhouse_client [label="port=8123"];
|
|
16
|
+
code_defaults -> clickhouse_client [label="db='exness'"];
|
|
17
|
+
|
|
18
|
+
// Missing
|
|
19
|
+
dbeaver [label="DBeaver\n(manual setup)"];
|
|
20
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: ClickHouse Pydantic Config Integration
|
|
3
|
+
adr: /docs/adr/2025-12-10-clickhouse-pydantic-config.md
|
|
4
|
+
status: accepted
|
|
5
|
+
created: 2025-12-10
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Design Spec: ClickHouse Pydantic Config Integration
|
|
9
|
+
|
|
10
|
+
**ADR**: [ClickHouse Pydantic Config Integration](/docs/adr/2025-12-10-clickhouse-pydantic-config.md)
|
|
11
|
+
|
|
12
|
+
## Goal
|
|
13
|
+
|
|
14
|
+
Generate DBeaver database client configurations from Pydantic v2 models using mise `[env]` as Single Source of Truth (SSoT).
|
|
15
|
+
|
|
16
|
+
## Canonical Reference
|
|
17
|
+
|
|
18
|
+
`/Users/terryli/eon/cc-skills/plugins/devops-tools/skills/clickhouse-pydantic-config/`
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Adaptation Requirements
|
|
23
|
+
|
|
24
|
+
| Aspect | Current State | Target State |
|
|
25
|
+
| ------------------ | --------------------------- | ------------------------------------ |
|
|
26
|
+
| **SSL config** | `CLICKHOUSE_SECURE` env var | `CLICKHOUSE_MODE` (local/cloud) |
|
|
27
|
+
| **Database** | `exness` (hardcoded) | `exness` via `CLICKHOUSE_DATABASE` |
|
|
28
|
+
| **mise [env]** | No CLICKHOUSE\_\* vars | Full SSoT configuration |
|
|
29
|
+
| **DBeaver config** | Does not exist | `.dbeaver/data-sources.json` |
|
|
30
|
+
| **Scripts** | None | `scripts/generate_dbeaver_config.py` |
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Implementation Tasks
|
|
35
|
+
|
|
36
|
+
### Task 1: Update `.mise.toml` [env] Section
|
|
37
|
+
|
|
38
|
+
Add ClickHouse SSoT configuration:
|
|
39
|
+
|
|
40
|
+
```toml
|
|
41
|
+
# ADR: 2025-12-10-clickhouse-pydantic-config
|
|
42
|
+
# ClickHouse SSoT Configuration
|
|
43
|
+
|
|
44
|
+
# Connection identity
|
|
45
|
+
CLICKHOUSE_NAME = "exness-clickhouse-local"
|
|
46
|
+
CLICKHOUSE_MODE = "local" # "local" or "cloud"
|
|
47
|
+
CLICKHOUSE_TYPE = "dev" # "dev", "test", or "prod"
|
|
48
|
+
|
|
49
|
+
# Connection parameters (match existing clickhouse_client.py defaults)
|
|
50
|
+
CLICKHOUSE_HOST = "localhost"
|
|
51
|
+
CLICKHOUSE_PORT = "8123"
|
|
52
|
+
CLICKHOUSE_DATABASE = "exness"
|
|
53
|
+
|
|
54
|
+
# Output paths
|
|
55
|
+
DBEAVER_CONFIG_PATH = ".dbeaver/data-sources.json"
|
|
56
|
+
|
|
57
|
+
# Cloud credentials (read from .env for security)
|
|
58
|
+
# CLICKHOUSE_USER_READONLY - set in .env
|
|
59
|
+
# CLICKHOUSE_PASSWORD_READONLY - set in .env
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Task 2: Create `scripts/generate_dbeaver_config.py`
|
|
63
|
+
|
|
64
|
+
Copy and adapt from canonical implementation:
|
|
65
|
+
|
|
66
|
+
- Source: `/Users/terryli/eon/cc-skills/plugins/devops-tools/skills/clickhouse-pydantic-config/scripts/generate_dbeaver_config.py`
|
|
67
|
+
- Adaptations:
|
|
68
|
+
- Change default database from `"default"` to `"exness"`
|
|
69
|
+
- Change default name from `"clickhouse-local"` to `"exness-clickhouse-local"`
|
|
70
|
+
|
|
71
|
+
Key components:
|
|
72
|
+
|
|
73
|
+
- `ClickHouseConnection` Pydantic model with `@model_validator` for mode-aware SSL
|
|
74
|
+
- `DBeaver JSON format` with folders and connections structure
|
|
75
|
+
- PEP 723 inline dependencies (`# /// script`)
|
|
76
|
+
|
|
77
|
+
### Task 3: Add mise Tasks
|
|
78
|
+
|
|
79
|
+
```toml
|
|
80
|
+
[tasks.db-client-generate]
|
|
81
|
+
description = "Generate DBeaver config from Pydantic model"
|
|
82
|
+
run = "uv run scripts/generate_dbeaver_config.py --output ${DBEAVER_CONFIG_PATH}"
|
|
83
|
+
|
|
84
|
+
[tasks."db-client:cloud"]
|
|
85
|
+
description = "Generate config for ClickHouse Cloud"
|
|
86
|
+
run = "uv run scripts/generate_dbeaver_config.py --mode cloud --output ${DBEAVER_CONFIG_PATH}"
|
|
87
|
+
|
|
88
|
+
[tasks."db-client:dry-run"]
|
|
89
|
+
description = "Preview generated config without writing"
|
|
90
|
+
run = "uv run scripts/generate_dbeaver_config.py --dry-run"
|
|
91
|
+
|
|
92
|
+
[tasks.dbeaver]
|
|
93
|
+
description = "Launch DBeaver with project workspace"
|
|
94
|
+
run = '"/Applications/DBeaver.app/Contents/MacOS/dbeaver" -data .dbeaver-workspace &'
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Task 4: Update `.gitignore`
|
|
98
|
+
|
|
99
|
+
Add DBeaver entries:
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
# DBeaver (credentials in generated JSON)
|
|
103
|
+
.dbeaver/
|
|
104
|
+
.dbeaver-workspace/
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Task 5: Update `clickhouse_client.py` (Backward Compatibility)
|
|
108
|
+
|
|
109
|
+
Add `CLICKHOUSE_MODE` support while keeping `CLICKHOUSE_SECURE` as fallback:
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
# Mode-based SSL detection (canonical pattern)
|
|
113
|
+
mode = os.environ.get("CLICKHOUSE_MODE", "").lower()
|
|
114
|
+
if mode == "cloud":
|
|
115
|
+
resolved_secure = True
|
|
116
|
+
resolved_port = port or int(os.environ.get("CLICKHOUSE_PORT", "8443"))
|
|
117
|
+
elif mode == "local":
|
|
118
|
+
resolved_secure = False
|
|
119
|
+
else:
|
|
120
|
+
# Fallback: existing CLICKHOUSE_SECURE logic
|
|
121
|
+
env_secure = os.environ.get("CLICKHOUSE_SECURE", "").lower()
|
|
122
|
+
# ... existing logic
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Critical Files
|
|
128
|
+
|
|
129
|
+
| File | Action |
|
|
130
|
+
| ------------------------------------------------- | --------------------------- |
|
|
131
|
+
| `.mise.toml` | Add `[env]` vars + tasks |
|
|
132
|
+
| `scripts/generate_dbeaver_config.py` | **CREATE** - PEP 723 script |
|
|
133
|
+
| `.gitignore` | Add `.dbeaver/` entries |
|
|
134
|
+
| `src/exness_data_preprocess/clickhouse_client.py` | Add MODE support |
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Validation Checklist
|
|
139
|
+
|
|
140
|
+
- [ ] `mise run db-client:dry-run` - Preview config
|
|
141
|
+
- [ ] `mise run db-client-generate` - Generate local config
|
|
142
|
+
- [ ] `jq . .dbeaver/data-sources.json` - Validate JSON
|
|
143
|
+
- [ ] `mise run db-client:cloud` - Generate cloud config (requires .env)
|
|
144
|
+
- [ ] DBeaver can import the connection
|
|
145
|
+
- [ ] Existing `clickhouse_client.py` tests still pass
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Dependencies
|
|
150
|
+
|
|
151
|
+
- `pydantic>=2.0.0` (already in pyproject.toml)
|
|
152
|
+
- `clickhouse-connect>=0.7.0` (already in pyproject.toml)
|
|
153
|
+
- DBeaver Community Edition (manual install)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "exness-data-preprocess"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.2.0"
|
|
4
4
|
description = "Professional Exness forex tick data preprocessing with optimal compression (Parquet Zstd-22) and DuckDB OHLC generation. Provides efficient storage (9% smaller than ZIP) with lossless precision and direct queryability."
|
|
5
5
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
6
6
|
authors = [
|