Skip to content

Tables

All table operations go through a single endpoint:

POST /workspaces/{workspace}/tables/query

You send SQL in the request body. Deep Lake executes it and returns the result.

Setup

import requests

API_URL = "https://api.deeplake.ai"
TOKEN = "YOUR_TOKEN"
WORKSPACE = "YOUR_WORKSPACE"
TABLE = "documents"

headers = {
    "Authorization": f"Bearer {TOKEN}",
    "Content-Type": "application/json",
}

def query(sql):
    """Execute a SQL query and return the response."""
    res = requests.post(
        f"{API_URL}/workspaces/{WORKSPACE}/tables/query",
        headers=headers,
        json={"query": sql},
    )
    return res.json()

Create a table

Standard SQL with optional tensor columns. Use FLOAT4[] for embeddings and FLOAT4[][] for multi-vector embeddings.

Tables must be schema-qualified with your workspace name and use USING deeplake for indexes (vector, BM25, exact text) to work.

query(f"""
    CREATE TABLE IF NOT EXISTS "{WORKSPACE}"."{TABLE}" (
        id SERIAL PRIMARY KEY,
        title TEXT,
        content TEXT,
        metadata JSONB,
        embedding FLOAT4[],
        file_id UUID,
        created_at TIMESTAMPTZ DEFAULT NOW()
    ) USING deeplake
""")

Insert rows

Single row

query(f"""
    INSERT INTO "{WORKSPACE}"."{TABLE}" (title, content, metadata)
    VALUES ('First doc', 'Hello world', '{{"source": "manual"}}'::jsonb)
""")

Eventual consistency

After INSERT, data may take a few seconds to become visible in SELECT queries. This is normal behavior for Deep Lake tables.

Parameterized insert

Use the params field for dynamic values:

res = requests.post(
    f"{API_URL}/workspaces/{WORKSPACE}/tables/query",
    headers=headers,
    json={
        "query": f"""
            INSERT INTO "{WORKSPACE}"."{TABLE}" (title, content, metadata)
            VALUES ($1, $2, $3::jsonb)
        """,
        "params": ["My title", "My content", '{"source": "api"}'],
    },
)

Batch insert

Use the batch endpoint for multiple rows:

res = requests.post(
    f"{API_URL}/workspaces/{WORKSPACE}/tables/query/batch",
    headers=headers,
    json={
        "query": f"""
            INSERT INTO "{WORKSPACE}"."{TABLE}" (title, content)
            VALUES ($1, $2)
        """,
        "params_batch": [
            ["Doc A", "Content A"],
            ["Doc B", "Content B"],
            ["Doc C", "Content C"],
        ],
    },
)

Query data

Select all

result = query(f'SELECT * FROM "{WORKSPACE}"."{TABLE}" LIMIT 10')
print(result)

Filter with WHERE

result = query(f"""
    SELECT title, content FROM "{WORKSPACE}"."{TABLE}"
    WHERE metadata->>'source' = 'api'
    ORDER BY created_at DESC
    LIMIT 5
""")

Count rows

result = query(f'SELECT COUNT(*) FROM "{WORKSPACE}"."{TABLE}"')

Update rows

query(f"""
    UPDATE "{WORKSPACE}"."{TABLE}"
    SET content = 'Updated content', metadata = '{{"source": "api", "version": 2}}'::jsonb
    WHERE title = 'First doc'
""")

Delete rows

query(f"""DELETE FROM "{WORKSPACE}"."{TABLE}" WHERE title = 'First doc'""")

Drop a table

query(f'DROP TABLE IF EXISTS "{WORKSPACE}"."{TABLE}"')

Or via the REST endpoint:

requests.delete(
    f"{API_URL}/workspaces/{WORKSPACE}/tables/{TABLE}",
    headers={"Authorization": f"Bearer {TOKEN}"},
)

List tables

res = requests.get(
    f"{API_URL}/workspaces/{WORKSPACE}/tables",
    headers={"Authorization": f"Bearer {TOKEN}"},
)
print(res.json())

Column types

Type Use for
TEXT Strings, identifiers
INT, BIGINT Integers
FLOAT4 Single-precision floats
FLOAT4[] Embedding vectors
FLOAT4[][] Multi-vector embeddings (MaxSim)
JSONB Structured metadata
UUID File references (file_id)
TIMESTAMPTZ Timestamps
BIGSERIAL Auto-incrementing IDs