Consider the project as a proof of concept! Definitely not production ready!
Dynafile
Embedded pure Python NoSQL database following DynamoDB concepts.
pip install dynafile
# with string filter support using filtration
pip install "dynafile[filter]"
# bloody edge
pip install git+https://github.com/eruvanos/dynafile.git
pip install filtration
Overview
Dynafile stores items within partitions, which are stored as separate files. Each partition contains a SortedDict
from sortedcontainers which are sorted by the sort key attribute.
Dynafile does not implement the interface or functionality of DynamoDB, but provides familiar API patterns.
Differences:
- Embedded, file based
- No pagination
Features
- persistence
- put item
- get item
- delete item
- scan - without parameters
- query - starts_with
- query - index direction
- query - filter
- scan - filter
- batch writer
- atomic file write
- event stream hooks (put, delete)
- TTL
Roadmap
- GSI - global secondary index
- update item
- batch get
- thread safeness
-
LSI - local secondary index - split partitions
- parallel scans - pre defined scan segments
- transactions
- optimise disc load time (cache partitions in memory, invalidate on file change)
- conditional put item
- improve file consistency (options: acidfile)
API
from dynafile import *
# init DB interface
db = Dynafile(path=".", pk_attribute="PK", sk_attribute="SK")
# put items
db.put_item(item={"PK": "user#1", "SK": "user#1", "name": "Bob"})
db.put_item(item={"PK": "user#1", "SK": "role#1", "TYPE": "sender"})
db.put_item(item={"PK": "user#2", "SK": "user#2", "name": "Alice"})
# more performant batch operation
with db.batch_writer() as writer:
db.put_item(item={"PK": "user#3", "SK": "user#3", "name": "Steve"})
db.delete_item(key={"PK": "user#3", "SK": "user#3"})
# retrieve items
item = db.get_item(key={
"PK": "user#1",
"SK": "user#1"
})
# query item collection by pk
items = list(db.query(pk="user#1"))
# scan full table
items = list(db.scan())
# add event stream listener to retrieve item modification
def print_listener(event: Event):
print(event.action)
print(event.old)
print(event.new)
db.add_stream_listener(print_listener)
Filter
query and scan support filter, you can provide callables as filter like lambda expressions.
Another option are filtration expressions.
- Equal ("==")
- Not equal ("!=")
- Less than ("<")
- Less than or equal ("<=")
- Greater than (">")
- Greater than or equal (">=")
- Contains ("in")
- RHS must be a list or a Subnet
- Regular expression ("=~")
- RHS must be a regex token
Examples:
SK =~ /^a/- SK starts with aSK == 1- SK is equal 1SK == 1- SK is equal 1nested.a == 1- accesses nested structureitem.nested.a
TTL - Time To Live
TTL provides the option to expire items on read time (get, query, scan).
import time
from dynafile import *
db = Dynafile(path=".", pk_attribute="PK", sk_attribute="SK", ttl_attribute="ttl")
item = {"PK": "1", "SK": "2", "ttl": time.time() - 1000} # expired ttl
db.put_item(item=item)
list(db.scan()) # -> []
Architecture
File Structure
--- ROOT ---
./db/
--- MAIN DB ---
|- meta.json - meta information
|- _partitions/
|- <hash>/
|- data.pickle - Contains partition data by sort key (SortedDict)
|- lsi-attr1.pickle - Contains partition data by lsi attr (SortedDict)
--- GSI ---
|- _gsi-<gsi-name>/
|- _partitions/
|- <hash>/
|- data.pickle - Contains partition data by sort key (SortedDict)
Metadata
Release files for dynafile 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| dynafile-0.1.3.tar.gz | 55.9 kB | Without provenance | Details for dynafile-0.1.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| dynafile-0.1.3-py3-none-any.whl | Python 3 | none | any | Details for dynafile-0.1.3-py3-none-any.whl |
Total release size: 62.8 kB
Release files / dynafile-0.1.3.tar.gz
| Download URL | dynafile-0.1.3.tar.gz |
|---|---|
| Size | 55.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f9402213a375358b4a22d9cdf3b423c4c99016f92a7505c893d0ade399f74aae
|
|
BLAKE2b-256 checksum How to use checksums |
c4d90d7e79caf7d3c7ac66dac24871c567bc4a40ffd3b53a3603238e9be018da
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.12.2
|
Release files / dynafile-0.1.3-py3-none-any.whl
| Download URL | dynafile-0.1.3-py3-none-any.whl |
|---|---|
| Size | 6.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
09ead0032825d5e83662d469891069d0e63a8630f420bd1429e2cf208052b0a9
|
|
BLAKE2b-256 checksum How to use checksums |
b4aa7c02df390215aa2dcd24519e2651ea490d8ab1ddbfcbb70cd25f5e2ae1df
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.12.2
|
Security for dynafile 0.1.3
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.