A lightweight JSON document database with field-level operation queuing and concurrency support
Project description
StarDDB — Python
"Shoot for the moon. Even if you miss, you'll land among the stars." - Norman Vincent Peale
StarDDB is a lightweight, single-file JSON database for Python with field-level operation queuing, lazy loading, and automatic background persistence.
Features
- Lazy loading — field values are read from disk on first access via
mmap; untouched fields never enter memory - Cache eviction — fields not accessed within a configurable threshold are dropped from memory and reloaded on demand
- Field-level queue — arithmetic operations are serialized per-field, preventing race conditions on shared values
- Thread-safe —
RLockper field,Lockon the database for save/reload - Auto-persistence — background thread saves every N seconds; only dirty fields are re-serialized
- Atomic writes — saves go to a
.tmpfile thenos.replace()into place - Nested documents — arbitrary depth with a configurable recursion limit
Installation
pip install starddb
Or from source:
pip install filelock
Quick Start
Field-only usage
from stardb import StarDDBField
field = StarDDBField(0)
field.update("set", 1)
field.update("mult", 5)
field.update("div", 0.5)
field.flush()
print(field.value) # 10.0
Load an existing file (lazy mode)
from stardb import StarDDB
# Values are loaded from disk only when accessed
db = StarDDB("data.json", save_time=5)
hook = db.db()
hook["health"].update("sub", 30)
hook["mana"].update("mult", 2)
db.close() # flushes, saves, stops background thread
Create a new database from a dict
db = StarDDB("data.json", save_time=5, database_hook={
"player": {"health": 100, "mana": 50},
"world": {"level": 1}
})
hook = db.db()
hook["player"]["health"].update("sub", 10)
db.close()
Cache eviction
# Fields unused for 30 seconds are evicted from memory
db = StarDDB("data.json", save_time=5, cache_threshold=30)
API
StarDDBField(value=None, max_queue_size=10000, offsets=None, loader=None)
| Parameter | Description |
|---|---|
value |
Initial value (any JSON-serializable type) |
max_queue_size |
Maximum queued operations before raising RuntimeError (default: 10000) |
Properties:
value— get or set the field's current value (triggers lazy load on first get)
Methods:
update(method, value)— queue an operation (see Operations table below)flush()— block until all queued operations are processeddrop_if_unused(threshold_seconds)— evict value from memory if clean and not recently accessed
StarDDB(database, save_time, database_hook=None, safe_root=None, cache_threshold=60)
| Parameter | Description |
|---|---|
database |
Path to the JSON database file |
save_time |
Seconds between automatic background saves |
database_hook |
Initial data dict; if omitted, file must exist and is loaded lazily |
safe_root |
If set, restricts the database path to this directory (prevents path traversal) |
cache_threshold |
Seconds since last access before a clean field is evicted from memory (default: 60) |
Methods:
| Method | Description |
|---|---|
db() |
Return the database hook (nested dict of StarDDBField instances) |
flush() |
Block until all pending field operations are complete |
save() |
Write the database to disk immediately |
close() |
Flush, save, and stop the background thread |
add_field(key_path, value) |
Add a new field at runtime (see below) |
Operations
| Op | Description |
|---|---|
set |
Set value directly |
add |
Add to current value |
sub |
Subtract from current value |
mult |
Multiply current value |
div |
Divide current value (zero is rejected) |
push |
Append to a list field |
add_field examples
key_path is a dot-separated string or a list of keys. Dict values are automatically crawled into StarDDBField instances.
# Add a primitive
db.add_field("players.new_guy", 0)
# Add a list field
db.add_field("players.new_guy.inventory", [])
# Append to it
hook["players"]["new_guy"]["inventory"].update("push", "sword")
# Add a nested dict (auto-crawled)
db.add_field("players.new_guy", {"coins": 0, "level": 1})
hook["players"]["new_guy"]["coins"].update("add", 5)
# Use a list to avoid dot ambiguity in key names
db.add_field(["some.weird.key", "nested"], 42)
Testing
cd src_python/tests
python test_crawl.py
python test_lazy.py
python test_errors.py
python single_field.py
python multi_field.py
Project details
Release history Release notifications | RSS feed
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 starddb-1.0.2.tar.gz.
File metadata
- Download URL: starddb-1.0.2.tar.gz
- Upload date:
- Size: 11.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
355fded18d8c191b052ea472bdff275faf32a16c8053eeb708855743f83735e5
|
|
| MD5 |
630ec046e5f76a4ba592cd9092d14303
|
|
| BLAKE2b-256 |
d86a4e420b15f5055a907ff9035859ea2823ec323c8609a1b744d67e6654edfe
|
File details
Details for the file starddb-1.0.2-py3-none-any.whl.
File metadata
- Download URL: starddb-1.0.2-py3-none-any.whl
- Upload date:
- Size: 7.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c0b040837ed70f07f9f9f345a88c5fae4b9f8192ad302a4b70a090bea2d074d2
|
|
| MD5 |
6e0122b6b16042fd65e821d698c34262
|
|
| BLAKE2b-256 |
afcfcba12bc5d8fa4bba860e0918212452ec1137a891a36bedb694366bacdcd7
|