ETL helpers focused on Fabric SQL workloads
Project description
dataprepkit metadata-driven SCD2 orchestrator
dataprepkit turns CSV snapshots into evolving dimensions by declaring the schema, keys, and dependency joins in metadata. The loader and scd2.apply_changes take care of schema evolution, dependency joins, normalizing datetimes, and the SCD2 workflow.
Metadata format
Each metadata entry registered via register_metadata(name, metadata) must include:
| Key | Description |
|---|---|
target_table |
Table name (schemaless or schema-qualified; target_schema can fill in the schema). |
target_schema |
Optional schema name. The loader auto-prefixes it during registration and creates the schema if missing. |
natural_key_cols |
List of natural key columns—required. |
natural_key_specs |
Optional overrides (ColumnSpec) for natural keys (type, nullable, unique, default). |
data_columns |
Map of column names → ColumnSpec. Required. |
surrogate_key / join_numeric_key |
System column names. |
filepath |
CSV path (or lakehouse path) to read. |
schema_handling.mode |
"suggest" (default) or "evolve" (auto-add missing columns). |
processing_class |
Optional callable that transforms the incoming pandas DataFrame. |
dependencies |
Optional dependency definitions (see below). |
run_policy |
Determines failure handling (continue or abort). |
archive_path |
Optional location for parquet archives. |
ColumnSpec fields:
type: SQL type (e.g.,NVARCHAR(4000),DATETIME2(3)).nullable: boolean.unique: boolean flag.default: SQL default expression.parse_format: optional format string for datetime parsing before staging.
Reserved NA convention:
- Any row whose natural key columns are all
"NA"is treated as the reservedNAmember automatically. - By default the reserved
NAmember uses-1for both the surrogate key and the join numeric key. - Duplicate
NArows fail the load. - Use
required_reserved_source_valuesto require special source rows likeNAorUNKNOWNto appear in a given dimension snapshot. - Use
reserved_source_memberswhen your pipeline contract needs different reserved key mappings, for exampleNA -> -1andUNKNOWN -> -2. - The reserved
NAmember does not participate in SCD2 history; it is stored as a single latest-value row and overwritten in place.
Example:
{
"schema_handling": {"mode": "evolve"},
"target_table": "tbl_d_company",
"target_schema": "Dimensions",
"natural_key_cols": ["Organisation_Cd"],
"data_columns": {
"Legacy_Company_Name": {"type": "NVARCHAR(4000)", "nullable": true},
"New_Column_From_Join": {"type": "NVARCHAR(4000)", "nullable": true}
},
"surrogate_key": "surrogate_key",
"join_numeric_key": "join_numeric_key",
"filepath": "/lakehouse/.../company_dim.csv",
"dependencies": [
{
"schema": "Dimensions",
"table": "tbl_d_company_service",
"on": [{"source": "Service_Type_Cd", "target": "Service_Type_Cd"}],
"select": {"Service_Description": "New_Column_From_Join"},
"where": {"target": ["Current_Ind == 1"]},
"how": "left",
"on_missing": "null"
}
]
}
Dependency joins
DependencyJoin entries support:
schema/table: lookup table to join to.on: list of{source, target}mappings between incoming and lookup columns.select: mapping of lookup column → alias added to the incoming frame.where: optional SQL filters applied before the join.filter_target_current: restricts toCurrent_Ind = 1rows (defaultTrue).how:"left"or"inner".on_missing:"null"or"error".
Joins run inside SQL; pandas only reads the filtered result set, renames columns, and maps the selected values to the incoming DataFrame.
Runtime flow
- Register metadata (see
examples/run_metadata_example_fabric.py). - Call
run_dimension(engine, metadata_name, csv_reader=...). - Loader steps:
- read CSV (custom reader may handle lakehouse authentication);
- cast datetimes using optional
parse_format; - ensure schema/table exist (auto-create/evolve if needed);
- run SQL dependency joins;
- apply SCD2 history for normal rows and latest-only handling for the reserved
NArow.
Tests
python -m pytest dataprepkit/tests/test_metadata_loader.py— metadata parsing, datetime casting, dependency joins, schema aliases.python -m pytest dataprepkit/tests/scd2/test_apply_changes.py::test_nullable_data_column_allows_null_staging— staging with nullable columns.
Examples
examples/run_metadata_example_fabric.py– registers multiple metadata objects and drives Fabric-based loading.examples/run_scd2_fabric.py– demo insert/update/delete/reinsert phases on Fabric tables.
Notes
- Metadata entries are validated via Pydantic; missing keys raise errors.
- Update metadata before rerunning
run_dimensionto maintain the registry. - The system is designed for declarative metadata so you can add dimensions by editing metadata, not code.
Helpers modules
dataprepkit.helpers exposes reusable utilities:
helpers/connectors/fabric.py– Fabric SQL connection builder that handles MSI tokens, driver selection, and pooling. Usecreate_engine_for_fabric(endpoint, database, preferred_driver, ...)plusvalidate(engine)before running any metadata loads.helpers/storage.py– Lakehouse/mount helpers (mounting, paths) used by the Fabric examples; consult it for paths when you need to read raw CSVs stored in your lakehouse.- Additional helper modules (e.g., connector-specific tooling) are referenced by the examples so you can replicate the Fabric patterns on other platforms.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ofwat_dataprepkit-0.18.tar.gz.
File metadata
- Download URL: ofwat_dataprepkit-0.18.tar.gz
- Upload date:
- Size: 62.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5148f0923fb9d6e1e328acea2a93e2cb5bad522994167c3bf5fdfc6a453cd6e9
|
|
| MD5 |
e191665e2f58bee587a6fd86d0313ced
|
|
| BLAKE2b-256 |
98279107e65493c75a7aa0b67faa41306aa8c6ff49f9248acc07ebc89b5b3aa1
|
Provenance
The following attestation bundles were made for ofwat_dataprepkit-0.18.tar.gz:
Publisher:
publish-to-pypi.yml on Ofwat/dataprepkit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ofwat_dataprepkit-0.18.tar.gz -
Subject digest:
5148f0923fb9d6e1e328acea2a93e2cb5bad522994167c3bf5fdfc6a453cd6e9 - Sigstore transparency entry: 1369900190
- Sigstore integration time:
-
Permalink:
Ofwat/dataprepkit@fa64519d486b9bc7be51663553d9840973740040 -
Branch / Tag:
refs/tags/v0.18 - Owner: https://github.com/Ofwat
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@fa64519d486b9bc7be51663553d9840973740040 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ofwat_dataprepkit-0.18-py3-none-any.whl.
File metadata
- Download URL: ofwat_dataprepkit-0.18-py3-none-any.whl
- Upload date:
- Size: 65.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7c104b8757b8a3d32e5ce295b02b45e1461ae9a0408e19ffcaf1c8fe27b95941
|
|
| MD5 |
04091edce3e6304822d82aa425ad8322
|
|
| BLAKE2b-256 |
d4df0fbb97e2f8e5b1018006d97a3901092021d440da35799909f8406909b856
|
Provenance
The following attestation bundles were made for ofwat_dataprepkit-0.18-py3-none-any.whl:
Publisher:
publish-to-pypi.yml on Ofwat/dataprepkit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ofwat_dataprepkit-0.18-py3-none-any.whl -
Subject digest:
7c104b8757b8a3d32e5ce295b02b45e1461ae9a0408e19ffcaf1c8fe27b95941 - Sigstore transparency entry: 1369900235
- Sigstore integration time:
-
Permalink:
Ofwat/dataprepkit@fa64519d486b9bc7be51663553d9840973740040 -
Branch / Tag:
refs/tags/v0.18 - Owner: https://github.com/Ofwat
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@fa64519d486b9bc7be51663553d9840973740040 -
Trigger Event:
push
-
Statement type: