Skip to main content

pylibseekdb

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 pylibseekdb

Logical version migration

pylibseekdb installs seekdb-dump and seekdb-restore for migrating an embedded database without opening an old data directory with a new runtime. Stop all application writes and DDL, then create the dump while the old wheel is still installed:

seekdb-dump ./old.db -o backup.sql

After installing the new wheel, restore into a new or otherwise empty instance:

seekdb-restore ./new.db backup.sql

The dump is mysql-compatible SQL, so stdout, stdin, and external compression can be used:

seekdb-dump ./old.db | gzip > backup.sql.gz
gzip -dc backup.sql.gz | seekdb-restore ./new.db

By default all user databases are included. Repeat --database NAME to select specific databases. System databases, users, and grants are never exported. Tables, their data and indexes, and ordinary views are supported. Triggers, stored routines, events, materialized views, and unknown object types are reported before any SQL is written and make the command fail. To deliberately create a partial dump, use --ignore-unsupported. Restore warns with the skipped-object list and continues without those objects.

seekdb-restore refuses a target containing any user table or view. A failed restore can contain already-applied DDL, so discard that target and retry with an empty instance.

Requirements

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

🎬 Quick Start

pylibseekdb 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 pylibseekdb as 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 pylibseekdb as 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, pylibseekdb connects through a per-instance short alias under /tmp/pylibseekdb-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. PyMySQL is installed with pylibseekdb:

pip install pylibseekdb
import pymysql
import pylibseekdb as 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 pylibseekdb as 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.

pylibseekdb-1.4.0-cp312-abi3-manylinux_2_28_x86_64.whl (54.0 MB view details)

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

pylibseekdb-1.4.0-cp312-abi3-manylinux_2_28_aarch64.whl (49.4 MB view details)

Uploaded CPython 3.12+manylinux: glibc 2.28+ ARM64

pylibseekdb-1.4.0-cp312-abi3-macosx_15_0_x86_64.whl (60.5 MB view details)

Uploaded CPython 3.12+macOS 15.0+ x86-64

pylibseekdb-1.4.0-cp312-abi3-macosx_15_0_arm64.whl (52.2 MB view details)

Uploaded CPython 3.12+macOS 15.0+ ARM64

pylibseekdb-1.4.0-cp311-cp311-manylinux_2_28_x86_64.whl (54.0 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

pylibseekdb-1.4.0-cp311-cp311-manylinux_2_28_aarch64.whl (49.4 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ ARM64

pylibseekdb-1.4.0-cp311-cp311-macosx_15_0_x86_64.whl (60.5 MB view details)

Uploaded CPython 3.11macOS 15.0+ x86-64

pylibseekdb-1.4.0-cp311-cp311-macosx_15_0_arm64.whl (52.2 MB view details)

Uploaded CPython 3.11macOS 15.0+ ARM64

File details

Details for the file pylibseekdb-1.4.0-cp312-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pylibseekdb-1.4.0-cp312-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 2d32d6f0d3b92b0c719b6c4230a24748ce10666f67052c696359e69138d8fbe7
MD5 80e40d21fee10221bdce0728cc1a4fc1
BLAKE2b-256 5cf3452485e45676a7d738720a7a3f7abbf4d24a3d272cbacabef41ae8b8e52c

See more details on using hashes here.

File details

Details for the file pylibseekdb-1.4.0-cp312-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pylibseekdb-1.4.0-cp312-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 f606579904a19bcd7ec96bc117251db9d4202485fc7355f2a289804d1b3b2c1b
MD5 0ef44fe951e2c5ca124064b02615c630
BLAKE2b-256 dfb5ea71acbee58925a51cb1a7137afd2d1c4e3fbb5bf2a0144cd53d299a20df

See more details on using hashes here.

File details

Details for the file pylibseekdb-1.4.0-cp312-abi3-macosx_15_0_x86_64.whl.

File metadata

File hashes

Hashes for pylibseekdb-1.4.0-cp312-abi3-macosx_15_0_x86_64.whl
Algorithm Hash digest
SHA256 c17f2f75793c287a4f14a51df046e14c32446d35dd64dda9b32c5f41bb9b4b20
MD5 f07d88f9d57994078faafccf16ccb9dc
BLAKE2b-256 7785ebd60eac61710da45b447e0ce6b63d124fa944a8c5e84c84f8527e95855b

See more details on using hashes here.

File details

Details for the file pylibseekdb-1.4.0-cp312-abi3-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for pylibseekdb-1.4.0-cp312-abi3-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 2fee55af299f2992dd5d61c9e239ef8855629f4117ee8b4c21dc877160707004
MD5 05fc119e642a88be2fc7ca8669ecc34d
BLAKE2b-256 ca034380094699cbd4539971c0b943701f776408c94c28cc3ecdaed7c217bb29

See more details on using hashes here.

File details

Details for the file pylibseekdb-1.4.0-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pylibseekdb-1.4.0-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 6aaa3c9e4865d32f533af04eb8eab06d2c10fc581ac38097d618efb44c05dc5b
MD5 51db850e0c0d45e1cf41148e6216def6
BLAKE2b-256 71cde54bb304512042cac0514fd607175f5425bd0924330e3eb74937c2afe827

See more details on using hashes here.

File details

Details for the file pylibseekdb-1.4.0-cp311-cp311-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pylibseekdb-1.4.0-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 e37b931417b7fc7fc88d15fd8b9b0dad499cd05e693cc483aa3743840e85f0c0
MD5 274455872344ff3a7801424ff56e171c
BLAKE2b-256 6493e9a13b996b5561f89c9a4f1b62796f8a6230a5dce215869e3cfef8adc4f1

See more details on using hashes here.

File details

Details for the file pylibseekdb-1.4.0-cp311-cp311-macosx_15_0_x86_64.whl.

File metadata

File hashes

Hashes for pylibseekdb-1.4.0-cp311-cp311-macosx_15_0_x86_64.whl
Algorithm Hash digest
SHA256 50ea01a5bec94a0642338323c036b83a98c987d5b040e5e9abb9d0d144c2562b
MD5 4ef6b90fa3d77de58facdd85fcb34b42
BLAKE2b-256 940931d35ee01a5c996b2b4e62f529ea7f1e2f163b2bf450799aefba8062e3e8

See more details on using hashes here.

File details

Details for the file pylibseekdb-1.4.0-cp311-cp311-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for pylibseekdb-1.4.0-cp311-cp311-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 5cb2efab9f1321cdb4b034d3a2bd92e41a402fc95e7dc9579c7473a426f96e24
MD5 76db2dd6ae3e853ad7593775cdc41d6e
BLAKE2b-256 aea87413d33218aff55a14ec9d20532b49243ffd0579e7a92244922c1885444e

See more details on using hashes here.

Release history Release notifications | RSS feed

1.4.0.post1

8 files

This release

1.4.0 This release

8 files

1.4.0.dev2

1.3.0.post5

8 files

1.3.0.post4

8 files

1.3.0.post3

12 files

1.3.0

18 files

1.2.0

18 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