Skip to main content

A sqlite3-compatible DB-API adapter for GNU recfiles

Project description

recdb

A PEP 249-style Python DB-API adapter for GNU recfiles — plain-text, human-readable, git diff-able databases.

Wikipedia: Recutils / Recfiles

Why?

Recfiles are plain text — human-readable, diffable with git diff, editable with any text editor, queryable with standard Unix tools. For small projects where textual transparency matters more than performance, they're a compelling alternative to a binary database file like SQLite.

recdb lets you use a familiar SQL subset against recfiles, with a clean one-line migration path to SQLite when you outgrow them.

Installation

pip install recdb
apt install recutils        # or: brew install recutils

Quickstart

# ── Recfile backend (plain text, human-readable) ──────────────────────────────
import recdb
conn = recdb.connect("inventory.rec")

# ── SQLite backend as an example of migration from Recfile ──────────────────
import sqlite3
conn = sqlite3.connect("inventory.db")

# ── Identical API from here ───────────────────────────────────────────────────
conn.execute(
    "INSERT INTO items (name, sku, stock, price) VALUES (?, ?, ?, ?)",
    ("Widget", "WGT-001", 50, 9.99)
)
conn.commit()

cur = conn.execute("SELECT * FROM items WHERE stock > 0")
for row in cur.fetchall():
    print(row["name"], row["stock"])

conn.close()

Switching from recfile to SQLite is a one-line change — replace recdb.connect("inventory.rec") with sqlite3.connect("inventory.db") and the rest of your code stays the same.

Context manager

with recdb.connect("inventory.rec") as conn:
    conn.execute("UPDATE items SET stock = 45 WHERE sku = 'WGT-001'")
# commit() called automatically on clean exit

Supported SQL

Statement Example
SELECT SELECT * FROM items
Column projection SELECT name, stock FROM items
WHERE SELECT * FROM items WHERE stock < 10
ORDER BY SELECT * FROM items ORDER BY price DESC
LIMIT SELECT * FROM items LIMIT 5
INSERT INSERT INTO items (name, sku, stock) VALUES ('X', 'X-1', 5)
UPDATE UPDATE items SET stock = 50 WHERE sku = 'WGT-001'
DELETE DELETE FROM items WHERE stock = 0
CREATE TABLE CREATE TABLE items (name text, sku text, stock int, price real)
Parameter binding cursor.execute("SELECT * FROM items WHERE sku = ?", ("WGT-001",))

WHERE clause operators support

= != < > <= >= LIKE AND

OR, IN, subqueries, JOIN, GROUP BY, UNION, and HAVING are not currently supported in the recfile backend (raises AssertionError).

File layout

recdb.connect() takes a path to a single .rec file.

Multiple tables are supported within one file using recutils' native multi-type format — multiple %rec: blocks in a single file.

Example .rec file with two tables:

%rec: items
%mandatory: name sku stock price
%type: stock int
%type: price real

name: Widget A
sku: WGT-001
stock: 120
price: 9.99

name: Widget B
sku: WGT-002
stock: 5
price: 14.50

%rec: suppliers
%mandatory: name contact

name: Acme Corp
contact: acme@example.com

Rows are dicts

The recfile backend returns rows as dict. Column access by name is always safe:

row = cur.fetchone()
print(row["name"])    # works
print(row["stock"])   # works

See COMPATIBILITY.md for a full table of deviations from stdlib sqlite3.

Requirements

  • Python 3.9+
  • sqlparse (installed automatically via pip)
  • GNU recutils (recsel, recins, recset, recdel) installed separately

Stability and 1.0 release

RecDB is a hobby project without a fixed release schedule. The 1.0 release will be considered when the project has been used successfully in other projects over time. Until then, minor versions may include breaking changes.

Known users / projects

Send a PR to add your project here — this helps track readiness for v1.0.

Project details


Download files

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

Source Distribution

recdb-0.1.1.tar.gz (16.3 kB view details)

Uploaded Source

Built Distribution

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

recdb-0.1.1-py3-none-any.whl (13.5 kB view details)

Uploaded Python 3

File details

Details for the file recdb-0.1.1.tar.gz.

File metadata

  • Download URL: recdb-0.1.1.tar.gz
  • Upload date:
  • Size: 16.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for recdb-0.1.1.tar.gz
Algorithm Hash digest
SHA256 92e57fcc3e3cf3415d553b236f87032aff0ad9cf93385acda83b1a89f1feca5c
MD5 71a7410851ca2f0a84c74f0ea8b94041
BLAKE2b-256 4b677d5b32ff3d9d96319bba54a0e076b84a43b5f9ba45d5fcc514ba18f2df58

See more details on using hashes here.

File details

Details for the file recdb-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: recdb-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 13.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for recdb-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 74c1f6f7045521bf47a7dae35b1e446791ec928f738d8ea024a0000524a4d933
MD5 4ee76c71d6172ccedc62527afe69b299
BLAKE2b-256 fbc2f5678e6167d52bc6fbacdc9cefd899a9cb214ca8f4d8f10b486c4ae552b4

See more details on using hashes here.

Supported by

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