Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

seekdb

Low-level Python bindings for the seekdb C client library.

🚀 What is OceanBase seekdb?

OceanBase seekdb is an AI-native search database that unifies relational, vector, full-text, JSON, and GIS in a single engine, enabling hybrid search and in-database AI workflows.

📖 Read the launch blog → · 📚 Docs →

✨ Why seekdb for Agents?

🔥 Streaming Write + Concurrent Search, Without the P99 Spike

Agent workloads are continuous write + millisecond-later read. seekdb's async index pipeline (Change Stream) decouples DML from index build, and its two-level HNSW (incremental + snapshot) makes newly-written vectors immediately searchable.

seekdb async index pipeline architecture

The write path commits and returns without waiting on index construction. The Change Stream pipeline consumes the redo log asynchronously and updates the delta HNSW. Queries hit both delta and snapshot indexes with fine-grained read locks — this is why P99 stays flat under concurrency.

🌿 Copy-on-Write Sandboxes for Agent Exploration

FORK DATABASE snapshots an entire database in seconds — no data copy. Agents experiment freely (write, query, even break tables); then MERGE TABLE commits the work back, or DROP DATABASE discards it.

🔍 Hybrid Search in a Single SQL

Vector + full-text + scalar filter pushed into one execution plan. No N+1 client-side merging, no glue code to combine results.

🐬 MySQL-Compatible, ACID, Embeddable

Built on the proven OceanBase SQL engine. Works as an embedded library, a single-node server, or in the OceanBase distributed cluster. Full ACID, real-time writes, and the entire MySQL ecosystem out of the box.

Installation

pip install seekdb

Requirements

  • CPython >= 3.11
  • Linux x86_64 or aarch64 with glibc >= 2.28 (Alpine / musl not supported yet)
  • macOS arm64 >= 15.6

🎬 Quick Start

seekdb exposes a lightweight DB-API 2-style interface directly over the seekdb C driver. It currently starts a local seekdb runtime via open(). Native embedded-mode support will be released soon.

import seekdb

# Start a local seekdb runtime (embedded-mode support will be released soon)
seekdb.open(db_dir="./seekdb.db")

# Get a connection and a cursor
conn   = seekdb.connect(database="test", autocommit=True)
cursor = conn.cursor()

# Create a table with a vector column and an HNSW index
cursor.execute("""
    CREATE TABLE IF NOT EXISTS articles (
        id        INT PRIMARY KEY,
        title     TEXT,
        embedding VECTOR(4),
        VECTOR INDEX idx_vec (embedding)
            WITH (DISTANCE=l2, TYPE=hnsw, LIB=vsag)
    ) ORGANIZATION = HEAP
""")

# Insert a row
cursor.execute(
    "INSERT INTO articles VALUES (1, 'Hello seekdb', '[0.1, 0.2, 0.3, 0.4]')"
)

# Hybrid / vector search
cursor.execute("""
    SELECT id, title,
           l2_distance(embedding, '[0.1, 0.2, 0.3, 0.4]') AS dist
    FROM articles
    ORDER BY dist APPROXIMATE
    LIMIT 5
""")
rows = cursor.fetchall()
for row in rows:
    print(row)

cursor.close()
conn.close()
seekdb.close()

Multiple instances

One process can manage multiple local seekdb runtimes through the SeekdbInstance objects returned by open():

import seekdb

first = seekdb.open("./first.db")
second = seekdb.open("./second.db")

first_connection = first.connect(database="test")
second_connection = second.connect(database="test")

first_connection.close()
second_connection.close()
first.close()
second.close()

Each instance stores its local socket inside the normalized database directory. On macOS and Linux, seekdb connects through a per-instance short alias under /tmp/seekdb-uds-<pid>-XXXXXX, so long database paths do not exceed the Unix socket pathname limit. The first successful open() also becomes the module's default instance, preserving the legacy seekdb.connect(), seekdb.connection_options(), and seekdb.close() API. Later calls return independent instance objects without changing that default. Use the object methods for additional instances.

Connect with PyMySQL

connection_options() returns endpoint and authentication arguments shared by Python MySQL-protocol drivers. Install the driver separately:

pip install PyMySQL
import pymysql
import seekdb

instance = seekdb.open(db_dir="./seekdb.db")
options = instance.connection_options()

connection = pymysql.connect(database="test", **options)
try:
    with connection.cursor() as cursor:
        cursor.execute("SELECT 1")
        print(cursor.fetchone())
finally:
    # External connections must release the server before its lifecycle handle.
    connection.close()
    instance.close()

On Unix, options contains only user="root" and unix_socket. For TCP it contains only user="root" and port; the driver supplies its default local host. The database name remains caller-owned because PyMySQL uses database while aiomysql uses db. Treat the returned dictionary as lifecycle-scoped: the Unix socket alias is removed with the underlying lifecycle handle, so do not use it after closing its SeekdbInstance and any retained native connections.

Async initialization and aiomysql

Install aiomysql separately:

pip install aiomysql
import asyncio

