Busabase
Busabase는 AI 에이전트를 위한 오픈소스(MIT) 데이터베이스 및 작업 공간입니다
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Turso databases for every ADBC client: a Grainlift worker for local files and Turso Cloud
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Query your Turso databases from DuckDB, Python, Go, Rust
and any other tool that speaks ADBC .
Built on Grainlift by Query.Farm
grainlift-turso is a small server that sits in front of a Turso database
and lets analytics and data tools work with it directly. Point DuckDB at it and
your Turso tables become tables you can join with local data. Use it from
Python and you get results as Apache Arrow, ready for pandas or Polars. Load
data into Turso from a DuckDB query in one statement.
It works with both kinds of Turso database:README 전문 보기 ↗grainlift-turso is a small server that sits in front of a Turso database and lets analytics and data tools work with it directly. Point DuckDB at it and your Turso tables become tables you can join with local data. Use it from Python and you get results as Apache Arrow, ready for pandas or Polars. Load data into Turso from a DuckDB query in one statement.
It works with both kinds of Turso database:
Your tool loads the Grainlift ADBC driver
(pip install adbc-driver-grainlift),
which talks to grainlift-turso over the network. grainlift-turso runs your SQL
on Turso as written and streams the results back.
This takes about five minutes. You need Python 3.13 or newer (for the driver) and uv (to run Haybarn, a DuckDB distribution).
1. Download grainlift-turso for your platform from the latest release and unpack it. For example, on a Mac with Apple Silicon:
curl -L https://github.com/Query-farm/grainlift-turso/releases/latest/download/grainlift-turso-aarch64-apple-darwin.tar.gz | tar xz
cd grainlift-turso-aarch64-apple-darwin
| Platform | Download |
|---|---|
| Linux, x86_64 | grainlift-turso-x86_64-unknown-linux-gnu.tar.gz |
| Linux, ARM64 | grainlift-turso-aarch64-unknown-linux-gnu.tar.gz |
| macOS, Apple Silicon | grainlift-turso-aarch64-apple-darwin.tar.gz |
| macOS, Intel | grainlift-turso-x86_64-apple-darwin.tar.gz |
| Windows, x86_64 | grainlift-turso-x86_64-pc-windows-msvc.zip |
Each release lists SHA-256 checksums in SHA256SUMS. (Prefer containers?
ghcr.io/query-farm/grainlift-turso is the same program; see
Running it in production.)
2. Install the Grainlift driver from PyPI, and note where its library is:
pip install adbc-driver-grainlift
export GRAINLIFT_DRIVER=$(python -c "import adbc_driver_grainlift; print(adbc_driver_grainlift.driver_path())")
3. Start grainlift-turso on a new local database file:
export GRAINLIFT_TOKEN=choose-a-secret
TURSO_DATABASE_URL=demo.db ./grainlift-turso
It prints Grainlift listening on http://127.0.0.1:8080. Leave it running.
4. Query it from DuckDB. In a second terminal, in the same directory and
with the same two exports, start Haybarn with uvx haybarn-cli and paste the
SQL below. It attaches the Turso database, creates a table in it from a DuckDB
query, adds a row, and joins it with local data. (It is also included as
examples/query.sql: uvx haybarn-cli < examples/query.sql runs it in one go.)
FORCE INSTALL adbc_scanner FROM community;
LOAD adbc_scanner;
-- How to reach grainlift-turso: the driver, the server and a token.
CREATE SECRET turso (
TYPE adbc,
DRIVER getenv('GRAINLIFT_DRIVER'),
URI 'http://127.0.0.1:8080',
SCOPE 'http://127.0.0.1:8080',
EXTRA_OPTIONS MAP {
'grainlift.target': 'turso',
'grainlift.auth.bearer_token': getenv('GRAINLIFT_TOKEN')
}
);
-- Attach the Turso database. READ_WRITE lets you create tables and insert.
ATTACH 'http://127.0.0.1:8080' AS turso (TYPE adbc, SECRET 'turso', READ_WRITE);
-- Create a Turso table from a DuckDB query, then add a row.
CREATE TABLE turso.cities AS
SELECT * FROM (VALUES
('Lima', 'PE', 10092000),
('Pune', 'IN', 7166000),
('Rome', 'IT', 2873000)
) AS v(name, country, population);
INSERT INTO turso.cities VALUES ('Oslo', 'NO', 709000);
-- Query it like any table, joined here with local data.
SELECT c.name, k.country, c.population
FROM turso.cities c
JOIN (VALUES ('PE', 'Peru'), ('IN', 'India'), ('IT', 'Italy'), ('NO', 'Norway')) AS k(code, country)
ON c.country = k.code
ORDER BY c.population DESC;
The last query prints:
┌─────────┬─────────┬────────────┐
│ name │ country │ population │
│ varchar │ varchar │ int64 │
├─────────┼─────────┼────────────┤
│ Lima │ Peru │ 10092000 │
│ Pune │ India │ 7166000 │
│ Rome │ Italy │ 2873000 │
│ Oslo │ Norway │ 709000 │
└─────────┴─────────┴────────────┘
Attach the database with READ_WRITE, and its tables behave much like local
ones: query and join them, create them from queries, and insert into them.
DRIVER is the library path that adbc_driver_grainlift.driver_path() prints:
FORCE INSTALL adbc_scanner FROM community;
LOAD adbc_scanner;
CREATE SECRET turso (
TYPE adbc,
DRIVER '/path/to/libadbc_driver_grainlift.dylib',
URI 'http://127.0.0.1:8080',
SCOPE 'http://127.0.0.1:8080',
EXTRA_OPTIONS MAP {'grainlift.target': 'turso', 'grainlift.auth.bearer_token': 'choose-a-secret'}
);
ATTACH 'http://127.0.0.1:8080' AS turso (TYPE adbc, SECRET 'turso', READ_WRITE);
SELECT * FROM turso.cities WHERE population > 1000000;
CREATE TABLE turso.sales AS SELECT * FROM 'sales.parquet'; -- loads in bulk
INSERT INTO turso.sales SELECT * FROM 'more_sales.parquet';
Leave out READ_WRITE to attach read-only.
DuckDB's attached databases cannot UPDATE or DELETE rows here, or run DDL
such as CREATE INDEX or DROP TABLE: DuckDB changes rows by row ID, which
remote tables do not have. Send those statements to Turso directly with
adbc_execute, which reports the rows changed:
SET VARIABLE conn = (SELECT adbc_connect({'secret': 'turso'}));
CALL adbc_execute(getvariable('conn')::BIGINT, 'UPDATE cities SET population = population + 1000 WHERE country = ''NO''');
CALL adbc_execute(getvariable('conn')::BIGINT, 'CREATE INDEX cities_country ON cities (country)');
A table created with adbc_execute appears in the attached database once you
attach it again.
Use Haybarn 1.5.5 or newer:
the adbc_scanner that stock DuckDB currently downloads is too old to load
data through Grainlift.
from adbc_driver_grainlift import dbapi
with dbapi.connect(db_kwargs={
"grainlift.uri": "http://127.0.0.1:8080",
"grainlift.target": "turso",
"grainlift.auth.bearer_token": "choose-a-secret",
}) as conn, conn.cursor() as cur:
cur.execute("SELECT name, population FROM cities")
table = cur.fetch_arrow_table() # or cur.fetch_df() for pandas
pip install adbc-driver-grainlift pyarrow provides everything this needs.
From Go, Rust, Java or C++, load the same library (driver_path()) through
that language's ADBC driver manager, with the entry point
AdbcDriverGrainliftInit and the same grainlift.* settings.
Point the server at your database's URL and give it a database token:
export TURSO_DATABASE_URL=libsql://my-db-my-org.turso.io
export TURSO_AUTH_TOKEN=$(turso db tokens create my-db)
./grainlift-turso
Prefer to have each person use their own Turso token, so Turso applies their
permissions? Leave TURSO_AUTH_TOKEN unset, and each client adds its token as
turso.auth_token next to its other connection settings.
For a long-running deployment, describe your databases and who may use them in a configuration file, then check and serve it:
[server]
listen = "127.0.0.1:8080"
[auth.static_bearer_tokens]
"replace-with-a-long-random-token" = "analytics"
[targets.app] # clients connect to the target "app"
url = "libsql://app-myorg.turso.io"
auth_token_env = "TURSO_APP_TOKEN" # the Turso token comes from the environment
grainlift-turso check --config turso.toml # validates the file and connects to every database
grainlift-turso serve --config turso.toml
Or run the container image, for Linux on x86_64 or ARM64:
docker run -p 8080:8080 -e TURSO_APP_TOKEN \
-v ./turso.toml:/etc/grainlift-turso/turso.toml:ro \
ghcr.io/query-farm/grainlift-turso:latest
One server can serve many databases, each with its own settings, and supports
single sign-on (JWT), mutual TLS, per-user database permissions, health checks,
JSON logs, tracing and graceful shutdown. The
deployment guide covers all of it, and
turso.example.toml is a complete, annotated example.
?, :name, ...).ATTACH.transaction_mode = "concurrent")."retry it" or SQLSTATE 40001. Another writer got there first: your
transaction was rolled back, and nothing it did was saved. Run it again. This
is normal under heavy concurrent writing.
"exceeded its … deadline". The query ran longer than the server allows
(60 seconds by default). Narrow the query, or raise
operation_timeout_seconds in the configuration.
A write fails as unauthorized. The database is read-only for you: a
read-only Turso token, or a file served with read_only = true.
"Column … has type Int64 but row … holds text". A column mixes kinds of
values, which SQLite-style databases allow. Add a CAST in your query to
choose the type you want.
Loading data hangs in DuckDB. Your adbc_scanner extension is too old.
Run FORCE INSTALL adbc_scanner FROM community; in Haybarn 1.5.5 or newer.
"Can only update base table", or "do not support creating tables through
DDL". DuckDB's attached databases cannot update, delete or run DDL on remote
tables; use adbc_execute (see From DuckDB).
A new table doesn't appear in an attached database. DuckDB caches the table list when you attach. Detach and attach again.
Copyright © 2026 Query Farm LLC. Released under the Apache License 2.0; see LICENSE.
The data in a Turso database belongs to its owner, and Turso Cloud is subject to Turso's terms. See NOTICE. This project is not affiliated with or endorsed by Turso.