FULL-COVERAGE grouped ingest of the entire ECB Data Portal (SDMX 2.1). Source: ECB Data Portal (data-api.ecb.europa.eu). license_id = ecb-attrib-nomodify (from configs/sources.yaml: "Source: ECB -- available free at the ECB; values not modified"). We do NOT modify values; the Clean tier stores the…
European Central Bank, Statistical Data Warehouse. Retrieved from https://data.ecb.europa.eu. Compiled and redistributed by the Elkassabgi Data Library.
Processing: Retrieved from the official source, normalized to a long {series_key, obs_date, value} schema (period-start dates), de-duplicated, and stored as zstd Parquet. Compiled and redistributed by the Elkassabgi Data Library.
FULL-COVERAGE grouped ingest of the entire ECB Data Portal (SDMX 2.1). Source: ECB Data Portal (data-api.ecb.europa.eu). license_id = ecb-attrib-nomodify (from configs/sources.yaml: "Source: ECB -- available free at the ECB; values not modified"). We do NOT modify values; the Clean tier stores the raw observation. Strategy (verified live against data-api.ecb.europa.eu, June 2026): * Catalog = EVERY dataflow from /service/dataflow (213 flows across agencies ECB, ECB.DISS, ESTAT, EUROSTAT, IMF -- ALL hosted at the ECB endpoint). * Data pulled as SDMX-CSV (?format=csvdata) with &detail=dataonly, which strips the ~25 bulky attribute columns (TITLE, OBS_COM, COLLECTION, ...) WITHOUT changing the observation count and is ~10-30x faster to transfer. The CSV header is then: KEY, <dim1..dimN>, TIME_PERIOD, OBS_VALUE. * SERIES KEY = the CSV `KEY` column, which the ECB already emits pre-joined (e.g. "EXR.D.USD.EUR.SP00.A") -> stored verbatim as column `series_key`. FREQ (when present as a column) -> stored as `freq`. * Most flows pull whole in one request. The handful of GIANTS (EXR ~197MB, MIR ~124MB, YC ~11M rows, BSI, ICP/HICP, STS, SEC, IRS, FM, BOP, RPP, ...) are FREQUENCY-CHUNKED via the SDMX positional path key (the DSD dimension order, FREQ value + dots for the rest, e.g. EXR key "D....."). If a single frequency chunk is still huge/fails, it is SUB-SPLIT by the next splitting dimension's codelist values (e.g. YC daily -> by INSTRUMENT_FM curve type). Each chunk is an independent, restart-safe request that lands in its own parquet part, so a process kill costs at most one chunk. OUTPUT: grouped Parquet under data/clean_full/ecb/ -> <AGENCY>__<FLOW>.parquet (whole-flow pulls) <AGENCY>__<FLOW>__<FREQ>.parquet (frequency chunks) <AGENCY>__<FLOW>__<FREQ>__<VAL>.parquet (sub-split chunks) columns: series_key (str), obs_date (date32), value (float64), freq (str). A sidecar _manifest.json records per-flow stats (NOT catalog.db, which is off-limits). Memory is bounded: every HTTP body streams to a temp .csv.gz on disk, is parsed row-by-row, and flushed to the Parquet writer in RecordBatches; no flow is held whole in RAM. The distinct-series set per file is capped to bound memory. Usage: python jobs/ingest_ecb.py --list # enumerate catalog, no data python jobs/ingest_ecb.py --only EXR,YC # just these flows python jobs/ingest_ecb.py --workers 4 # FULL run, 4 concurrent flows python jobs/ingest_ecb.py --report # re-read parquet, print true totals python jobs/ingest_ecb.py # FULL run (default workers=4)
{
"@context": "https://schema.org/",
"@type": "Dataset",
"name": "ECB Data Portal / euro reference rates",
"description": "FULL-COVERAGE grouped ingest of the entire ECB Data Portal (SDMX 2.1). Source: ECB Data Portal (data-api.ecb.europa.eu). license_id = ecb-attrib-nomodify (from configs/sources.yaml: \"Source: ECB -- available free at the ECB; values not modified\"). We do NOT modify values; the Clean tier stores the…",
"url": "https://econdatalibrary.com/ecb.html",
"identifier": "ecb",
"isAccessibleForFree": true,
"publisher": {
"@type": "Organization",
"name": "Econ Data Library",
"url": "https://econdatalibrary.com"
},
"creator": {
"@type": "Organization",
"name": "ECB Data Portal / euro reference rates"
},
"license": "ecb-attrib-nomodify",
"keywords": [
"fx",
"rates",
"ecb"
],
"temporalCoverage": "1994-01-01/2026-06-03",
"repeatFrequency": [
"P1D",
"P1M"
],
"creditText": "Source: ECB -- available free at the ECB; values not modified",
"citation": "European Central Bank, Statistical Data Warehouse. Retrieved from https://data.ecb.europa.eu. Compiled and redistributed by the Elkassabgi Data Library.",
"sameAs": [
"https://huggingface.co/datasets/econdatalibrary-ecb",
"https://zenodo.org/communities/econdatalibrary"
],
"distribution": [
{
"@type": "DataDownload",
"encodingFormat": "text/csv",
"contentUrl": "https://econdatalibrary.com/download.html?source=ecb"
}
]
}{
"@context": {
"@language": "en",
"@vocab": "https://schema.org/",
"cr": "http://mlcommons.org/croissant/",
"data": {
"@id": "cr:data",
"@type": "@json"
},
"dataType": {
"@id": "cr:dataType",
"@type": "@vocab"
},
"sc": "https://schema.org/",
"conformsTo": "dct:conformsTo",
"dct": "http://purl.org/dc/terms/"
},
"@type": "sc:Dataset",
"conformsTo": "http://mlcommons.org/croissant/1.0",
"name": "ecb",
"description": "FULL-COVERAGE grouped ingest of the entire ECB Data Portal (SDMX 2.1). Source: ECB Data Portal (data-api.ecb.europa.eu). license_id = ecb-attrib-nomodify (from configs/sources.yaml: \"Source: ECB -- available free at the ECB; values not modified\"). We do NOT modify values; the Clean tier stores the…",
"url": "https://econdatalibrary.com/ecb.html",
"creator": {
"@type": "sc:Organization",
"name": "ECB Data Portal / euro reference rates"
},
"publisher": {
"@type": "sc:Organization",
"name": "Econ Data Library",
"url": "https://econdatalibrary.com"
},
"license": "ecb-attrib-nomodify",
"keywords": [
"fx",
"rates"
],
"temporalCoverage": "1994-01-01/2026-06-03",
"citation": "European Central Bank, Statistical Data Warehouse. Retrieved from https://data.ecb.europa.eu. Compiled and redistributed by the Elkassabgi Data Library.",
"distribution": [
{
"@type": "cr:FileObject",
"@id": "ecb-csv",
"name": "ecb-csv",
"description": "Per-series CSV, downloadable with a free API key.",
"contentUrl": "https://econdatalibrary.com/download.html?source=ecb",
"encodingFormat": "text/csv"
}
]
}