import aiomysql
import seekdb


async def main():
    instance = await seekdb.aopen(db_dir="./seekdb.db")
    options = instance.connection_options()
    pool = await aiomysql.create_pool(
        db="test",
        minsize=1,
        maxsize=5,
        **options,
    )
    try:
        async with pool.acquire() as connection:
            async with connection.cursor() as cursor:
                await cursor.execute("SELECT 1")
                print(await cursor.fetchone())
    finally:
        pool.close()
        await pool.wait_closed()
        instance.close()


asyncio.run(main())

aopen() runs the synchronous C startup operation in a worker thread and returns a SeekdbInstance, so it does not block the asyncio event loop. Cancelling the coroutine cannot stop seekdb_open() after that worker starts.

Transaction support

conn = seekdb.connect(database="test", autocommit=False)
cursor = conn.cursor()
try:
    conn.begin()
    cursor.execute("INSERT INTO articles VALUES (2, 'Second', '[0.5,0.6,0.7,0.8]')")
    conn.commit()
except seekdb.SeekdbError:
    conn.rollback()
    raise
finally:
    cursor.close()
    conn.close()

SQL — Hybrid Search

-- Create table with vector column, full-text index, and HNSW vector index
CREATE TABLE docs (
    id        INT PRIMARY KEY,
    title     TEXT,
    content   TEXT,
    embedding VECTOR(384),
    FULLTEXT INDEX idx_fts (content) WITH PARSER ik,
    VECTOR   INDEX idx_vec (embedding)
        WITH (DISTANCE=l2, TYPE=hnsw, LIB=vsag)
) ORGANIZATION = HEAP;

-- Hybrid search: vector similarity + full-text match in one query
SELECT id, title,
       l2_distance(embedding, '[0.12, 0.34, ...]') AS dist
FROM docs
WHERE MATCH(content) AGAINST('quarterly report')
ORDER BY dist APPROXIMATE
LIMIT 10;

API Reference

Module-level functions

Function Description
open(db_dir="./seekdb.db") Start a local runtime and return its SeekdbInstance. The first open instance becomes the module default.
await aopen(db_dir="./seekdb.db") Run open() in a worker thread and return its SeekdbInstance.
connection_options() Return connection arguments for the default instance. The database name is not included.
connect(database="test", autocommit=False) Return a Connection to the default instance.
close() Close and clear the default instance. Idempotent.

SeekdbInstance

Attribute or method Description
db_dir Normalized absolute database directory used by this instance.
closed Whether this instance has been closed.
connect(database="test", autocommit=False) Return a Connection to this instance.
connection_options() Return connection arguments for PyMySQL or aiomysql.
close() Release this instance. Existing native Connection objects keep the underlying lifecycle handle alive until they close.

Connection

Method Description
cursor() Return a new Cursor.
begin() Begin a transaction.
commit() Commit the current transaction.
rollback() Roll back the current transaction.
close() Disconnect and release resources.

Cursor

Method Description
execute(sql) Execute sql; returns the number of rows in the result set (0 for statements without a result set).
fetchone() Return the next row as a tuple, or None.
fetchall() Return all remaining rows as a list of tuple.
close() Free the result set.

SeekdbError

Exception raised on driver errors. Subclass of RuntimeError.

📚 Use Cases

  • 🤖 Agentic AI — streaming memory writes, millisecond-later vector retrieval, FORK DATABASE for safe exploration
  • 📖 RAG & Knowledge Retrieval — hybrid search across enterprise knowledge bases
  • 🔍 Semantic Search — embedding-based search for text, images, and other modalities
  • 💻 AI-Assisted Coding — semantic code search with multi-project isolation
  • 📱 On-Device & Edge AI — lightweight local deployments today, with embedded-mode support coming soon

🌐 Resources

License

Apache-2.0 — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

seekdb-1.4.0.dev2-cp312-abi3-manylinux_2_28_x86_64.whl (53.9 MB view details)

Uploaded CPython 3.12+manylinux: glibc 2.28+ x86-64

seekdb-1.4.0.dev2-cp311-cp311-manylinux_2_28_x86_64.whl (53.9 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

File details

Details for the file seekdb-1.4.0.dev2-cp312-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for seekdb-1.4.0.dev2-cp312-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 20a246b85e24896044b18831463acbf71c21165712c199d774b8e2d1b6c658e3
MD5 b335ea9a8f32ff921baafbb7fb5a7ab7
BLAKE2b-256 a106e934786bae4094938fb3111c2f33193fdb24b75667e38061435c627ddf11

See more details on using hashes here.

File details

Details for the file seekdb-1.4.0.dev2-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for seekdb-1.4.0.dev2-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 be31f4f0935c78edf81c7676ce3d3c2d40506ad29ab1809011423e8d3cbe1e7c
MD5 852b3b63c17cc0f2dda189341382a252
BLAKE2b-256 46449827863f1bd44d1c6c89001547c658cd45b8115451205b5145d877d07757

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.4.0.dev2 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page