sqllocks-spindle 2.2.0__tar.gz → 2.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sqllocks_spindle-2.2.0/sqllocks_spindle.egg-info → sqllocks_spindle-2.2.2}/PKG-INFO +4 -2
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/README.md +3 -1
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/pyproject.toml +1 -1
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/__init__.py +1 -1
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/fabric/warehouse_bulk_writer.py +7 -5
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/inference/profiler.py +1 -1
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2/sqllocks_spindle.egg-info}/PKG-INFO +4 -2
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_inference.py +3 -3
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_streaming.py +19 -5
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/LICENSE +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/LICENSE-NOTICES.md +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/setup.cfg +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/chaos/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/chaos/categories.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/chaos/config.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/chaos/engine.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/cli.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/_shared/reference_data/us_zip_locations.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/base.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/capital_markets/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/capital_markets/capital_markets.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/capital_markets/profiles/default.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/capital_markets/reference_data/exchanges.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/capital_markets/reference_data/gics_sectors.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/capital_markets/reference_data/index_memberships.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/capital_markets/reference_data/sp500_constituents.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/composite.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/education/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/education/education.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/education/profiles/default.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/education/reference_data/aid_types.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/education/reference_data/course_catalog.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/education/reference_data/department_names.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/financial/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/financial/financial.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/financial/profiles/default.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/financial/reference_data/branch_names.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/financial/reference_data/merchant_names.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/financial/reference_data/transaction_categories.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/healthcare/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/healthcare/healthcare.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/healthcare/profiles/default.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/healthcare/reference_data/cpt_codes.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/healthcare/reference_data/icd10_codes.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/healthcare/reference_data/insurance_plans.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/healthcare/reference_data/medication_names.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/healthcare/reference_data/specialties.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/healthcare/reference_data/us_zip_locations.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/hr/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/hr/hr.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/hr/profiles/default.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/hr/reference_data/department_names.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/hr/reference_data/position_titles.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/hr/reference_data/training_courses.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/insurance/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/insurance/insurance.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/insurance/profiles/default.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/insurance/reference_data/claim_categories.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/insurance/reference_data/peril_types.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/insurance/reference_data/policy_types.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/iot/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/iot/iot.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/iot/profiles/default.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/iot/reference_data/alert_severity_levels.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/iot/reference_data/device_types.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/iot/reference_data/sensor_types.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/manufacturing/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/manufacturing/manufacturing.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/manufacturing/profiles/default.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/manufacturing/reference_data/defect_codes.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/manufacturing/reference_data/material_types.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/manufacturing/reference_data/operation_types.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/marketing/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/marketing/marketing.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/marketing/profiles/default.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/marketing/reference_data/campaign_types.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/marketing/reference_data/industry_names.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/marketing/reference_data/lead_sources.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/real_estate/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/real_estate/profiles/default.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/real_estate/real_estate.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/real_estate/reference_data/inspection_items.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/real_estate/reference_data/neighborhoods.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/real_estate/reference_data/property_types.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/retail/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/retail/profiles/default.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/retail/reference_data/categories.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/retail/reference_data/product_names.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/retail/reference_data/promo_names.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/retail/reference_data/us_zip_locations.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/retail/retail.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/shared_registry.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/supply_chain/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/supply_chain/profiles/default.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/supply_chain/reference_data/carrier_names.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/supply_chain/reference_data/material_categories.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/supply_chain/reference_data/shipping_methods.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/supply_chain/supply_chain.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/telecom/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/telecom/profiles/default.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/telecom/reference_data/device_models.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/telecom/reference_data/network_event_types.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/telecom/reference_data/plan_types.json +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/telecom/telecom.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/chunked_generator.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/generator.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/id_manager.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/rules/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/rules/business_rules.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/base.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/computed.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/conditional.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/correlated.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/derived.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/distribution.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/enum.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/faker_strategy.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/first_per_parent.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/foreign_key.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/formula.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/lifecycle.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/lookup.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/pattern.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/record_field.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/record_sample.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/reference_data.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/scd2.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/self_referencing.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/sequence.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/temporal.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/uuid_strategy.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/table_generator.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/fabric/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/fabric/credentials.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/fabric/eventhouse_writer.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/fabric/eventstream_client.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/fabric/lakehouse_files_writer.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/fabric/onelake_paths.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/fabric/semantic_model_writer.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/fabric/sql_database_writer.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/fabric/stream_writer_convenience.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/incremental/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/incremental/continue_config.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/incremental/continue_engine.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/incremental/time_travel.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/inference/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/inference/comparator.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/inference/masker.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/inference/profile_io.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/inference/schema_builder.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/manifests/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/manifests/run_manifest.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/mcp_bridge.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/observability.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/output/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/output/csv_writer.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/output/delta_writer.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/output/fabric_utils.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/output/pandas_writer.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/packs/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/packs/loader.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/packs/runner.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/packs/validator.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/presets/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/presets/builtin.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/presets/registry.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/py.typed +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/schema/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/schema/ddl_parser.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/schema/dependency.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/schema/inference/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/schema/inference/business_rule_inference.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/schema/inference/cardinality_inference.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/schema/inference/column_classifier.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/schema/inference/correlation_inference.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/schema/inference/enum_inference.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/schema/inference/fk_distribution.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/schema/inference/numeric_inference.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/schema/inference/table_classifier.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/schema/inference/temporal_inference.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/schema/parser.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/schema/validator.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/simulation/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/simulation/clickstream_patterns.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/simulation/file_drop.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/simulation/financial_patterns.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/simulation/hybrid.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/simulation/iot_patterns.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/simulation/operational_log_patterns.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/simulation/scd2_file_drops.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/simulation/state_machine.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/simulation/stream_emit.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/specs/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/specs/gsl_parser.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/streaming/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/streaming/anomaly.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/streaming/config.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/streaming/envelope.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/streaming/rate_limiter.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/streaming/sinks/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/streaming/sinks/console_sink.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/streaming/sinks/eventhub_sink.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/streaming/sinks/file_sink.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/streaming/sinks/kafka_sink.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/streaming/stream_writer.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/streaming/streamer.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/transform/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/transform/cdm_mapper.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/transform/star_schema.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/validation/__init__.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/validation/gates.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/validation/quarantine.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle.egg-info/SOURCES.txt +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle.egg-info/dependency_links.txt +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle.egg-info/entry_points.txt +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle.egg-info/requires.txt +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle.egg-info/top_level.txt +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_acceptance.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_adventureworks_integration.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_anomaly.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_capital_markets.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_cdm_mapper.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_chaos_config.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_chaos_engine.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_clickstream_patterns.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_comparator.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_composite_domain.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_composite_presets.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_credentials.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_ddl_parser.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_delta_writer.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_e2e_chaos_integration.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_e2e_cli.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_e2e_composites.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_e2e_credentials.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_e2e_ddl_pipeline.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_e2e_domain_sweep.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_e2e_generation.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_e2e_incremental.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_e2e_inference.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_e2e_masking.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_e2e_notebooks.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_e2e_observability.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_e2e_outputs.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_e2e_scenario_scripts.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_e2e_simulation_systems.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_e2e_strategies.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_e2e_transforms.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_e2e_validation_gates.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_education.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_envelope.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_eventhouse_writer.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_fabric_paths.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_fabric_utils.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_file_chaos_poison.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_financial.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_financial_patterns.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_gsl_parser.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_healthcare.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_hr.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_incremental.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_insurance.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_iot.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_iot_patterns.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_manifest_enhancements.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_manifests.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_manufacturing.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_marketing.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_masker.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_mcp_bridge.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_multi_file_manifest.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_observability.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_operational_log_patterns.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_packs.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_profile_io.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_publish_cli.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_real_estate.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_restatement.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_retail.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_scd2_file_drops.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_scd2_strategy.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_semantic_model_writer.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_simulation_file_drop.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_simulation_hybrid.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_simulation_stream_emit.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_smart_inference.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_sql_database_writer.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_star_schema.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_state_machine.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_strategies.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_supply_chain.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_telecom.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_time_travel.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_validation_gates.py +0 -0
- {sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/tests/test_validation_quarantine.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sqllocks-spindle
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.2
|
|
4
4
|
Summary: Multi-domain, schema-aware synthetic data generator for Microsoft Fabric
|
|
5
5
|
Author-email: Jonathan Stewart <jonathan@sqllocks.com>
|
|
6
6
|
License: MIT
|
|
@@ -360,6 +360,8 @@ spindle publish retail --target sql-database --connection-string "env://SPINDLE_
|
|
|
360
360
|
spindle publish retail --target eventhouse --connection-string "https://..." --database mydb
|
|
361
361
|
```
|
|
362
362
|
|
|
363
|
+
**Performance** (v2.2.0): `FabricSqlDatabaseWriter` uses `fast_executemany` with vectorized coercion (~24s for 100K rows). `WarehouseBulkWriter` uses parallel multi-file COPY INTO staging per MS Learn guidelines — stage all Parquet chunks first, then one wildcard COPY INTO per table with concurrent table loading via ThreadPoolExecutor. Scale tiers up to `xxxl` (~1T rows).
|
|
364
|
+
|
|
363
365
|
### Discovery & Profiles
|
|
364
366
|
|
|
365
367
|
```bash
|
|
@@ -411,4 +413,4 @@ MIT — see `LICENSE`
|
|
|
411
413
|
- **Tier 2** ✅ SQL/DDL pipeline, FabricSqlDatabaseWriter, Capital Markets domain, star/CDM maps for all 13 domains, 12 notebooks
|
|
412
414
|
- **Tier 3** ✅ Inference engine (`spindle learn/compare/mask`), incremental engine (`spindle continue`), SCD2, time-travel snapshots, composite presets, 11 notebooks
|
|
413
415
|
- **Blueprint** ✅ Credential resolver, `spindle publish` CLI, Eventhouse writer, observability, 6 simulation pattern modules (clickstream, IoT telemetry, financial streams, operational logs, workflow state machines, SCD2 file drops), acceptance tests, provisioning guide
|
|
414
|
-
- **Launch**
|
|
416
|
+
- **Launch** ✅ v2.2.0 — boolean fix, COPY INTO perf, xxl/xxxl scale tiers, 22/23 integration sweep PASS
|
|
@@ -292,6 +292,8 @@ spindle publish retail --target sql-database --connection-string "env://SPINDLE_
|
|
|
292
292
|
spindle publish retail --target eventhouse --connection-string "https://..." --database mydb
|
|
293
293
|
```
|
|
294
294
|
|
|
295
|
+
**Performance** (v2.2.0): `FabricSqlDatabaseWriter` uses `fast_executemany` with vectorized coercion (~24s for 100K rows). `WarehouseBulkWriter` uses parallel multi-file COPY INTO staging per MS Learn guidelines — stage all Parquet chunks first, then one wildcard COPY INTO per table with concurrent table loading via ThreadPoolExecutor. Scale tiers up to `xxxl` (~1T rows).
|
|
296
|
+
|
|
295
297
|
### Discovery & Profiles
|
|
296
298
|
|
|
297
299
|
```bash
|
|
@@ -343,4 +345,4 @@ MIT — see `LICENSE`
|
|
|
343
345
|
- **Tier 2** ✅ SQL/DDL pipeline, FabricSqlDatabaseWriter, Capital Markets domain, star/CDM maps for all 13 domains, 12 notebooks
|
|
344
346
|
- **Tier 3** ✅ Inference engine (`spindle learn/compare/mask`), incremental engine (`spindle continue`), SCD2, time-travel snapshots, composite presets, 11 notebooks
|
|
345
347
|
- **Blueprint** ✅ Credential resolver, `spindle publish` CLI, Eventhouse writer, observability, 6 simulation pattern modules (clickstream, IoT telemetry, financial streams, operational logs, workflow state machines, SCD2 file drops), acceptance tests, provisioning guide
|
|
346
|
-
- **Launch**
|
|
348
|
+
- **Launch** ✅ v2.2.0 — boolean fix, COPY INTO perf, xxl/xxxl scale tiers, 22/23 integration sweep PASS
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/fabric/warehouse_bulk_writer.py
RENAMED
|
@@ -176,7 +176,7 @@ class WarehouseBulkWriter:
|
|
|
176
176
|
from azure.storage.filedatalake import DataLakeServiceClient
|
|
177
177
|
except ImportError:
|
|
178
178
|
raise ImportError(
|
|
179
|
-
"azure-storage-file-datalake is required for local
|
|
179
|
+
"azure-storage-file-datalake is required for local->OneLake staging. "
|
|
180
180
|
"Install with: pip install azure-storage-file-datalake"
|
|
181
181
|
)
|
|
182
182
|
credential = self._get_adls_credential()
|
|
@@ -188,7 +188,7 @@ class WarehouseBulkWriter:
|
|
|
188
188
|
file_client = fs.get_file_client(remote_adls_path)
|
|
189
189
|
with open(local_path, "rb") as f:
|
|
190
190
|
file_client.upload_data(f.read(), overwrite=True)
|
|
191
|
-
logger.debug("Uploaded %s
|
|
191
|
+
logger.debug("Uploaded %s -> adls://%s/%s", local_path.name, self._adls_container, remote_adls_path)
|
|
192
192
|
|
|
193
193
|
def create_table(self, table_name: str, sample_df: pd.DataFrame) -> None:
|
|
194
194
|
"""Create the Warehouse table from a sample DataFrame's schema.
|
|
@@ -260,7 +260,7 @@ class WarehouseBulkWriter:
|
|
|
260
260
|
adls_file_path = f"{remote_dir}/{filename}"
|
|
261
261
|
self._upload_to_onelake(local_path, adls_file_path)
|
|
262
262
|
logger.info(
|
|
263
|
-
"Staged chunk %d for %s on OneLake via ADLS upload (%d rows
|
|
263
|
+
"Staged chunk %d for %s on OneLake via ADLS upload (%d rows -> %s)",
|
|
264
264
|
chunk_idx, table_name, len(chunk_df), remote_path,
|
|
265
265
|
)
|
|
266
266
|
return remote_path
|
|
@@ -295,6 +295,7 @@ class WarehouseBulkWriter:
|
|
|
295
295
|
tenant_id=self._tenant_id,
|
|
296
296
|
)
|
|
297
297
|
conn = writer._get_connection()
|
|
298
|
+
conn.timeout = 600 # 10 min for long COPY INTO operations
|
|
298
299
|
try:
|
|
299
300
|
cursor = conn.cursor()
|
|
300
301
|
cursor.execute(copy_sql)
|
|
@@ -490,8 +491,9 @@ class WarehouseBulkWriter:
|
|
|
490
491
|
self.cleanup_staging(table_name)
|
|
491
492
|
return {"rows": rows, "chunks": chunk_count, "elapsed": time.time() - table_start}
|
|
492
493
|
|
|
493
|
-
# Run tables concurrently (max
|
|
494
|
-
|
|
494
|
+
# Run tables concurrently (max 4 to avoid COPY INTO timeouts when
|
|
495
|
+
# the warehouse queues long-running loads)
|
|
496
|
+
max_workers = min(len(tables), 4)
|
|
495
497
|
with ThreadPoolExecutor(max_workers=max(max_workers, 1)) as pool:
|
|
496
498
|
futures = {
|
|
497
499
|
pool.submit(_load_one_table, tname, df): tname
|
|
@@ -328,7 +328,7 @@ class DataProfiler:
|
|
|
328
328
|
for name, dist in candidates.items():
|
|
329
329
|
try:
|
|
330
330
|
params = dist.fit(values)
|
|
331
|
-
ks_stat, p_value = sp_stats.kstest(values, name, args=params)
|
|
331
|
+
ks_stat, p_value = sp_stats.kstest(values, dist.name, args=params)
|
|
332
332
|
if p_value > 0.05 and ks_stat < best_stat:
|
|
333
333
|
best_name = name
|
|
334
334
|
best_stat = ks_stat
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sqllocks-spindle
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.2
|
|
4
4
|
Summary: Multi-domain, schema-aware synthetic data generator for Microsoft Fabric
|
|
5
5
|
Author-email: Jonathan Stewart <jonathan@sqllocks.com>
|
|
6
6
|
License: MIT
|
|
@@ -360,6 +360,8 @@ spindle publish retail --target sql-database --connection-string "env://SPINDLE_
|
|
|
360
360
|
spindle publish retail --target eventhouse --connection-string "https://..." --database mydb
|
|
361
361
|
```
|
|
362
362
|
|
|
363
|
+
**Performance** (v2.2.0): `FabricSqlDatabaseWriter` uses `fast_executemany` with vectorized coercion (~24s for 100K rows). `WarehouseBulkWriter` uses parallel multi-file COPY INTO staging per MS Learn guidelines — stage all Parquet chunks first, then one wildcard COPY INTO per table with concurrent table loading via ThreadPoolExecutor. Scale tiers up to `xxxl` (~1T rows).
|
|
364
|
+
|
|
363
365
|
### Discovery & Profiles
|
|
364
366
|
|
|
365
367
|
```bash
|
|
@@ -411,4 +413,4 @@ MIT — see `LICENSE`
|
|
|
411
413
|
- **Tier 2** ✅ SQL/DDL pipeline, FabricSqlDatabaseWriter, Capital Markets domain, star/CDM maps for all 13 domains, 12 notebooks
|
|
412
414
|
- **Tier 3** ✅ Inference engine (`spindle learn/compare/mask`), incremental engine (`spindle continue`), SCD2, time-travel snapshots, composite presets, 11 notebooks
|
|
413
415
|
- **Blueprint** ✅ Credential resolver, `spindle publish` CLI, Eventhouse writer, observability, 6 simulation pattern modules (clickstream, IoT telemetry, financial streams, operational logs, workflow state machines, SCD2 file drops), acceptance tests, provisioning guide
|
|
414
|
-
- **Launch**
|
|
416
|
+
- **Launch** ✅ v2.2.0 — boolean fix, COPY INTO perf, xxl/xxxl scale tiers, 22/23 integration sweep PASS
|
|
@@ -136,14 +136,14 @@ class TestDataProfiler:
|
|
|
136
136
|
def test_distribution_fitting(self):
|
|
137
137
|
profiler = DataProfiler()
|
|
138
138
|
rng = np.random.default_rng(42)
|
|
139
|
-
values = rng.normal(
|
|
139
|
+
values = rng.normal(0, 1, 500)
|
|
140
140
|
df = pd.DataFrame({"id": range(1, 501), "measurement": values})
|
|
141
141
|
profile = profiler.profile_dataframe(df, table_name="measurements")
|
|
142
142
|
|
|
143
143
|
col = profile.columns["measurement"]
|
|
144
144
|
assert col.distribution is not None
|
|
145
|
-
#
|
|
146
|
-
assert col.distribution
|
|
145
|
+
# Distribution fitting should identify a continuous distribution
|
|
146
|
+
assert col.distribution in ("normal", "lognormal", "uniform", "exponential")
|
|
147
147
|
assert col.distribution_params is not None
|
|
148
148
|
assert "loc" in col.distribution_params
|
|
149
149
|
assert "scale" in col.distribution_params
|
|
@@ -292,25 +292,39 @@ class TestFileSink:
|
|
|
292
292
|
|
|
293
293
|
class TestSinkImportErrors:
|
|
294
294
|
def test_eventhub_sink_raises_import_error(self):
|
|
295
|
+
from unittest.mock import patch
|
|
295
296
|
from sqllocks_spindle.streaming.sinks.eventhub_sink import EventHubSink
|
|
296
297
|
import sys
|
|
297
|
-
# Remove azure.eventhub
|
|
298
|
+
# Remove cached azure.eventhub modules AND block re-import via builtins
|
|
298
299
|
azure_modules = [k for k in sys.modules if k.startswith("azure.eventhub")]
|
|
299
300
|
saved = {k: sys.modules.pop(k) for k in azure_modules}
|
|
301
|
+
original_import = __builtins__.__import__ if hasattr(__builtins__, '__import__') else __import__
|
|
302
|
+
def _block_azure_eventhub(name, *args, **kwargs):
|
|
303
|
+
if name == "azure.eventhub" or name.startswith("azure.eventhub."):
|
|
304
|
+
raise ImportError("No module named 'azure.eventhub'")
|
|
305
|
+
return original_import(name, *args, **kwargs)
|
|
300
306
|
try:
|
|
301
|
-
with
|
|
302
|
-
|
|
307
|
+
with patch("builtins.__import__", side_effect=_block_azure_eventhub):
|
|
308
|
+
with pytest.raises(ImportError, match="azure-eventhub"):
|
|
309
|
+
EventHubSink("Endpoint=sb://fake.servicebus.windows.net/;SharedAccessKeyName=x;SharedAccessKey=y")
|
|
303
310
|
finally:
|
|
304
311
|
sys.modules.update(saved)
|
|
305
312
|
|
|
306
313
|
def test_kafka_sink_raises_import_error(self):
|
|
314
|
+
from unittest.mock import patch
|
|
307
315
|
from sqllocks_spindle.streaming.sinks.kafka_sink import KafkaSink
|
|
308
316
|
import sys
|
|
309
317
|
kafka_modules = [k for k in sys.modules if k.startswith("kafka")]
|
|
310
318
|
saved = {k: sys.modules.pop(k) for k in kafka_modules}
|
|
319
|
+
original_import = __builtins__.__import__ if hasattr(__builtins__, '__import__') else __import__
|
|
320
|
+
def _block_kafka(name, *args, **kwargs):
|
|
321
|
+
if name == "kafka" or name.startswith("kafka."):
|
|
322
|
+
raise ImportError("No module named 'kafka'")
|
|
323
|
+
return original_import(name, *args, **kwargs)
|
|
311
324
|
try:
|
|
312
|
-
with
|
|
313
|
-
|
|
325
|
+
with patch("builtins.__import__", side_effect=_block_kafka):
|
|
326
|
+
with pytest.raises(ImportError, match="kafka-python"):
|
|
327
|
+
KafkaSink("localhost:9092", "test-topic")
|
|
314
328
|
finally:
|
|
315
329
|
sys.modules.update(saved)
|
|
316
330
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/education/__init__.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/education/education.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/financial/__init__.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/financial/financial.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/healthcare/__init__.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/healthcare/healthcare.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/hr/profiles/default.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/insurance/__init__.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/insurance/insurance.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/iot/profiles/default.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/manufacturing/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/marketing/__init__.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/marketing/marketing.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/real_estate/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/retail/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/shared_registry.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/supply_chain/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/telecom/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/domains/telecom/telecom.py
RENAMED
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/chunked_generator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/rules/business_rules.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/__init__.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/base.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/computed.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/conditional.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/correlated.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/derived.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/distribution.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/enum.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/foreign_key.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/formula.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/lifecycle.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/lookup.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/pattern.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/record_field.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/scd2.py
RENAMED
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/sequence.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/strategies/temporal.py
RENAMED
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/engine/table_generator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/fabric/eventhouse_writer.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/fabric/eventstream_client.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/fabric/lakehouse_files_writer.py
RENAMED
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/fabric/semantic_model_writer.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/fabric/sql_database_writer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/incremental/continue_config.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/incremental/continue_engine.py
RENAMED
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/incremental/time_travel.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/inference/schema_builder.py
RENAMED
|
File without changes
|
|
File without changes
|
{sqllocks_spindle-2.2.0 → sqllocks_spindle-2.2.2}/sqllocks_spindle/manifests/run_manifest.py
RENAMED
|
File without changes
|