fix(storage): preserve the EIA-930 fuel mix in the degenerate write path - #30
Merged
Conversation
… fuel-mix data loss The EIA-930 generation-by-fuel connector emits ~10 rows per (BA, hour) distinguished only by the fuel_type column, but _canonicalize and write_bars deduplicated on the valid_time index alone, so a single arbitrary fuel per hour survived in power.generation_by_fuel on every hourly ingest. Dedup now keys on a (Datetime, fuel_type) MultiIndex whenever a fuel_type column is present (_dedup_key), in _canonicalize and in both write_bars paths (new-row check and interior-insert). Sorting is a stable sort_index: ArcticDB validate_index=True only requires a sorted index, so duplicate timestamps across fuels are fine. Frames without fuel_type behave exactly as before; keep="last" semantics unchanged. Verified end-to-end by materializing eia930_generation_by_fuel against a scratch lmdb store: 72 BAs / 33,386 rows / 15 fuel types stored, 8-9 fuels per hour for CISO/ERCO/MISO (previously 1), re-pull idempotent. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
power.generation_by_fuelwas silently losing ~90% of its data on every hourly ingest:_canonicalizeandwrite_barsinsrc/energex/core/storage.pydeduplicated on thevalid_timeindex alone, while the EIA-930 generation-by-fuel connector emits ~10 rows per (BA, hour) distinguished only by thefuel_typecolumn (schemaPOWER_GEN_BY_FUELrequires uniqueness over[instrument_id, valid_time, fuel_type]). Only one arbitrary fuel per hour survived.Fix
_dedup_key()helper: theDatetimeindex, extended to a(Datetime, fuel_type)MultiIndex when afuel_typecolumn is present._canonicalizeand bothwrite_barspaths (new-row check, interior-insert dedup) key on it.sort_index: ArcticDBvalidate_index=Trueonly requires a sorted index — duplicate timestamps across fuels are fine.fuel_typebehave exactly as before;keep="last"/append-only semantics unchanged.Tests
New
tests/test_write_bars_fuel_mix.py(written first, all 6 failed on the old code): multi-fuel roundtrip, idempotent rewrite, interior sparse insert, append-after-tail, new fuel at an existing hour, canonicalize-level dedup. Full suite: 268 passed (test_write_bars_sparse.pyandtest_storage_roundtrip.pyuntouched and green).End-to-end verification
Materialized the real
eia930_generation_by_fuelDagster asset (live EIA API → quality gate →write_bars) into a scratch lmdb Arctic store: 72 BA symbols, 33,386 rows, 15 distinct fuel types; CISO stores 9 fuels/hour, ERCO/MISO 8 (previously 1). Re-materializing the same partition changed nothing (idempotent), no duplicate (hour, fuel) pairs, all indexes sorted.Follow-up
eia930_generation_by_fuelover the affected window recovers the full mix; re-ingest adds missing fuels without touching stored rows._observed_fuel_typesonfeat/entity-graphneeds no change — it heals automatically once the store carries the mix. The doc caveat inwebsite/docs/entity-graph.md(that branch) has been updated separately.🤖 Generated with Claude Code