Skip to main content

mpedb-py — Python bindings for mpedb

CPython 3.12+ extension module (PyO3 0.29, abi3-py312: one wheel/.so for all 3.12+ versions). Module name: mpedb. Free-threading friendly by design: no module-level mutable state, and the GIL is released around every engine call, so point reads from multiple Python threads run truly in parallel.

Building

Manual (no extra tooling):

cargo build --release -p mpedb-py
mkdir -p /path/to/pymod
cp target/release/libmpedb_py.so /path/to/pymod/mpedb.so   # the rename is required
PYTHONPATH=/path/to/pymod python3.12 -c "import mpedb; print(mpedb.Database)"

The cdylib is built as libmpedb_py.so but must be importable as mpedb.so (the #[pymodule] is named mpedb, so its init symbol is PyInit_mpedb).

With maturin (builds a proper wheel):

pip install maturin && maturin build --release -m crates/mpedb-py/Cargo.toml

Tests (plain Python, no pytest; run it twice against the same directory to also exercise persistence across process restarts):

PYTHONPATH=/path/to/pymod python3.12 crates/mpedb-py/pytest/test_mpedb.py /tmp/mpedb-pytest
PYTHONPATH=/path/to/pymod python3.12 crates/mpedb-py/pytest/test_mpedb.py /tmp/mpedb-pytest

API

import mpedb
db = mpedb.Database("app.toml")   # open/create from a TOML config file
Call Returns Notes
mpedb.Database(config_path) Database Opens/creates the database described by the TOML config. Thread-safe; share one handle.
db.prepare(sql) str (64-hex plan hash) Compiles once, publishes to the shared plan registry: any attached process can execute it by hash.
db.execute(hash, params=None) SELECT → list[tuple]; DML → int (affected) Hot path — no SQL parsing. params is a list/tuple.
db.query(sql, params=None) as execute; EXPLAIN …str One-shot prepare + execute. Use $1…$n parameters, never interpolate values into the SQL text (each distinct text becomes a registry plan).
db.query_full(sql, params=None) (columns: list[str], rows: list[tuple]) For callers who need output column names. Raises ProgrammingError for non-SELECT.
db.explain(sql) str Plan rendering; nothing is executed (prepends EXPLAIN if absent).
db.tables() list[str] Table names from the schema.
db.verify() None Page-accounting verification; raises on integrity failure. Takes the writer lock briefly.
db.begin() Transaction Interactive write transaction; holds the single writer lock until commit/rollback.
tx.execute(hash, params=None) / tx.query(sql, params=None) as above Run inside the transaction; SELECTs see the session's own uncommitted writes. tx.query plans are cached process-locally, never published.
tx.insert_file(table, values, stream_col, path) None INSERT one row, streaming column stream_col from the file at path a page at a time (never resident — files larger than RAM are fine). values is the full row; values[stream_col] is a placeholder (b""). Path-based on purpose: the engine pulls pages with the writer lock held, so there is no Python read()-callback variant. The streamed column must be the table's last varlen column; tables with a secondary UNIQUE index are refused.
tx.commit() / tx.rollback() None Explicit finish. A dropped/GC'd transaction rolls back.
with db.begin() as tx: Commits on clean exit, rolls back if an exception propagates (never suppresses it).

Value mapping (both directions)

Python mpedb column type Notes
None NULL
bool bool checked before int (Python bool subclasses int)
int int64 out of range → OverflowError
float float64
str text
bytes / bytearray blob always returned as bytes
datetime.datetime timestamp stored as microseconds since epoch, UTC. Aware datetimes are converted to UTC; naive ones are treated as UTC. Returned as an aware UTC datetime. A plain int is also accepted for timestamp parameters and taken as raw microseconds.

Exceptions

mpedb.Error (Exception)
├── mpedb.IntegrityError     primary-key / UNIQUE / NOT NULL / CHECK violations
├── mpedb.ProgrammingError   parse, bind, type mismatch, wrong param count,
│                            unknown/invalidated plan, unsupported statement
└── mpedb.OperationalError   I/O, corruption, DbFull, ReadersFull, evicted
                             snapshot, config/schema mismatch, poisoned write
                             session, engine internals

Messages carry the engine's Display text. Binding-level misuse (bad params container, non-convertible value) raises the ordinary TypeError/OverflowError.

Locking rules (inherited from the Rust facade)

  • Never call db.prepare(...), db.verify(), or db.query(...) for a not-yet-cached statement while a Transaction from the same handle is open on the same thread. They may need the single writer lock the transaction already holds; the ERRORCHECK mutex turns the relock into an error rather than a deadlock. Prepare the statements you need before db.begin(); inside the transaction, tx.query/tx.execute are always safe.
  • Sessions poison on partially-applied statements. Statements are not internally atomic: if e.g. a multi-row UPDATE fails on its third row, the first two are already modified and the session becomes poisoned — every further tx.execute/tx.query and tx.commit() raises mpedb.OperationalError ("… poisoned …") and commit rolls back instead of persisting the torn statement. Only tx.rollback() (or leaving the with block via the exception) is valid. A statement that fails before any side effect (single-row constraint violation, type error) does not poison the session.
  • One writer at a time, process-wide and machine-wide: db.begin() blocks on (or errors for re-entry into) the single writer lock. Readers never block.
  • Use a Transaction from the thread that created it; the writer lock is a pthread mutex with thread affinity.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mpedb-0.1.0.tar.gz (1.8 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

mpedb-0.1.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.2 MB view details)

Uploaded CPython 3.12+manylinux: glibc 2.17+ x86-64

mpedb-0.1.0-cp312-abi3-macosx_11_0_arm64.whl (2.9 MB view details)

Uploaded CPython 3.12+macOS 11.0+ ARM64

File details

Details for the file mpedb-0.1.0.tar.gz.

File metadata

  • Download URL: mpedb-0.1.0.tar.gz
  • Upload date:
  • Size: 1.8 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for mpedb-0.1.0.tar.gz
Algorithm Hash digest
SHA256 37aa240b9ffe70b6e4b6dfad1f26244e7ba4ea0c191e79988d09dab0e2486d8e
MD5 34c8f72983012a61e06696552fb11d96
BLAKE2b-256 2cd43a5dee67c7a056e4102b67e05ccc504218f38f1e300e71962cbe1cfeb67a

See more details on using hashes here.

File details

Details for the file mpedb-0.1.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for mpedb-0.1.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 12637dae277f91a92397829b777cc88bda173f2ff8c74203f492825193fdde6b
MD5 4bd11282c02d93c52bcdd7bcccdca2b8
BLAKE2b-256 b8f4249312a8ae8087ecea655595b45c1c98d80a2c0f967c68f9d15f9bcfdc06

See more details on using hashes here.

File details

Details for the file mpedb-0.1.0-cp312-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for mpedb-0.1.0-cp312-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3318b226ca80ea6287b8cf73869d22793d63d4eb46e29647205e8d0a4c2fadae
MD5 b26fda3b21f58d1ec30f58b17e868c22
BLAKE2b-256 406f341fdde17031cf2531de8417818c160e73abe0fdc2c651bed8af9be09f41

See more details on using hashes here.

Release history Release notifications | RSS feed

0.3.1

7 files

0.3.0

7 files

0.2.9

6 files

0.2.8

6 files

0.2.7

6 files

0.2.6

6 files

0.2.5

6 files

0.2.4

6 files

0.2.3

6 files

0.2.2

6 files

0.2.1

6 files

0.2.0

6 files

0.1.5

6 files

0.1.3

6 files

0.1.2

3 files

0.1.1

3 files

This release

0.1.0 This release

3 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page