# CafeDB
A lightweight, human-readable JSON database for Python with zero dependencies and powerful querying capabilities.
[](https://www.python.org/downloads/)
[](https://opensource.org/licenses/MIT)
[](https://github.com/yourusername/cafedb)
## Features
- **Zero Configuration** - Just point to a JSON/CDB file and start working
- **Human-Readable** - All data stored in plain JSON format
- **Advanced Querying** - Rich operator support including wildcards, regex, ranges, and logical operators ($or support)
- **Thread-Safe** - Built-in locking for concurrent operations
- **Atomic Writes** - Crash-safe operations with temporary files
- **Automatic Backups** - Optional backup creation on each write
- **Transaction Support** - Rollback capability for batch operations
- **Detailed Statistics** - Get insights about your data with extended field statistics
- **No Dependencies** - Pure Python with standard library only
## Installation
### Option 1: pip install
```bash
pip install cafedb
```
### Option 2: Copy the module
Simply copy `cafedb.py` to your project directory:
```python
from cafedb import CafeDB
```
### Option 3: Install from source
```bash
git clone https://github.com/Crystallinecore/cafedb.git
cd cafedb
pip install -e .
```
## Quick Start
```python
from cafedb import CafeDB
# Initialize database
db = CafeDB("mydata.cdb", verbose=True)
# Create a table
db.create_table("users")
# Insert data
db.insert("users", {
"name": "Alice Johnson",
"age": 28,
"email": "alice@example.com",
"city": "Paris"
})
# Batch insert
db.insert_many("users", [
{"name": "Bob Smith", "age": 34, "email": "bob@example.com"},
{"name": "Carol White", "age": 22, "email": "carol@example.com"}
])
# Query data with advanced operators
results = db.select("users", {"age": {"$gte": 25}})
# Sorting and pagination
top_users = db.select("users", order_by="age", reverse=True, limit=5)
# Update data
db.update("users",
{"name": "Alice Johnson"},
{"city": "London"}
)
# Delete data
db.delete("users", {"age": {"$lt": 25}})
```
## Query Operators
CafeDB supports powerful query operators for filtering data:
### Comparison Operators
```python
# Equal
db.select("users", {"age": 28})
db.select("users", {"age": {"$eq": 28}})
# Not equal
db.select("users", {"age": {"$ne": 28}})
# Greater than / Less than
db.select("users", {"age": {"$gt": 25}})
db.select("users", {"age": {"$gte": 25}})
db.select("users", {"age": {"$lt": 30}})
db.select("users", {"age": {"$lte": 30}})
# Between (inclusive range)
db.select("users", {"age": {"$between": [25, 35]}})
```
### Membership Operators
```python
# In list
db.select("users", {"city": {"$in": ["Paris", "London", "Berlin"]}})
# Not in list
db.select("users", {"city": {"$nin": ["Paris", "London"]}})
```
### String Operators
```python
# Wildcard matching (* for any chars, ? for single char)
db.select("users", {"name": "A*"}) # Names starting with A
db.select("users", {"email": "*@gmail.com"}) # Gmail users
# Contains substring (case-insensitive)
db.select("users", {"bio": {"$contains": "python"}})
# Starts with / Ends with
db.select("users", {"name": {"$startswith": "Ali"}})
db.select("users", {"email": {"$endswith": ".com"}})
# Regex pattern matching
db.select("users", {"email": {"$regex": r"^[a-z]+@gmail\.com$"}})
# Like (wildcard shorthand)
db.select("users", {"name": {"$like": "J*son"}})
# Exists check
db.select("users", {"phone": {"$exists": True}})
```
### Logical Operators
```python
# Multiple conditions (AND by default)
db.select("users", {
"age": {"$gte": 25},
"city": "Paris",
"email": "*@gmail.com"
})
# OR operator
db.select("users", {
"$or": [
{"city": "Paris"},
{"city": "London"}
]
})
# Combining AND and OR
db.select("users", {
"age": {"$gte": 25}, # AND condition
"$or": [ # OR conditions
{"city": "Paris"},
{"score": {"$gte": 85}}
]
})
```
## Advanced Features
### Sorting and Pagination
```python
# Sort by field
results = db.select("users", order_by="age")
# Sort descending
results = db.select("users", order_by="score", reverse=True)
# Pagination
results = db.select("users", limit=10, offset=20)
# Combine all
results = db.select(
"users",
{"age": {"$gte": 25}},
order_by="score",
reverse=True,
limit=5,
offset=0
)
```
### Field Projection
```python
# Select specific fields only
results = db.select("users", fields=["name", "email"])
# Returns: [{"name": "Alice", "email": "alice@example.com"}, ...]
```
### Custom Filter Functions
```python
# Use a custom function for complex filtering
results = db.select("users", lambda row: row["age"] > 25 and "@gmail.com" in row["email"])
# Custom update function
db.update(
"users",
{"age": {"$gte": 30}},
lambda row: {**row, "category": "senior", "discount": row["age"] * 0.01}
)
```
### Transactions
```python
# Rollback all changes if any operation fails
try:
with db.transaction():
db.insert("users", user1)
db.update("users", {"name": "Alice"}, {"status": "active"})
db.delete("users", {"status": "inactive"})
# All changes committed together
except Exception as e:
# All changes rolled back automatically
print(f"Transaction failed: {e}")
```
### Batch Operations
```python
# Batch insert (more efficient)
users = [
{"name": "User1", "age": 25},
{"name": "User2", "age": 30},
{"name": "User3", "age": 35}
]
count = db.insert_many("users", users)
print(f"Inserted {count} rows")
# Update multiple rows
count = db.update(
"users",
{"age": {"$gte": 30}},
{"category": "senior"}
)
print(f"Updated {count} rows")
# Delete multiple rows
count = db.delete("users", {"age": {"$lt": 18}})
print(f"Deleted {count} rows")
```
## Utility Methods
### Table Management
```python
# List all tables
tables = db.list_tables()
# Check if table exists
if db.exists_table("users"):
print("Users table exists")
# Clear all data from table (keep structure)
count = db.clear_table("users")
print(f"Cleared {count} rows")
# Drop table completely
db.drop_table("users")
```
### Statistics and Information
```python
# Count rows
total = db.count("users")
filtered = db.count("users", {"age": {"$gte": 25}})
# Detailed table statistics
stats = db.stats("users")
print(f"Total rows: {stats['total_rows']}")
print(f"Size: {stats['size_kb']} KB")
print(f"Fields: {stats['fields']}")
# Field statistics include:
# - present_count: Number of rows with this field
# - present_percentage: Percentage of rows with this field
# - unique_count: Number of unique values
# - null_count: Number of null values
# - data_types: List of data types found
# - min/max/avg: For numeric fields
# Database information
info = db.info()
print(f"Path: {info['path']}")
print(f"Tables: {info['table_count']}")
print(f"Total rows: {info['total_rows']}")
print(f"Created: {info['created']}")
print(f"Last modified: {info['last_modified']}")
```
## Configuration Options
```python
# Verbose mode (prints operations)
db = CafeDB("data.json", verbose=True)
# Disable automatic backups
db = CafeDB("data.json", backup=False)
# Combine options
db = CafeDB("data.json", verbose=True, backup=True)
```
## Error Handling
CafeDB uses custom exceptions for better error handling:
```python
from cafedb import (
CafeDB,
CafeDBError,
TableNotFoundError,
TableExistsError,
QueryError
)
try:
db.create_table("users")
except TableExistsError:
print("Table already exists")
try:
db.select("nonexistent")
except TableNotFoundError as e:
print(f"Error: {e}")
try:
db.select("users", {"age": {"$invalid": 25}})
except QueryError as e:
print(f"Invalid query: {e}")
```
## Data Structure
CafeDB stores data in a simple JSON format:
```json
{
"_meta": {
"tables": ["users", "products"],
"created": "2025-01-15T10:30:00",
"last_modified": "2025-01-15T11:45:00",
"version": "1.0.0"
},
"users": [
{
"name": "Alice Johnson",
"age": 28,
"email": "alice@example.com",
"_inserted_at": "2025-01-15T10:35:00",
"_updated_at": "2025-01-15T11:00:00"
}
]
}
```
## Best Practices
1. **Use batch operations** - `insert_many()` is more efficient than multiple `insert()` calls
2. **Enable backups for production** - Keep `backup=True` for important data
3. **Use transactions for related changes** - Group operations that should succeed or fail together
4. **Use field projection** - Only select the fields you need with the `fields` parameter
5. **Handle exceptions** - Always catch `TableNotFoundError`, `QueryError`, etc.
6. **Keep tables under 10,000 rows** - For optimal performance
## Limitations
- Not suitable for very large datasets (>100MB)
- No SQL-like JOIN operations (use application-level logic)
- No built-in indexing (all queries are full table scans)
- Single-file storage (one JSON file per database)
- Queries work on top-level fields only (no nested field queries)
## Use Cases
Perfect for:
- Small to medium-sized datasets
- Configuration storage
- Rapid prototyping
- Testing and development
- Embedded applications
- Data that needs to be human-readable
- Applications where simplicity is more important than performance
## API Reference
### Core Methods
- `create_table(table_name: str)` - Create a new table
- `drop_table(table_name: str)` - Delete a table
- `insert(table_name: str, row: dict)` - Insert a single row
- `insert_many(table_name: str, rows: List[dict])` - Batch insert rows
- `select(table_name: str, filters=None, fields=None, limit=None, offset=0, order_by=None, reverse=False)` - Query rows
- `update(table_name: str, filters, updater)` - Update matching rows
- `delete(table_name: str, filters)` - Delete matching rows
- `count(table_name: str, filters=None)` - Count matching rows
- `list_tables()` - List all tables
- `exists_table(table_name: str)` - Check if table exists
- `stats(table_name: str)` - Get table statistics
- `clear_table(table_name: str)` - Remove all rows from table
- `info()` - Get database information
### Context Managers
- `transaction()` - Execute operations with rollback support
## Complete Example
```python
from cafedb import CafeDB
# Initialize
db = CafeDB("app.json", verbose=True)
# Setup
if not db.exists_table("users"):
db.create_table("users")
# Add users
db.insert_many("users", [
{"username": "alice", "email": "alice@example.com", "age": 28, "role": "admin"},
{"username": "bob", "email": "bob@example.com", "age": 34, "role": "user"},
{"username": "carol", "email": "carol@example.com", "age": 22, "role": "user"}
])
# Find admin users
admins = db.select("users", {"role": "admin"})
# Find users by age range and role with OR logic
results = db.select("users", {
"age": {"$between": [25, 35]},
"$or": [
{"role": "admin"},
{"role": "moderator"}
]
})
# Update user email
db.update(
"users",
{"username": "alice"},
{"email": "alice.new@example.com"}
)
# Promote users over 30
db.update(
"users",
{"age": {"$gte": 30}},
{"role": "senior"}
)
# Get statistics with extended field info
stats = db.stats("users")
print(f"Total users: {stats['total_rows']}")
print(f"Database size: {stats['size_kb']} KB")
for field, info in stats['fields'].items():
print(f"{field}: {info['unique_count']} unique, {info['present_percentage']}% present")
# Use transactions
try:
with db.transaction():
db.insert("users", {"username": "dave", "age": 40})
db.update("users", {"role": "user"}, {"verified": True})
except Exception as e:
print(f"Transaction failed: {e}")
```
## Contributing
Contributions are welcome! Feel free to:
- Report bugs
- Suggest features
- Submit pull requests
- Improve documentation
## License
MIT License - Free to use and modify for any purpose.
## FAQ
**Q: Can CafeDB handle millions of records?**
A: CafeDB is optimized for small to medium datasets (< 100K records). For larger datasets, consider a traditional database.
**Q: Is CafeDB thread-safe?**
A: Yes, CafeDB uses `threading.RLock()` for thread-safe operations.
**Q: Can I use CafeDB in production?**
A: CafeDB is great for prototypes, small applications, and internal tools. For mission-critical production systems with high load, use PostgreSQL, MongoDB, etc.
**Q: How do I backup my database?**
A: CafeDB creates automatic backups (if enabled). You can also manually copy the JSON file.
**Q: What about JOIN operations?**
A: CafeDB doesn't support JOINs. Query multiple tables and combine results in your application code.
---
**☕ CafeDB** - Simple, powerful, human-readable database for Python.
Raw data
{
"_id": null,
"home_page": null,
"name": "cafedb",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": "CafeDB Team <sivaprasad.off@gmail.com>",
"keywords": "database, json, nosql, lightweight, human-readable, query, storage, embedded",
"author": null,
"author_email": "CafeDB Team <sivaprasad.off@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/0b/0b/8ca5e8a5ad16c8ed9530a905e353b8637be8651cf6a816c0638a2f70d2ba/cafedb-0.1.0.tar.gz",
"platform": null,
"description": "# CafeDB\n\nA lightweight, human-readable JSON database for Python with zero dependencies and powerful querying capabilities.\n\n[](https://www.python.org/downloads/)\n[](https://opensource.org/licenses/MIT)\n[](https://github.com/yourusername/cafedb)\n\n## Features\n\n- **Zero Configuration** - Just point to a JSON/CDB file and start working\n- **Human-Readable** - All data stored in plain JSON format\n- **Advanced Querying** - Rich operator support including wildcards, regex, ranges, and logical operators ($or support)\n- **Thread-Safe** - Built-in locking for concurrent operations\n- **Atomic Writes** - Crash-safe operations with temporary files\n- **Automatic Backups** - Optional backup creation on each write\n- **Transaction Support** - Rollback capability for batch operations\n- **Detailed Statistics** - Get insights about your data with extended field statistics\n- **No Dependencies** - Pure Python with standard library only\n\n## Installation\n\n### Option 1: pip install\n```bash\npip install cafedb\n```\n\n### Option 2: Copy the module\nSimply copy `cafedb.py` to your project directory:\n```python\nfrom cafedb import CafeDB\n```\n\n### Option 3: Install from source\n```bash\ngit clone https://github.com/Crystallinecore/cafedb.git\ncd cafedb\npip install -e .\n```\n\n## Quick Start\n\n```python\nfrom cafedb import CafeDB\n\n# Initialize database\ndb = CafeDB(\"mydata.cdb\", verbose=True)\n\n# Create a table\ndb.create_table(\"users\")\n\n# Insert data\ndb.insert(\"users\", {\n \"name\": \"Alice Johnson\",\n \"age\": 28,\n \"email\": \"alice@example.com\",\n \"city\": \"Paris\"\n})\n\n# Batch insert\ndb.insert_many(\"users\", [\n {\"name\": \"Bob Smith\", \"age\": 34, \"email\": \"bob@example.com\"},\n {\"name\": \"Carol White\", \"age\": 22, \"email\": \"carol@example.com\"}\n])\n\n# Query data with advanced operators\nresults = db.select(\"users\", {\"age\": {\"$gte\": 25}})\n\n# Sorting and pagination\ntop_users = db.select(\"users\", order_by=\"age\", reverse=True, limit=5)\n\n# Update data\ndb.update(\"users\", \n {\"name\": \"Alice Johnson\"}, \n {\"city\": \"London\"}\n)\n\n# Delete data\ndb.delete(\"users\", {\"age\": {\"$lt\": 25}})\n```\n\n## Query Operators\n\nCafeDB supports powerful query operators for filtering data:\n\n### Comparison Operators\n\n```python\n# Equal\ndb.select(\"users\", {\"age\": 28})\ndb.select(\"users\", {\"age\": {\"$eq\": 28}})\n\n# Not equal\ndb.select(\"users\", {\"age\": {\"$ne\": 28}})\n\n# Greater than / Less than\ndb.select(\"users\", {\"age\": {\"$gt\": 25}})\ndb.select(\"users\", {\"age\": {\"$gte\": 25}})\ndb.select(\"users\", {\"age\": {\"$lt\": 30}})\ndb.select(\"users\", {\"age\": {\"$lte\": 30}})\n\n# Between (inclusive range)\ndb.select(\"users\", {\"age\": {\"$between\": [25, 35]}})\n```\n\n### Membership Operators\n\n```python\n# In list\ndb.select(\"users\", {\"city\": {\"$in\": [\"Paris\", \"London\", \"Berlin\"]}})\n\n# Not in list\ndb.select(\"users\", {\"city\": {\"$nin\": [\"Paris\", \"London\"]}})\n```\n\n### String Operators\n\n```python\n# Wildcard matching (* for any chars, ? for single char)\ndb.select(\"users\", {\"name\": \"A*\"}) # Names starting with A\ndb.select(\"users\", {\"email\": \"*@gmail.com\"}) # Gmail users\n\n# Contains substring (case-insensitive)\ndb.select(\"users\", {\"bio\": {\"$contains\": \"python\"}})\n\n# Starts with / Ends with\ndb.select(\"users\", {\"name\": {\"$startswith\": \"Ali\"}})\ndb.select(\"users\", {\"email\": {\"$endswith\": \".com\"}})\n\n# Regex pattern matching\ndb.select(\"users\", {\"email\": {\"$regex\": r\"^[a-z]+@gmail\\.com$\"}})\n\n# Like (wildcard shorthand)\ndb.select(\"users\", {\"name\": {\"$like\": \"J*son\"}})\n\n# Exists check\ndb.select(\"users\", {\"phone\": {\"$exists\": True}})\n```\n\n### Logical Operators\n\n```python\n# Multiple conditions (AND by default)\ndb.select(\"users\", {\n \"age\": {\"$gte\": 25},\n \"city\": \"Paris\",\n \"email\": \"*@gmail.com\"\n})\n\n# OR operator\ndb.select(\"users\", {\n \"$or\": [\n {\"city\": \"Paris\"},\n {\"city\": \"London\"}\n ]\n})\n\n# Combining AND and OR\ndb.select(\"users\", {\n \"age\": {\"$gte\": 25}, # AND condition\n \"$or\": [ # OR conditions\n {\"city\": \"Paris\"},\n {\"score\": {\"$gte\": 85}}\n ]\n})\n```\n\n## Advanced Features\n\n### Sorting and Pagination\n\n```python\n# Sort by field\nresults = db.select(\"users\", order_by=\"age\")\n\n# Sort descending\nresults = db.select(\"users\", order_by=\"score\", reverse=True)\n\n# Pagination\nresults = db.select(\"users\", limit=10, offset=20)\n\n# Combine all\nresults = db.select(\n \"users\",\n {\"age\": {\"$gte\": 25}},\n order_by=\"score\",\n reverse=True,\n limit=5,\n offset=0\n)\n```\n\n### Field Projection\n\n```python\n# Select specific fields only\nresults = db.select(\"users\", fields=[\"name\", \"email\"])\n# Returns: [{\"name\": \"Alice\", \"email\": \"alice@example.com\"}, ...]\n```\n\n### Custom Filter Functions\n\n```python\n# Use a custom function for complex filtering\nresults = db.select(\"users\", lambda row: row[\"age\"] > 25 and \"@gmail.com\" in row[\"email\"])\n\n# Custom update function\ndb.update(\n \"users\",\n {\"age\": {\"$gte\": 30}},\n lambda row: {**row, \"category\": \"senior\", \"discount\": row[\"age\"] * 0.01}\n)\n```\n\n### Transactions\n\n```python\n# Rollback all changes if any operation fails\ntry:\n with db.transaction():\n db.insert(\"users\", user1)\n db.update(\"users\", {\"name\": \"Alice\"}, {\"status\": \"active\"})\n db.delete(\"users\", {\"status\": \"inactive\"})\n # All changes committed together\nexcept Exception as e:\n # All changes rolled back automatically\n print(f\"Transaction failed: {e}\")\n```\n\n### Batch Operations\n\n```python\n# Batch insert (more efficient)\nusers = [\n {\"name\": \"User1\", \"age\": 25},\n {\"name\": \"User2\", \"age\": 30},\n {\"name\": \"User3\", \"age\": 35}\n]\ncount = db.insert_many(\"users\", users)\nprint(f\"Inserted {count} rows\")\n\n# Update multiple rows\ncount = db.update(\n \"users\",\n {\"age\": {\"$gte\": 30}},\n {\"category\": \"senior\"}\n)\nprint(f\"Updated {count} rows\")\n\n# Delete multiple rows\ncount = db.delete(\"users\", {\"age\": {\"$lt\": 18}})\nprint(f\"Deleted {count} rows\")\n```\n\n## Utility Methods\n\n### Table Management\n\n```python\n# List all tables\ntables = db.list_tables()\n\n# Check if table exists\nif db.exists_table(\"users\"):\n print(\"Users table exists\")\n\n# Clear all data from table (keep structure)\ncount = db.clear_table(\"users\")\nprint(f\"Cleared {count} rows\")\n\n# Drop table completely\ndb.drop_table(\"users\")\n```\n\n### Statistics and Information\n\n```python\n# Count rows\ntotal = db.count(\"users\")\nfiltered = db.count(\"users\", {\"age\": {\"$gte\": 25}})\n\n# Detailed table statistics\nstats = db.stats(\"users\")\nprint(f\"Total rows: {stats['total_rows']}\")\nprint(f\"Size: {stats['size_kb']} KB\")\nprint(f\"Fields: {stats['fields']}\")\n\n# Field statistics include:\n# - present_count: Number of rows with this field\n# - present_percentage: Percentage of rows with this field\n# - unique_count: Number of unique values\n# - null_count: Number of null values\n# - data_types: List of data types found\n# - min/max/avg: For numeric fields\n\n# Database information\ninfo = db.info()\nprint(f\"Path: {info['path']}\")\nprint(f\"Tables: {info['table_count']}\")\nprint(f\"Total rows: {info['total_rows']}\")\nprint(f\"Created: {info['created']}\")\nprint(f\"Last modified: {info['last_modified']}\")\n```\n\n## Configuration Options\n\n```python\n# Verbose mode (prints operations)\ndb = CafeDB(\"data.json\", verbose=True)\n\n# Disable automatic backups\ndb = CafeDB(\"data.json\", backup=False)\n\n# Combine options\ndb = CafeDB(\"data.json\", verbose=True, backup=True)\n```\n\n## Error Handling\n\nCafeDB uses custom exceptions for better error handling:\n\n```python\nfrom cafedb import (\n CafeDB, \n CafeDBError,\n TableNotFoundError, \n TableExistsError, \n QueryError\n)\n\ntry:\n db.create_table(\"users\")\nexcept TableExistsError:\n print(\"Table already exists\")\n\ntry:\n db.select(\"nonexistent\")\nexcept TableNotFoundError as e:\n print(f\"Error: {e}\")\n\ntry:\n db.select(\"users\", {\"age\": {\"$invalid\": 25}})\nexcept QueryError as e:\n print(f\"Invalid query: {e}\")\n```\n\n## Data Structure\n\nCafeDB stores data in a simple JSON format:\n\n```json\n{\n \"_meta\": {\n \"tables\": [\"users\", \"products\"],\n \"created\": \"2025-01-15T10:30:00\",\n \"last_modified\": \"2025-01-15T11:45:00\",\n \"version\": \"1.0.0\"\n },\n \"users\": [\n {\n \"name\": \"Alice Johnson\",\n \"age\": 28,\n \"email\": \"alice@example.com\",\n \"_inserted_at\": \"2025-01-15T10:35:00\",\n \"_updated_at\": \"2025-01-15T11:00:00\"\n }\n ]\n}\n```\n\n## Best Practices\n\n1. **Use batch operations** - `insert_many()` is more efficient than multiple `insert()` calls\n2. **Enable backups for production** - Keep `backup=True` for important data\n3. **Use transactions for related changes** - Group operations that should succeed or fail together\n4. **Use field projection** - Only select the fields you need with the `fields` parameter\n5. **Handle exceptions** - Always catch `TableNotFoundError`, `QueryError`, etc.\n6. **Keep tables under 10,000 rows** - For optimal performance\n\n## Limitations\n\n- Not suitable for very large datasets (>100MB)\n- No SQL-like JOIN operations (use application-level logic)\n- No built-in indexing (all queries are full table scans)\n- Single-file storage (one JSON file per database)\n- Queries work on top-level fields only (no nested field queries)\n\n## Use Cases\n\nPerfect for:\n- Small to medium-sized datasets\n- Configuration storage\n- Rapid prototyping\n- Testing and development\n- Embedded applications\n- Data that needs to be human-readable\n- Applications where simplicity is more important than performance\n\n## API Reference\n\n### Core Methods\n\n- `create_table(table_name: str)` - Create a new table\n- `drop_table(table_name: str)` - Delete a table\n- `insert(table_name: str, row: dict)` - Insert a single row\n- `insert_many(table_name: str, rows: List[dict])` - Batch insert rows\n- `select(table_name: str, filters=None, fields=None, limit=None, offset=0, order_by=None, reverse=False)` - Query rows\n- `update(table_name: str, filters, updater)` - Update matching rows\n- `delete(table_name: str, filters)` - Delete matching rows\n- `count(table_name: str, filters=None)` - Count matching rows\n- `list_tables()` - List all tables\n- `exists_table(table_name: str)` - Check if table exists\n- `stats(table_name: str)` - Get table statistics\n- `clear_table(table_name: str)` - Remove all rows from table\n- `info()` - Get database information\n\n### Context Managers\n\n- `transaction()` - Execute operations with rollback support\n\n## Complete Example\n\n```python\nfrom cafedb import CafeDB\n\n# Initialize\ndb = CafeDB(\"app.json\", verbose=True)\n\n# Setup\nif not db.exists_table(\"users\"):\n db.create_table(\"users\")\n\n# Add users\ndb.insert_many(\"users\", [\n {\"username\": \"alice\", \"email\": \"alice@example.com\", \"age\": 28, \"role\": \"admin\"},\n {\"username\": \"bob\", \"email\": \"bob@example.com\", \"age\": 34, \"role\": \"user\"},\n {\"username\": \"carol\", \"email\": \"carol@example.com\", \"age\": 22, \"role\": \"user\"}\n])\n\n# Find admin users\nadmins = db.select(\"users\", {\"role\": \"admin\"})\n\n# Find users by age range and role with OR logic\nresults = db.select(\"users\", {\n \"age\": {\"$between\": [25, 35]},\n \"$or\": [\n {\"role\": \"admin\"},\n {\"role\": \"moderator\"}\n ]\n})\n\n# Update user email\ndb.update(\n \"users\",\n {\"username\": \"alice\"},\n {\"email\": \"alice.new@example.com\"}\n)\n\n# Promote users over 30\ndb.update(\n \"users\",\n {\"age\": {\"$gte\": 30}},\n {\"role\": \"senior\"}\n)\n\n# Get statistics with extended field info\nstats = db.stats(\"users\")\nprint(f\"Total users: {stats['total_rows']}\")\nprint(f\"Database size: {stats['size_kb']} KB\")\nfor field, info in stats['fields'].items():\n print(f\"{field}: {info['unique_count']} unique, {info['present_percentage']}% present\")\n\n# Use transactions\ntry:\n with db.transaction():\n db.insert(\"users\", {\"username\": \"dave\", \"age\": 40})\n db.update(\"users\", {\"role\": \"user\"}, {\"verified\": True})\nexcept Exception as e:\n print(f\"Transaction failed: {e}\")\n```\n\n## Contributing\n\nContributions are welcome! Feel free to:\n- Report bugs\n- Suggest features\n- Submit pull requests\n- Improve documentation\n\n## License\n\nMIT License - Free to use and modify for any purpose.\n\n## FAQ\n\n**Q: Can CafeDB handle millions of records?** \nA: CafeDB is optimized for small to medium datasets (< 100K records). For larger datasets, consider a traditional database.\n\n**Q: Is CafeDB thread-safe?** \nA: Yes, CafeDB uses `threading.RLock()` for thread-safe operations.\n\n**Q: Can I use CafeDB in production?** \nA: CafeDB is great for prototypes, small applications, and internal tools. For mission-critical production systems with high load, use PostgreSQL, MongoDB, etc.\n\n**Q: How do I backup my database?** \nA: CafeDB creates automatic backups (if enabled). You can also manually copy the JSON file.\n\n**Q: What about JOIN operations?** \nA: CafeDB doesn't support JOINs. Query multiple tables and combine results in your application code.\n\n---\n\n**\u2615 CafeDB** - Simple, powerful, human-readable database for Python.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A lightweight, human-readable JSON database with advanced querying capabilities",
"version": "0.1.0",
"project_urls": {
"Changelog": "https://github.com/CrystallineCore/cafedb/releases",
"Documentation": "https://github.com/CrystallineCore/cafedb#readme",
"Homepage": "https://github.com/CrystallineCore/cafedb",
"Issues": "https://github.com/CrystallineCore/cafedb/issues",
"Repository": "https://github.com/CrystallineCore/cafedb"
},
"split_keywords": [
"database",
" json",
" nosql",
" lightweight",
" human-readable",
" query",
" storage",
" embedded"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "32c74d982016980824d3d98ef2f579375fb13a4969734b1833df887399abf31d",
"md5": "7cee543f6d8004a33657ba3929958c0d",
"sha256": "ca3a69c717afc3d55f3153292fd48f6746cc9d3ad85c463139493355233ae19e"
},
"downloads": -1,
"filename": "cafedb-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "7cee543f6d8004a33657ba3929958c0d",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 15840,
"upload_time": "2025-10-06T05:32:26",
"upload_time_iso_8601": "2025-10-06T05:32:26.752617Z",
"url": "https://files.pythonhosted.org/packages/32/c7/4d982016980824d3d98ef2f579375fb13a4969734b1833df887399abf31d/cafedb-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "0b0b8ca5e8a5ad16c8ed9530a905e353b8637be8651cf6a816c0638a2f70d2ba",
"md5": "71406b68760f026309e61bc7fe720cdd",
"sha256": "c46fc1607ff6cc2771010ef9d91b7ec6831ecbeba424112bec2fcab58016e329"
},
"downloads": -1,
"filename": "cafedb-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "71406b68760f026309e61bc7fe720cdd",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 19157,
"upload_time": "2025-10-06T05:32:28",
"upload_time_iso_8601": "2025-10-06T05:32:28.785807Z",
"url": "https://files.pythonhosted.org/packages/0b/0b/8ca5e8a5ad16c8ed9530a905e353b8637be8651cf6a816c0638a2f70d2ba/cafedb-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-06 05:32:28",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "CrystallineCore",
"github_project": "cafedb",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "cafedb"
}