Skip to main content

⚡ EnergyDB

Persistent storage for energy portfolios — assets, grid topology, and 3-dimensional time series, in one connected database.

PyPI Python Versions License Slack


🏗️ What is EnergyDB?

EnergyDB is a database for energy portfolios. It stores three things together in one connected system:

Layer Description Real-World Example
🌳 Asset hierarchy Arbitrary-depth tree of portfolios, sites, and assets "Offshore-1 → WindTurbine T01 → power"
🔗 Grid topology Typed edges (lines, transformers, pipes, interconnections) connecting any two assets "Cable-1: BusA → BusB"
⏱️ 3-dimensional time series Actuals and versioned forecasts attached to any node or edge, queryable as-of any point in time "power_flow on Cable-1, valid Wed 12:00, known Mon 18:00"

Structure lives in PostgreSQL, values live in ClickHouse, and stable UUID identity lets Python objects round-trip to the database without losing any structural state.

EnergyDB extends TimeDB with persistent storage for EnergyDataModel hierarchies.


✨ Why EnergyDB?

Most time-series systems are agnostic about what their series represent — they treat data as opaque (series_id, timestamp, value) triples. EnergyDB knows it is a portfolio, and links every series back to the asset or grid edge it describes.

  • 🔁 Round-trip persistence: Every Element keeps its UUID7 from in-memory object to row primary key — renames, moves, and property edits become silent UPDATEs, never delete-then-insert.
  • 📋 Diffable structural changes: dry_run=True previews every insert, rename, move, and delete as a TreeDiff before you apply — no surprise mutations, and the same preview is available across a whole transaction().
  • ⏱️ Time-of-knowledge queries: Forecast revisions, corrections, and as-of backtests, powered by TimeDB.
  • 🧭 Lazy fluent navigation: client.get_node("Portfolio", "Site", "T01").read(...) resolves to one indexed SQL query, regardless of subtree size.
  • ⚖️ Unit conversion at the boundary: Declare canonical units once; pint rescales every read and write automatically.
  • 🧹 Idempotent writes: write(..., skip_unchanged=True) drops rows that only duplicate the latest stored value before insert, so writing the same window repeatedly doesn't bloat storage. The comparison key is chosen per series — actuals dedupe per valid_time, versioned forecasts per (valid_time, knowledge_time) — so a republished forecast is never mistaken for a duplicate. Opt-in; the write still returns its run_id (a WriteResult carrying .written / .skipped counts).
  • 🎯 Partial reads that don't fail: read(manifest, on_missing="skip") returns every series that resolved plus the triples that didn't, so one unregistered series in a 1,500-series manifest costs you that series — not the whole batch.
  • 🧯 Typed errors: NodeNotFoundError, SeriesNotFoundError (carrying every unresolved triple), ManifestError, … all under one EnergyDBError base — so you branch on types and structured fields instead of matching message text. Every class also subclasses ValueError, so broad handlers keep working.

TimeDB demo

🚀 Quick Start

1. Installation

pip install energydb

Requires Python 3.12+, PostgreSQL (asset hierarchy + series catalog), and ClickHouse (time-series values).

Need a local Postgres + ClickHouse? One command brings both up: cd local-db && docker compose up -d (see local-db/, or DEVELOPMENT.md for the full setup).

2. Usage Example

from datetime import UTC, datetime
import energydb as edb
import pandas as pd

client = edb.Client()  # reads TIMEDB_PG_DSN / TIMEDB_CH_URL
client.create()

# 1. Declare your portfolio: a tree of typed assets with their series.
t01 = edb.wind.WindTurbine(
    name="T01", capacity=3.5, hub_height=80,
    timeseries=[edb.TimeSeries(name="power", unit="MW",
                               data_type=edb.DataType.ACTUAL)],
)
portfolio = edb.Portfolio(
    name="my-portfolio",
    members=[edb.Site(name="Offshore-1", members=[t01])],
)
client.register_tree(portfolio)   # create-only; edit existing nodes via scope mutators

# 2. Write hourly power for that turbine.
start = datetime(2026, 1, 1, tzinfo=UTC)
df = pd.DataFrame({
    "valid_time": pd.date_range(start, periods=24, freq="1h", tz="UTC"),
    "value":      [2.5 + 0.05 * i for i in range(24)],
})
client.get_node("my-portfolio", "Offshore-1", "T01").write(
    df, name="power", data_type="actual",
)

# 3. Read across the whole portfolio in one fluent call.
client.get_node("my-portfolio").read(name="power", data_type="actual")

Async? edb.Client is a synchronous facade over edb.AsyncClient. For async/await code, use AsyncClient directly — await client.open() once, then await every method shown above.


🧪 Try it in Google Colab

Want to try EnergyDB without a local setup? Open our Quickstart in Colab — the first cell automatically installs PostgreSQL + ClickHouse inside the VM.

Open In Colab

Note: Data persists only within the active Colab session. Additional notebooks are available in the examples/ directory.


📚 Documentation & Resources


📦 Related Projects

Project Description
TimeDB 3-dimensional time-series storage on ClickHouse with auditability and overlapping-forecast support
TimeDataModel Pythonic data model for time series
EnergyDataModel Data model for energy assets (solar, wind, battery, grid, ...)

🤝 Contributing

Contributions are welcome! If you're interested in improving EnergyDB, please see our Development Guide for local setup instructions.


Licensed under the Apache-2.0 License.

Find a bug or have a feature request? Open an Issue.

Metadata

Release files for energydb 0.10.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for energydb 0.10.0
File Size Uploaded
energydb-0.10.0.tar.gz 167.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for energydb 0.10.0
File Interpreter ABI Platform
energydb-0.10.0-py3-none-any.whl Python 3 none any Details

Total release size: 270.0 kB

Release files / energydb-0.10.0.tar.gz

Download URL energydb-0.10.0.tar.gz
Size 167.2 kB
Tags Source
SHA-256 checksum
How to use checksums
b8b328a0850cce9ec5b8668d7443a8f8132b2641e5e7d0429bd60d24a0f81947
BLAKE2b-256 checksum
How to use checksums
8858e500d6273dd659bc75ed0b247bd50e31c22e039ce2bb1a9c051bb61a48c5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 17, 2026.

Transparency log

Release files / energydb-0.10.0-py3-none-any.whl

Download URL energydb-0.10.0-py3-none-any.whl
Size 102.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
727268b09906c672a21087b05c926a2cf5962e04a54808dcee8b4dbcb5de6d3b
BLAKE2b-256 checksum
How to use checksums
b4e7d9adf9e20af59b33e7a0aaebf252b7b30bf744490bec8f573d94fbc299d5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 17, 2026.

Transparency log

Release history Release notifications | RSS feed

0.12.0

2 release files

0.11.0

2 release files

This release

0.10.0 This release

2 release files

0.9.0

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.3

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page