Skip to main content

A lightweight, file-based database implementation in Python

Project description

Bazoola

CI PyPI version Python Version License: MIT

A lightweight, file-based database implementation in Python designed for educational purposes and simple applications.

Overview

Bazoola is a minimal database system that stores data in text files with fixed-width fields. It supports basic database operations like CRUD (Create, Read, Update, Delete), schema validation, foreign key relationships, and simple querying capabilities.

Features

  • File-based storage: Data is stored in human-readable text files with fixed-width fields
  • Schema definition: Define table schemas with typed fields
  • Primary keys: Automatic ID generation (manual ID assignment validates uniqueness but doesn't support custom sequences)
  • Foreign keys: Support for relationships between tables
  • Indexing: ID-based indexing for fast lookups
  • Joins: Support for joining related tables
  • Querying: Find records by field values, substrings, or custom conditions
  • Free space management: Reuses deleted record space

Installation

Install as a package

# Install directly from GitHub
pip install git+https://github.com/ddoroshev/bazoola.git

Development setup

# Clone the repository
git clone https://github.com/ddoroshev/bazoola.git
cd bazoola

# Install dependencies using Poetry
poetry install

Quick Start

from bazoola import DB, Table, Schema, Field, PK, FK, CHAR, INT, Join

# Define table schemas
class TableAuthors(Table):
    name = "authors"
    schema = Schema([
        Field("id", PK()),
        Field("name", CHAR(20)),
    ])

class TableBooks(Table):
    name = "books"
    schema = Schema([
        Field("id", PK()),
        Field("title", CHAR(20)),
        Field("author_id", FK("authors")),
        Field("year", INT(null=True)),
    ])

# Create database instance
db = DB([TableAuthors, TableBooks])

# Insert data
author = db.insert("authors", {"name": "John Doe"})
book = db.insert("books", {
    "title": "My Book",
    "author_id": author["id"],
    "year": 2024
})

# Query with joins
book_with_author = db.find_by_id(
    "books",
    book["id"],
    joins=[Join("author_id", "author", "authors")]
)
print(book_with_author)
# Output: {'id': 1, 'title': 'My Book', 'author_id': 1, 'year': 2024, 'author': {'id': 1, 'name': 'John Doe'}}

# Close the database
db.close()

Field Types

  • PK(): Primary key field (auto-incrementing integer)
  • INT(null=False): Integer field
  • CHAR(size, null=False): Fixed-size character field
  • FK(table_name, null=False): Foreign key field

Demo Application

A full-featured task management web application is included to demonstrate Bazoola's capabilities in a real-world scenario.

# Run the demo
poetry install
poetry run python demo/app.py

Visit http://localhost:5000 to explore the demo. It showcases:

  • Complex schema with 4 interconnected tables (users, projects, tasks, comments)
  • Foreign key relationships and joins
  • CRUD operations with web forms
  • Case-insensitive search across multiple tables
  • Working within Bazoola's constraints (fixed-width fields, no transactions)

See demo/ for more details.

API Reference

Database Operations

# Insert a record
row = db.insert("table_name", {"field": "value"})

# Find by ID
row = db.find_by_id("table_name", id)

# Find all records
rows = db.find_all("table_name")

# Update a record
row = db.update_by_id("table_name", id, {"field": "new_value"})

# Delete a record
db.delete_by_id("table_name", id)

# Truncate table
db.truncate("table_name", cascade=False)

Advanced Queries

from bazoola import GT, LT

# Find with conditions
rows = db.find_by_cond("books", EQ(year=2020))
rows = db.find_by_cond("books", GT(year=2020))
rows = db.find_by_cond("books", LT(year=2000))
rows = db.find_by_cond("table_name", SUBSTR(field_name="substr"))
rows = db.find_by_cond("table_name", ISUBSTR(field_name="SuBsTr"))

# Query with joins
rows = db.find_all("books", joins=[
    Join("author_id", "author", "authors")
])

# Inverse joins (one-to-many)
from bazoola import InverseJoin
author = db.find_by_id("authors", 1, joins=[
    InverseJoin("author_id", "books", "books")
])

File Structure

Bazoola creates the following files for each table:

  • {table_name}.dat - Main data file
  • {table_name}__seqnum.dat - Sequence number for auto-increment
  • {table_name}__id.idx.dat - Primary key index
  • {table_name}__free.dat - Free rownum stack for space reuse

Configuration

By default, database files are stored in a data directory. You can specify a different directory when creating the database:

# Use default 'data' directory
db = DB([TableAuthors, TableBooks])

# Use custom directory
db = DB([TableAuthors, TableBooks], base_dir="/path/to/data/directory")

Testing

# Run tests
poetry run pytest

# Run tests with coverage
poetry run pytest --cov

# Type checking
poetry run mypy .

# Linting
poetry run ruff check .

Limitations

  • No multi-threading support
  • No transactions or rollback support
  • Limited query optimization
  • Fixed-size fields only
  • No SQL interface (by design)

License

This project is licensed under the MIT License - see the LICENSE file for details.

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

bazoola-0.0.6.tar.gz (11.5 kB view details)

Uploaded Source

Built Distribution

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

bazoola-0.0.6-py3-none-any.whl (11.8 kB view details)

Uploaded Python 3

File details

Details for the file bazoola-0.0.6.tar.gz.

File metadata

  • Download URL: bazoola-0.0.6.tar.gz
  • Upload date:
  • Size: 11.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.4 CPython/3.10.18 Linux/6.11.0-1018-azure

File hashes

Hashes for bazoola-0.0.6.tar.gz
Algorithm Hash digest
SHA256 bcf89300fc8f1d4f3b37879b1fc27b5fbf32ad3ce6047d921aae979ac8e5e496
MD5 85e0858a90ccfb8feee6c5602390c85b
BLAKE2b-256 30d464bd6abe9f9072d2d3f3255d5b1e9309094b0fd4903b697ae6dde95d1741

See more details on using hashes here.

File details

Details for the file bazoola-0.0.6-py3-none-any.whl.

File metadata

  • Download URL: bazoola-0.0.6-py3-none-any.whl
  • Upload date:
  • Size: 11.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.4 CPython/3.10.18 Linux/6.11.0-1018-azure

File hashes

Hashes for bazoola-0.0.6-py3-none-any.whl
Algorithm Hash digest
SHA256 800172f49a72b6b0a796347efd20e5d718c0f31ee4ca6b6c397862a35efe7de3
MD5 693e0d44d475d130b24a56e175f46a7a
BLAKE2b-256 b49ab1a1284a7bb2d1f33a79d31bed38bedd6a4081962105dd4ef6acde743a64

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