Python client for OxiDB — a fast, embeddable document database
Project description
OxiDB Python Client
Python client for OxiDB document database.
Zero external dependencies — uses only the Python standard library. Communicates with oxidb-server over TCP using the length-prefixed JSON protocol.
Requirements
- Python 3.7+
- A running
oxidb-serverinstance (see main README)
Installation
Copy the single file into your project:
cp oxidb.py your_project/
Quick Start
from oxidb import OxiDbClient
db = OxiDbClient("127.0.0.1", 4444)
db.insert("users", {"name": "Alice", "age": 30})
docs = db.find("users", {"name": "Alice"})
print(docs)
# [{'_id': 1, '_version': 1, 'name': 'Alice', 'age': 30}]
db.close()
Or use as a context manager:
with OxiDbClient("127.0.0.1", 4444) as db:
db.insert("users", {"name": "Bob", "age": 25})
API Reference
Connection
client = OxiDbClient(host="127.0.0.1", port=4444, timeout=5.0)
client.close()
# or as context manager:
with OxiDbClient() as client:
...
CRUD
| Method | Description |
|---|---|
insert(collection, doc) |
Insert a document, returns {"id": ...} |
insert_many(collection, docs) |
Insert multiple documents |
find(collection, query, *, sort, skip, limit) |
Find matching documents |
find_one(collection, query) |
Find first matching document or None |
update(collection, query, update) |
Update all matching documents |
update_one(collection, query, update) |
Update first matching document |
delete(collection, query) |
Delete all matching documents |
delete_one(collection, query) |
Delete first matching document |
count(collection, query) |
Count matching documents |
# Insert
db.insert("users", {"name": "Alice", "age": 30})
db.insert_many("users", [
{"name": "Bob", "age": 25},
{"name": "Charlie", "age": 35},
])
# Find with options
docs = db.find("users", {"age": {"$gte": 18}})
docs = db.find("users", {}, sort={"age": 1}, skip=0, limit=10)
doc = db.find_one("users", {"name": "Alice"})
# Update
db.update("users", {"name": "Alice"}, {"$set": {"age": 31}})
# Delete
db.delete("users", {"name": "Charlie"})
# Count
n = db.count("users")
Collections & Indexes
db.create_collection("orders")
cols = db.list_collections()
db.drop_collection("orders")
db.create_index("users", "name")
db.create_unique_index("users", "email")
db.create_composite_index("users", ["name", "age"])
db.create_text_index("articles", ["title", "body"])
indexes = db.list_indexes("users")
db.drop_index("users", "name")
Document Full-Text Search
# Create a text index on fields you want to search
db.create_text_index("articles", ["title", "body"])
# Search returns matching documents with _score field, sorted by relevance
results = db.text_search("articles", "rust programming", limit=10)
for doc in results:
print(f"{doc['title']} (score: {doc['_score']})")
Aggregation
results = db.aggregate("orders", [
{"$match": {"status": "completed"}},
{"$group": {"_id": "$category", "total": {"$sum": "$amount"}}},
{"$sort": {"total": -1}},
{"$limit": 10},
])
Supported stages: $match, $group, $sort, $skip, $limit, $project, $count, $unwind, $addFields, $lookup
Accumulators: $sum, $avg, $min, $max, $count, $first, $last, $push
Transactions
# Auto-commit on success, auto-rollback on exception
with db.transaction():
db.insert("ledger", {"action": "debit", "amount": 100})
db.insert("ledger", {"action": "credit", "amount": 100})
# Manual control
db.begin_tx()
db.insert("ledger", {"action": "refund", "amount": 50})
db.commit_tx() # or db.rollback_tx()
Blob Storage
# Buckets
db.create_bucket("files")
db.list_buckets()
db.delete_bucket("files")
# Objects
db.put_object("files", "hello.txt", b"Hello!",
content_type="text/plain", metadata={"author": "py"})
data, meta = db.get_object("files", "hello.txt")
head = db.head_object("files", "hello.txt")
objs = db.list_objects("files", prefix="hello", limit=10)
db.delete_object("files", "hello.txt")
Full-Text Search
results = db.search("hello world", bucket="files", limit=10)
# Returns: [{"bucket": "files", "key": "doc.txt", "score": 2.45}, ...]
Compaction
stats = db.compact("users")
# Returns: {"old_size": 4096, "new_size": 2048, "docs_kept": 10}
Error Handling
from oxidb import OxiDbError, TransactionConflictError
try:
db.insert("users", {"email": "duplicate@test.com"})
except TransactionConflictError as e:
print(f"OCC conflict: {e}")
except OxiDbError as e:
print(f"Database error: {e}")
License
See LICENSE for details.
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 oxidb-0.18.0.tar.gz.
File metadata
- Download URL: oxidb-0.18.0.tar.gz
- Upload date:
- Size: 7.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
11b9c2e4c447b208828fc11bb2cecc228f6407dddcd41bf2e374ca5c5b9b63dd
|
|
| MD5 |
cab46142b4eeb3d2a96f40082fa26b04
|
|
| BLAKE2b-256 |
0a8c73c8ce695c8dadbe1ba5f47543025683efa6bfe8fb6b10d5c9a678ebc0e9
|
File details
Details for the file oxidb-0.18.0-py3-none-any.whl.
File metadata
- Download URL: oxidb-0.18.0-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.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
614806978889ebb4fc4de7962852d2b6e053f54eb1a8907b02157aa4ec8ef3fc
|
|
| MD5 |
52b263f9d8bf1dbfb602b714915f1d5c
|
|
| BLAKE2b-256 |
9865d5773f26a5f6f868ac002e298868a7d508df7e12acc3cf7d6f541d2fe388
|