Skip to main content

A simple ELDB engine for Python

Project description

ELDB — EXTREMELY Lightweight DB Engine

Simple file-backed fixed-width record database for small projects and experimentation.

ELDB is a minimal, easy-to-use embedded database implemented in Python. It stores tables as binary files with a small text header and fixed-width records. This project is intended for learning, prototyping, and small single-user applications — not for production use.

Features

  • Tiny footprint: each table is a single .eldb file under a database folder
  • Fixed-size fields: supports int and fixed-length str columns
  • Simple API: create/load tables, insert/select/update/delete rows, add/delete columns
  • Primary key index: builds an in-memory index for a declared primary key on load

Installation

No external dependencies — just Python 3.6+.

Clone or copy the repository files to your project folder. The engine writes table files to a folder (default mydb).

Basic Usage

Example session using the ELDB class from ELDB_engine.py:

from MicroDB import ELDB

# Create engine (defaults to folder 'mydb')
db = ELDB(db_folder='ELDB_Data')

# Define table schema: column -> {type, size, nullable}
columns = {
    'id': {'type': 'int', 'size': 4, 'nullable': False},
    'name': {'type': 'str', 'size': 50, 'nullable': False},
    'age': {'type': 'int', 'size': 4, 'nullable': True}
}

# Create table with a primary key
db.create_table('users', columns, primary_key='id', if_not_exists=True)

# Insert a row (note: columns with no value must be nullable or provide default)
db.insert('users', {'id': 1, 'name': 'Alice', 'age': 30})
db.insert('users', {'id': 2, 'name': 'Bob'})

# Select rows (where uses dict: column -> (operator, value))
rows = db.select('users', where={'age': ('>=', 18)}, order_by=('age', False), limit=10)
print(rows)

# Update rows
db.update('users', updates={'age': 31}, where={'id': ('=', 1)})

# Delete rows
db.delete('users', where={'id': ('=', 2)})

# Add a new column
db.add_column('users', 'email', column_type='str', size=100, nullable=True, default='')

# Delete table
# db.delete_table('users')

API Reference

  • ELDB(db_folder='mydb')

    • Create engine instance. db_folder is the folder where .eldb files live.
  • create_table(name, columns, primary_key=None, if_not_exists=False)

    • columns is a dict mapping column name to options: {'type': 'int'|'str', 'size': <int>, 'nullable': True|False}.
    • primary_key (optional) column name to build an in-memory index on load.
  • load_table(table_name)

    • Loads an existing .eldb table and builds the primary key index if present.
  • insert(table_name, row)

    • row is a dict of column -> value. Type checks are performed.
  • select(table_name=None, where=None, order_by=None, limit=None, columns=None)

    • table_name: choose specific table or None to select across all tables.
    • where: dict of column -> (operator, value), operators: =, !=, >, <, >=, <=.
    • order_by: tuple (column, reverse) where reverse is True for descending.
    • limit: maximum number of rows to return.
    • columns: list of column names to return.
  • update(table_name, updates, where=None)

    • updates is a dict of column -> new value.
  • delete(table_name, where=None)

    • Remove rows matching where — omit where to remove all rows.
  • add_column(table_name, column_name, column_type='str', size=50, nullable=True, default=None)

    • Adds a column to the schema and writes the default value to existing rows.
  • delete_column(table_name, column_name)

    • Removes a column from the schema and from existing rows.
  • clear_table(table_name)

    • Remove all rows from a table (keeps file and schema).
  • delete_table(table_name) and drop_all_tables()

    • Remove files from disk.

Table File Format

Each table is stored as a .eldb file under the database folder. The file begins with a single text header line (a Python dictionary representation) that contains the columns schema, primary_key, and row_count. Following the header, records are stored as fixed-size binary blobs. String columns are fixed-length and padded with NUL bytes; integers are 4-byte little-endian signed integers using Python's struct format i.

Note: The header is written using str() and read with eval() in the current implementation. This is simple but unsafe for untrusted inputs; do not open files from unknown sources.

Limitations & Notes

  • Binary fixed-width format: you must choose adequate size for str columns.
  • No concurrency control: this engine is not safe for concurrent writers.

