Skip to content

Releases: tonbo-io/tonbo

Tonbo release 0.2.0

30 Oct 12:38
a729040
Compare
Choose a tag to compare
img_v3_02g5_7d00dd28-d1fc-47ce-aa62-dfef4be74f2g

Tonbo Now Supports S3 as Remote Storage

With the integration of Fusio, Tonbo now supports storing data on S3, making cloud storage integration easier and reducing costs. Users can store either parts of stale data or the full dataset on S3. We believe object storage is key for the next generation of data systems, and supporting S3 is crucial for Tonbo's goal of providing a unified storage solution for both local and cloud environments, enabling databases like SQLite and PostgreSQL to act as stateless query engines on top of it. Configuration example:

let options = DbOption::from(Path::from_filesystem_path("./db_path/users").unwrap())
    // tonbo only stores 3 and beyond level stale data of lsm tree on S3
    // 1 and 2 level fresh data are on local disk as default
    .level_path(
        3,
        "/remote-storage".into(),
        FsOptions::S3 {
            bucket: "bucket".into(),
            credential: None,
            region: None,
            sign_payload: None,
            checksum: None,
        },
    )
    .unwrap();
let db = DB::new(options, TokioExecutor::default()).await.unwrap();

Python Binding Now Supported

Starting from version 0.2.0, Tonbo can be used in Python with minimal setup. Given Python's wide adoption in scientific computing, AI, and data analysis, this support helps developers easily build data-intensive applications for local/edge-first environments.

The Python binding offers an ORM-like experience, simplifying data modeling and reducing boilerplate code, allowing developers to focus on building features. Quick preview:

from tonbo import DbOption, Column, DataType, Record, TonboDB, Bound
import asyncio
tempfile

@Record
class User:
    id = Column(DataType.Int64, name="id", primary_key=True)
    age = Column(DataType.Int16, name="age", nullable=True)
    name = Column(DataType.String, name="name", nullable=False)
    email = Column(DataType.String, name="email", nullable=True)
    data = Column(DataType.Bytes, name="data", nullable=True)


async def main():
    temp_dir = tempfile.TemporaryDirectory()

    db = TonboDB(DbOption(temp_dir.name), User())
    await db.insert(User(id=18, age=175, name="Alice"))

    record = await db.get(18)
    assert record == {
        "id": 18,
        "age": 175,
        "name": "Alice",
        "email": None,
        "data": None,
    }

    txn = await db.transaction()

    txn.insert(
        User(
            id=19,
            age=195,
            name="Bob",
            data=b"Hello Tonbo!",
            email="[email protected]",
        )
    )

    await txn.commit()
    txn = await db.transaction()
    scan = await txn.scan(
        Bound.Excluded(18),
        None,
        limit=100,
        projection=["id", "email", "data"],
    )
    async for record in scan:
        assert record["age"] is None
        print(record)
    await txn.commit()


asyncio.run(main())