Catalogs, Databases, and Tables¶
Catalog is the workspace entry point for data assets. Import tasks write to it; SQL, workflows, and knowledge bases reference assets from it. Both official SDKs expose low-level methods for Catalogs, Databases, and Tables.
Workspace
└─ Catalog
└─ Database
└─ Table
Databases also contain Volumes and Files. See Volumes, Folders, and Files for file operations.
Create a client¶
Python uses RawClient and dictionary request bodies:
import os
from moi import RawClient
client = RawClient(
base_url=os.environ["MOI_BASE_URL"],
api_key=os.environ["MOI_API_KEY"],
)
Go uses NewRawClient and typed requests:
client, err := sdk.NewRawClient(os.Getenv("MOI_BASE_URL"), os.Getenv("MOI_API_KEY"))
if err != nil {
log.Fatal(err)
}
Keep the API key out of source control. The remaining examples assume that a client is available.
Walk the resource tree¶
Resolve the complete parent chain before calling a child resource. Applications should persist server-assigned IDs at every level and reserve names for logs and user interfaces.
Resource |
Python / Go methods |
Use |
|---|---|---|
Catalog |
|
List top-level assets or fetch the nested tree |
Database |
|
List by Catalog or fetch Tables and Volumes |
Table |
|
Read a full schema or a lightweight overview |
Python can fetch each level directly:
tree = client.get_catalog_tree()
catalog = client.get_catalog({"id": 101})
databases = client.list_databases({"id": 101})
children = client.get_database_children({"id": 201})
Read table metadata¶
Before passing a Table to a query, workflow, or export task, confirm that:
The Table still belongs to the expected Catalog and Database.
The current identity can read it.
Required columns exist and their types match the caller’s expectations.
Loading or processing has finished and the object is readable.
Treat the schema as the runtime contract. preview_table returns a limited sample, while get_table_data provides paginated rows:
table = client.get_table({"id": 301})
sample = client.preview_table({"id": 301, "lines": 10})
page = client.get_table_data(
{"id": 301, "database_id": 201, "page": 1, "page_size": 100}
)
Create and change objects¶
The basic Python creation flow is:
catalog = client.create_catalog(
{"name": "analytics", "description": "Production analytics"}
)
database = client.create_database(
{"catalog_id": 101, "name": "sales", "description": "Sales mart"}
)
table = client.create_table(
{
"database_id": 201,
"name": "orders",
"columns": [{"name": "id", "type": "int", "is_pk": True}],
}
)
Use a column type supported by the target service. Before retrying Table creation, call check_table_exists({"database_id": ..., "name": ...}). Persist IDs from Catalog and Database creation responses rather than rediscovering objects by name.
The corresponding Go methods are CreateCatalog, CreateDatabase, and CreateTable, with CatalogCreateRequest, DatabaseCreateRequest, and TableCreateRequest. UpdateCatalog can change the name or comment; UpdateDatabase changes only the comment and cannot rename a Database.
Download table data¶
Both SDKs can request a signed download link. Python also exposes download_table_data, which returns a CSV FileStream:
stream = client.download_table_data({"id": 301})
try:
with open("orders.csv", "wb") as output:
while chunk := stream.read(1024 * 1024):
output.write(chunk)
finally:
stream.close()
Always close the stream. Treat signed URLs and preview results as temporary data, not durable addresses.
Delete safely¶
truncate_table removes all rows but retains the schema; delete_table removes both schema and data. delete_database removes the complete Database, while delete_catalog cascades through its Databases, Tables, and Volumes. Before calling any of them:
Verify the Table’s complete location with
get_table_full_path.Inspect references with
get_table_ref_list,get_database_ref_list, orget_catalog_ref_list.Remove downstream references before deleting the leaf object.
Read again or list the parent after deletion to confirm the object is no longer available.