Database¶
The database is represented by a ParamDB object. A path is passed, and a new
database file is created if it does not already exist. We can parameterize the class with
the root data type in order for its methods (e.g. ParamDB.commit()) work properly
with type checking. For example:
from paramdb import ParamDataclass, ParamDB
class Root(ParamDataclass):
param: CustomParam
class CustomParam(ParamDataclass):
value: float
param_db = ParamDB[Root]("path/to/param.db")
Important
The ParamDB object should be created once per project and imported by other
files that access the database.
Note
Dataclass fields created with init=False will not be stored in or restored from the
database. See dataclasses.field for more information.
Commit and Load¶
Data can be committed using ParamDB.commit() and loaded using
ParamDB.load(), which either loads the most recent commit, or takes a specific
commit ID. Note that commit IDs start from 1. For example:
root = Root(param=CustomParam(value=1.23))
param_db.commit(f"Initial commit", root)
for _ in range(10):
root.param.value += 1
param_db.commit(f"Increment param value to {root.param.value}", root)
We can then load the most recent commit:
param_db.load()
Root(param=CustomParam(value=11.23))
Or a specific previous commit:
param_db.load(5)
Root(param=CustomParam(value=5.23))
Commit History¶
We can get a list of commits (as CommitEntry objects) using the
ParamDB.commit_history() method.
param_db.commit_history()
[CommitEntry(id=1, message='Initial commit', timestamp=datetime.datetime(2025, 8, 27, 5, 4, 52, 734102, tzinfo=datetime.timezone(datetime.timedelta(0), 'UTC'))),
CommitEntry(id=2, message='Increment param value to 2.23', timestamp=datetime.datetime(2025, 8, 27, 5, 4, 52, 741233, tzinfo=datetime.timezone(datetime.timedelta(0), 'UTC'))),
CommitEntry(id=3, message='Increment param value to 3.23', timestamp=datetime.datetime(2025, 8, 27, 5, 4, 52, 747400, tzinfo=datetime.timezone(datetime.timedelta(0), 'UTC'))),
CommitEntry(id=4, message='Increment param value to 4.23', timestamp=datetime.datetime(2025, 8, 27, 5, 4, 52, 753367, tzinfo=datetime.timezone(datetime.timedelta(0), 'UTC'))),
CommitEntry(id=5, message='Increment param value to 5.23', timestamp=datetime.datetime(2025, 8, 27, 5, 4, 52, 759046, tzinfo=datetime.timezone(datetime.timedelta(0), 'UTC'))),
CommitEntry(id=6, message='Increment param value to 6.23', timestamp=datetime.datetime(2025, 8, 27, 5, 4, 52, 764962, tzinfo=datetime.timezone(datetime.timedelta(0), 'UTC'))),
CommitEntry(id=7, message='Increment param value to 7.23', timestamp=datetime.datetime(2025, 8, 27, 5, 4, 52, 770654, tzinfo=datetime.timezone(datetime.timedelta(0), 'UTC'))),
CommitEntry(id=8, message='Increment param value to 8.23', timestamp=datetime.datetime(2025, 8, 27, 5, 4, 52, 776186, tzinfo=datetime.timezone(datetime.timedelta(0), 'UTC'))),
CommitEntry(id=9, message='Increment param value to 9.23', timestamp=datetime.datetime(2025, 8, 27, 5, 4, 52, 781968, tzinfo=datetime.timezone(datetime.timedelta(0), 'UTC'))),
CommitEntry(id=10, message='Increment param value to 10.23', timestamp=datetime.datetime(2025, 8, 27, 5, 4, 52, 787547, tzinfo=datetime.timezone(datetime.timedelta(0), 'UTC'))),
CommitEntry(id=11, message='Increment param value to 11.23', timestamp=datetime.datetime(2025, 8, 27, 5, 4, 52, 793071, tzinfo=datetime.timezone(datetime.timedelta(0), 'UTC')))]
A specific range can also be requested by passing in start and/or end indices to
ParamDB.commit_history(), which function like Python list slicing, where the
start index is inclusive and the end is exclusive. For example:
param_db.commit_history(3, 6)
[CommitEntry(id=4, message='Increment param value to 4.23', timestamp=datetime.datetime(2025, 8, 27, 5, 4, 52, 753367, tzinfo=datetime.timezone(datetime.timedelta(0), 'UTC'))),
CommitEntry(id=5, message='Increment param value to 5.23', timestamp=datetime.datetime(2025, 8, 27, 5, 4, 52, 759046, tzinfo=datetime.timezone(datetime.timedelta(0), 'UTC'))),
CommitEntry(id=6, message='Increment param value to 6.23', timestamp=datetime.datetime(2025, 8, 27, 5, 4, 52, 764962, tzinfo=datetime.timezone(datetime.timedelta(0), 'UTC')))]
Note that the indices passed in are list indices, and do not necessarily correspond
to commit IDs, whereas ParamDB.load() takes in a specific commit ID.
Negative indices also are allowed and function like Python list slicing. For example, to
get the last three commits, we can pass in -3 for the start and leave the end as
None.
param_db.commit_history(start=-3)
[CommitEntry(id=9, message='Increment param value to 9.23', timestamp=datetime.datetime(2025, 8, 27, 5, 4, 52, 781968, tzinfo=datetime.timezone(datetime.timedelta(0), 'UTC'))),
CommitEntry(id=10, message='Increment param value to 10.23', timestamp=datetime.datetime(2025, 8, 27, 5, 4, 52, 787547, tzinfo=datetime.timezone(datetime.timedelta(0), 'UTC'))),
CommitEntry(id=11, message='Increment param value to 11.23', timestamp=datetime.datetime(2025, 8, 27, 5, 4, 52, 793071, tzinfo=datetime.timezone(datetime.timedelta(0), 'UTC')))]