bazoola


Namebazoola JSON
Version 0.0.5 PyPI version JSON
download
home_pagehttps://github.com/ddoroshev/bazoola
SummaryA lightweight, file-based database implementation in Python
upload_time2025-07-30 04:06:24
maintainerNone
docs_urlNone
authorDima Doroshev
requires_python<4.0,>=3.10
licenseMIT
keywords database file-based educational lightweight
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Bazoola

[![CI](https://github.com/ddoroshev/bazoola/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/ddoroshev/bazoola/actions/workflows/ci.yml)
[![Python Version](https://img.shields.io/badge/python-3.10%2B-blue)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/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

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

### Development setup

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

# Install dependencies using Poetry
poetry install
```

## Quick Start

```python
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.

```bash
# 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/](demo/) for more details.

## API Reference

### Database Operations

```python
# 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")

# Find by field value
rows = db.find_by("table_name", "field_name", value)

# 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

```python
from bazoola import GT, LT

# Find with conditions
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:

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

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

## Testing

```bash
# 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.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/ddoroshev/bazoola",
    "name": "bazoola",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.10",
    "maintainer_email": null,
    "keywords": "database, file-based, educational, lightweight",
    "author": "Dima Doroshev",
    "author_email": "github@doroshev.com",
    "download_url": "https://files.pythonhosted.org/packages/da/41/13214d0926c9451276196fe1aa0d0e6683b0ed965a7dcb612d32dc5909fa/bazoola-0.0.5.tar.gz",
    "platform": null,
    "description": "# Bazoola\n\n[![CI](https://github.com/ddoroshev/bazoola/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/ddoroshev/bazoola/actions/workflows/ci.yml)\n[![Python Version](https://img.shields.io/badge/python-3.10%2B-blue)](https://www.python.org/downloads/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nA lightweight, file-based database implementation in Python designed for educational purposes and simple applications.\n\n## Overview\n\nBazoola 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.\n\n## Features\n\n- **File-based storage**: Data is stored in human-readable text files with fixed-width fields\n- **Schema definition**: Define table schemas with typed fields\n- **Primary keys**: Automatic ID generation (manual ID assignment validates uniqueness but doesn't support custom sequences)\n- **Foreign keys**: Support for relationships between tables\n- **Indexing**: ID-based indexing for fast lookups\n- **Joins**: Support for joining related tables\n- **Querying**: Find records by field values, substrings, or custom conditions\n- **Free space management**: Reuses deleted record space\n\n## Installation\n\n### Install as a package\n\n```bash\n# Install directly from GitHub\npip install git+https://github.com/ddoroshev/bazoola.git\n```\n\n### Development setup\n\n```bash\n# Clone the repository\ngit clone https://github.com/ddoroshev/bazoola.git\ncd bazoola\n\n# Install dependencies using Poetry\npoetry install\n```\n\n## Quick Start\n\n```python\nfrom bazoola import DB, Table, Schema, Field, PK, FK, CHAR, INT, Join\n\n# Define table schemas\nclass TableAuthors(Table):\n    name = \"authors\"\n    schema = Schema([\n        Field(\"id\", PK()),\n        Field(\"name\", CHAR(20)),\n    ])\n\nclass TableBooks(Table):\n    name = \"books\"\n    schema = Schema([\n        Field(\"id\", PK()),\n        Field(\"title\", CHAR(20)),\n        Field(\"author_id\", FK(\"authors\")),\n        Field(\"year\", INT(null=True)),\n    ])\n\n# Create database instance\ndb = DB([TableAuthors, TableBooks])\n\n# Insert data\nauthor = db.insert(\"authors\", {\"name\": \"John Doe\"})\nbook = db.insert(\"books\", {\n    \"title\": \"My Book\",\n    \"author_id\": author[\"id\"],\n    \"year\": 2024\n})\n\n# Query with joins\nbook_with_author = db.find_by_id(\n    \"books\",\n    book[\"id\"],\n    joins=[Join(\"author_id\", \"author\", \"authors\")]\n)\nprint(book_with_author)\n# Output: {'id': 1, 'title': 'My Book', 'author_id': 1, 'year': 2024, 'author': {'id': 1, 'name': 'John Doe'}}\n\n# Close the database\ndb.close()\n```\n\n## Field Types\n\n- **PK()**: Primary key field (auto-incrementing integer)\n- **INT(null=False)**: Integer field\n- **CHAR(size, null=False)**: Fixed-size character field\n- **FK(table_name, null=False)**: Foreign key field\n\n## Demo Application\n\nA full-featured task management web application is included to demonstrate Bazoola's capabilities in a real-world scenario.\n\n```bash\n# Run the demo\npoetry install\npoetry run python demo/app.py\n```\n\nVisit http://localhost:5000 to explore the demo. It showcases:\n- Complex schema with 4 interconnected tables (users, projects, tasks, comments)\n- Foreign key relationships and joins\n- CRUD operations with web forms\n- Case-insensitive search across multiple tables\n- Working within Bazoola's constraints (fixed-width fields, no transactions)\n\nSee [demo/](demo/) for more details.\n\n## API Reference\n\n### Database Operations\n\n```python\n# Insert a record\nrow = db.insert(\"table_name\", {\"field\": \"value\"})\n\n# Find by ID\nrow = db.find_by_id(\"table_name\", id)\n\n# Find all records\nrows = db.find_all(\"table_name\")\n\n# Find by field value\nrows = db.find_by(\"table_name\", \"field_name\", value)\n\n# Update a record\nrow = db.update_by_id(\"table_name\", id, {\"field\": \"new_value\"})\n\n# Delete a record\ndb.delete_by_id(\"table_name\", id)\n\n# Truncate table\ndb.truncate(\"table_name\", cascade=False)\n```\n\n### Advanced Queries\n\n```python\nfrom bazoola import GT, LT\n\n# Find with conditions\nrows = db.find_by_cond(\"books\", GT(year=2020))\nrows = db.find_by_cond(\"books\", LT(year=2000))\nrows = db.find_by_cond(\"table_name\", SUBSTR(field_name=\"substr\"))\nrows = db.find_by_cond(\"table_name\", ISUBSTR(field_name=\"SuBsTr\"))\n\n# Query with joins\nrows = db.find_all(\"books\", joins=[\n    Join(\"author_id\", \"author\", \"authors\")\n])\n\n# Inverse joins (one-to-many)\nfrom bazoola import InverseJoin\nauthor = db.find_by_id(\"authors\", 1, joins=[\n    InverseJoin(\"author_id\", \"books\", \"books\")\n])\n```\n\n## File Structure\n\nBazoola creates the following files for each table:\n- `{table_name}.dat` - Main data file\n- `{table_name}__seqnum.dat` - Sequence number for auto-increment\n- `{table_name}__id.idx.dat` - Primary key index\n- `{table_name}__free.dat` - Free rownum stack for space reuse\n\n## Configuration\n\nBy default, database files are stored in a `data` directory. You can specify a different directory when creating the database:\n\n```python\n# Use default 'data' directory\ndb = DB([TableAuthors, TableBooks])\n\n# Use custom directory\ndb = DB([TableAuthors, TableBooks], base_dir=\"/path/to/data/directory\")\n```\n\n## Testing\n\n```bash\n# Run tests\npoetry run pytest\n\n# Run tests with coverage\npoetry run pytest --cov\n\n# Type checking\npoetry run mypy .\n\n# Linting\npoetry run ruff check .\n```\n\n## Limitations\n\n- No multi-threading support\n- No transactions or rollback support\n- Limited query optimization\n- Fixed-size fields only\n- No SQL interface (by design)\n\n## License\n\nThis project is licensed under the MIT License - see the LICENSE file for details.\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A lightweight, file-based database implementation in Python",
    "version": "0.0.5",
    "project_urls": {
        "Documentation": "https://github.com/ddoroshev/bazoola#readme",
        "Homepage": "https://github.com/ddoroshev/bazoola",
        "Repository": "https://github.com/ddoroshev/bazoola"
    },
    "split_keywords": [
        "database",
        " file-based",
        " educational",
        " lightweight"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "9cabb25fe9d5cfedc59fdef3391042b28b23db2d80e7c1eaab82169fb729cf0b",
                "md5": "5fef19cd11e8cd130d62366ef50bbeea",
                "sha256": "e322979dfb73781388e5ac04d57983ab5f812cec7d3aad9bb862fd88d2d10d3d"
            },
            "downloads": -1,
            "filename": "bazoola-0.0.5-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "5fef19cd11e8cd130d62366ef50bbeea",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.10",
            "size": 9327,
            "upload_time": "2025-07-30T04:06:23",
            "upload_time_iso_8601": "2025-07-30T04:06:23.045002Z",
            "url": "https://files.pythonhosted.org/packages/9c/ab/b25fe9d5cfedc59fdef3391042b28b23db2d80e7c1eaab82169fb729cf0b/bazoola-0.0.5-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "da4113214d0926c9451276196fe1aa0d0e6683b0ed965a7dcb612d32dc5909fa",
                "md5": "22af6ae2a15f92319654969adc4cb997",
                "sha256": "c3b8f005187073e61151c14cace852d3f26da20ff2d01318320a28fefbdf220a"
            },
            "downloads": -1,
            "filename": "bazoola-0.0.5.tar.gz",
            "has_sig": false,
            "md5_digest": "22af6ae2a15f92319654969adc4cb997",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.10",
            "size": 11044,
            "upload_time": "2025-07-30T04:06:24",
            "upload_time_iso_8601": "2025-07-30T04:06:24.522435Z",
            "url": "https://files.pythonhosted.org/packages/da/41/13214d0926c9451276196fe1aa0d0e6683b0ed965a7dcb612d32dc5909fa/bazoola-0.0.5.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-30 04:06:24",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ddoroshev",
    "github_project": "bazoola",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "bazoola"
}
        
Elapsed time: 0.62768s