Skip to content

Tables Module

SDK reference for table and document storage

The tables module provides document-oriented data storage with JSONB support, similar to Dataverse or MongoDB. Tables can be scoped to organizations, applications, or globally.

from bifrost import tables

Create a new table for storing documents.

async def create(
name: str,
description: str | None = None,
table_schema: dict[str, Any] | None = None,
scope: str | None = None,
app: str | None = None,
) -> TableInfo
ParameterTypeDescription
namestrTable name (lowercase, underscores allowed, must start with letter)
descriptionstrOptional table description
table_schemadictOptional JSON Schema for validation hints
scopestrNone=context org, "global"=global, UUID=specific org
appstrApplication UUID to scope table to an app

TableInfo with table metadata including id, name, organization_id, application_id.

# Create org-scoped table
customers = await tables.create("customers", description="Customer records")
# Create app-scoped table
app_data = await tables.create("app_settings", app="app-uuid-here")
# Create global table
shared = await tables.create("shared_lookups", scope="global")

List all tables in the current scope.

async def list(
scope: str | None = None,
app: str | None = None,
) -> list[TableInfo]
ParameterTypeDescription
scopestrNone=context org (includes global), "global"=global only, UUID=specific org
appstrFilter by application UUID
# List all accessible tables
all_tables = await tables.list()
# List only app-specific tables
app_tables = await tables.list(app="app-uuid-here")

Delete a table and all its documents.

async def delete(
name: str,
scope: str | None = None,
app: str | None = None,
) -> bool

True if deleted, False if table not found.

deleted = await tables.delete("old_customers")

Insert a document into a table.

async def insert(
table: str,
data: dict[str, Any],
scope: str | None = None,
app: str | None = None,
) -> DocumentData
ParameterTypeDescription
tablestrTable name
datadictDocument data (any JSON-serializable dict)
scopestrOrganization scope
appstrApplication UUID

DocumentData with id, table_id, data, created_at, updated_at.

doc = await tables.insert("customers", {
"name": "Acme Corp",
"email": "info@acme.com",
"status": "active",
"revenue": 50000
})
print(f"Created document: {doc.id}")

Get a document by ID.

async def get(
table: str,
doc_id: str,
scope: str | None = None,
app: str | None = None,
) -> DocumentData | None

DocumentData if found, None if not found.

doc = await tables.get("customers", "uuid-here")
if doc:
print(doc.data["name"])

Update a document (partial update, merges with existing data).

async def update(
table: str,
doc_id: str,
data: dict[str, Any],
scope: str | None = None,
app: str | None = None,
) -> DocumentData | None
ParameterTypeDescription
tablestrTable name
doc_idstrDocument UUID
datadictFields to update (merged with existing data)
# Only updates status field, other fields unchanged
updated = await tables.update("customers", doc_id, {"status": "inactive"})

Delete a document.

async def delete_document(
table: str,
doc_id: str,
scope: str | None = None,
app: str | None = None,
) -> bool

True if deleted, False if not found.

Query documents with filtering and pagination.

async def query(
table: str,
where: dict[str, Any] | None = None,
order_by: str | None = None,
order_dir: str = "asc",
limit: int = 100,
offset: int = 0,
scope: str | None = None,
app: str | None = None,
) -> DocumentList
ParameterTypeDescription
tablestrTable name
wheredictFilter conditions (see Filter Operators below)
order_bystrField name to order by
order_dirstr"asc" or "desc"
limitintMaximum documents to return (default 100, max 1000)
offsetintNumber of documents to skip

DocumentList with documents, total, limit, offset.

# Simple equality filter
results = await tables.query("customers", where={"status": "active"})
# With pagination
results = await tables.query(
"customers",
where={"status": "active"},
order_by="name",
limit=20,
offset=40
)
for doc in results.documents:
print(doc.data["name"])
print(f"Showing {len(results.documents)} of {results.total}")

Count documents matching a filter.

async def count(
table: str,
where: dict[str, Any] | None = None,
scope: str | None = None,
app: str | None = None,
) -> int
total = await tables.count("customers")
active = await tables.count("customers", where={"status": "active"})

The where parameter supports advanced filter operators for flexible querying.

where={"status": "active"}
# SQL: WHERE data->>'status' = 'active'
# Greater than
where={"amount": {"gt": 100}}
# Greater than or equal
where={"amount": {"gte": 100}}
# Less than
where={"amount": {"lt": 1000}}
# Less than or equal
where={"amount": {"lte": 1000}}
# Range query (multiple operators)
where={"amount": {"gte": 100, "lt": 1000}}
where={"status": {"ne": "deleted"}}
# Case-sensitive LIKE
where={"name": {"like": "%acme%"}}
# Case-insensitive LIKE (recommended)
where={"name": {"ilike": "%acme%"}}
where={"category": {"in": ["electronics", "software", "services"]}}
# Field is null
where={"deleted_at": {"is_null": True}}
# Field is not null
where={"deleted_at": {"is_null": False}}

Multiple fields are combined with AND:

results = await tables.query("orders", where={
"status": "active",
"amount": {"gte": 100, "lt": 10000},
"category": {"in": ["electronics", "software"]},
"customer_name": {"ilike": "%corp%"}
})
# SQL: WHERE status = 'active'
# AND amount >= 100 AND amount < 10000
# AND category IN ('electronics', 'software')
# AND customer_name ILIKE '%corp%'
class TableInfo(BaseModel):
id: str
name: str
description: str | None
table_schema: dict[str, Any] | None
organization_id: str | None
application_id: str | None
created_by: str | None
class DocumentData(BaseModel):
id: str
table_id: str
data: dict[str, Any]
created_at: str | None
updated_at: str | None
class DocumentList(BaseModel):
documents: list[DocumentData]
total: int
limit: int
offset: int

Tables support three levels of scoping:

Tables are scoped to the current organization:

# Uses execution context org
table = await tables.create("customers")

Tables can be scoped to a specific application within an organization:

# Scoped to an app
table = await tables.create("app_data", app="app-uuid")
results = await tables.query("app_data", app="app-uuid")

Tables with scope="global" are platform-wide:

# Global table (no org_id)
table = await tables.create("shared_lookups", scope="global")