Suggested Improvements

  • Add transaction/locking and append-mode writes for better concurrency.
  • Support variable-length fields or a simple heap for strings to save space.
  • Add basic tests and a small CLI for table inspection.

Development

To experiment interactively, run python in the project folder and import the ELDB class.

Contributing

Feel free to open issues or create pull requests with improvements, tests, or bug fixes.

License

This project is provided as-is for learning and prototyping. No explicit license file is included.

ELDB Database - Changelog

All notable changes to the ELDB database system will be documented in this file.

[v2.0.0] - 2024-01-15

Major Release: Foreign Key Support & Modernization

New Features

  • Foreign Key System - Simulated foreign key constraints with RESTRICT/CASCADE delete actions
  • Relation Management - Establish table relationships via add_foreign_key() method
  • Cascade Operations - Automatic deletion of dependent records in CASCADE mode
  • Constraint Validation - Real-time foreign key validation during insert/update operations
  • Safe Header Parsing - Replaced insecure eval() with ast.literal_eval()

🔧 API Changes

# NEW: Add foreign key constraint
db.add_foreign_key('orders', 'user_id', 'users', 'id', on_delete='CASCADE')

# NEW: Get foreign key information
db.get_foreign_keys('orders')

# NEW: Cascade table deletion
db.delete_table('users', cascade=True)

# ENHANCED: Delete with cascade support
db.delete('users', where={'id': ('=', 1)})  # Cascades to related orders

Performance Improvements

Optimized Row Reading - Streamlined binary parsing with minimal memory usage

Efficient Index Rebuilding - Faster primary key index reconstruction

Memory-Efficient Operations - Reduced data copying during bulk operations

Compact Database Command - New compact() method to rebuild and optimize tables

🛡️ Security Enhancements

Eliminated eval() - Replaced with secure ast.literal_eval() for header parsing

Input Validation - Comprehensive type and constraint checking

Safe String Handling - Proper UTF-8 encoding with error resilience

Constraint Enforcement - Foreign key validation prevents orphaned records

🐛 Bug Fixes

Fixed - Binary string encoding issues with null bytes

Fixed - WHERE clause evaluation with None values

Fixed - Index corruption when updating tables

Fixed - Memory leak in large table operations

Fixed - Concurrent file access issues

📊 Schema Management

Enhanced Column Operations - Better validation for add_column() and delete_column()

Primary Key Enforcement - Stricter uniqueness checking

Nullable Field Support - Proper handling of optional columns

Type Safety - Runtime type checking for all data operations

🚨 Breaking Changes

eval() Removal - Database files from v1.x must be migrated or recreated

Error Messages - Changed format for better debugging

File Structure - Minor binary format optimization (backward compatible for reads)

Method Signatures - delete_table() now accepts cascade parameter

📈 Quality of Life

Better Logging - Informative console output for all operations

Clear Error Messages - Descriptive error messages with actionable feedback

Example Usage - Comprehensive example in main module

Type Hints - Added Python type hints for better IDE support

📋 Deprecated

Direct file manipulation (use ELDB API instead)

Manual header editing (unsupported)

Legacy eval()-based file format

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

eldb-1.0.0.tar.gz (9.3 kB view details)

Uploaded Source

Built Distribution

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

eldb-1.0.0-py3-none-any.whl (9.1 kB view details)

Uploaded Python 3

File details

Details for the file eldb-1.0.0.tar.gz.

File metadata

  • Download URL: eldb-1.0.0.tar.gz
  • Upload date:
  • Size: 9.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for eldb-1.0.0.tar.gz
Algorithm Hash digest
SHA256 f11d66b125f22cc3aeabfff38ee44d7ee16f4bec404f48ba1f1bac8b8e46fdc9
MD5 9e6889a0243666367d0632c29f9dcd64
BLAKE2b-256 0e8217e042933de2ddefb4bddd20147a5ec78635447afbfdbc7817f158bf15b4

See more details on using hashes here.

File details

Details for the file eldb-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: eldb-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 9.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for eldb-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5d06200440397c72653df5bda509318c46fa42e48955511bb0670e9e195ec2af
MD5 b03dce55e66118455a5268e9da6e3e0d
BLAKE2b-256 91dae049f6169cad5837915e65963fe1048248387d5f50f5cce35e773ed4c72f

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