BingsanBingsan
Getting Started

First Steps

Create your first namespace and table in Bingsan

First Steps

After installing Bingsan, follow this guide to create your first namespace and table.

Understanding the Hierarchy

Iceberg catalogs use a hierarchical structure:

Catalog (Bingsan)
└── Namespace (e.g., "analytics", "raw.events")
    └── Table (e.g., "user_events")
        └── Metadata (schema, partitions, snapshots)

Create a Namespace

Namespaces are containers for tables. They can be nested using dots or arrays.

# Create a simple namespace
curl -X POST http://localhost:8181/v1/namespaces \
  -H "Content-Type: application/json" \
  -d '{
    "namespace": ["analytics"],
    "properties": {
      "owner": "data-team",
      "description": "Analytics data warehouse"
    }
  }'

Response:

{
  "namespace": ["analytics"],
  "properties": {
    "owner": "data-team",
    "description": "Analytics data warehouse"
  }
}

Nested Namespaces

Create a nested namespace:

curl -X POST http://localhost:8181/v1/namespaces \
  -H "Content-Type: application/json" \
  -d '{
    "namespace": ["analytics", "events"],
    "properties": {}
  }'

Referencing Nested Namespaces in URLs

When referencing nested namespaces in REST API URLs (GET, DELETE, HEAD), use one of these formats:

Option 1: Dot-separated (simple)

# Get nested namespace
curl http://localhost:8181/v1/namespaces/analytics.events

# Delete nested namespace
curl -X DELETE http://localhost:8181/v1/namespaces/analytics.events

Option 2: URL-encoded unit separator (%1F)

# For namespaces with dots in their names, use %1F separator
curl http://localhost:8181/v1/namespaces/analytics%1Fevents

Note: Use %1F (unit separator) when namespace parts contain dots, e.g., ["my.app", "events"] should be encoded as my.app%1Fevents.

List Namespaces

# List all namespaces
curl http://localhost:8181/v1/namespaces

Response:

{
  "namespaces": [
    ["analytics"],
    ["analytics", "events"]
  ]
}

Filter by Parent

# List child namespaces
curl "http://localhost:8181/v1/namespaces?parent=analytics"

Get Namespace Details

curl http://localhost:8181/v1/namespaces/analytics

Response:

{
  "namespace": ["analytics"],
  "properties": {
    "owner": "data-team",
    "description": "Analytics data warehouse"
  }
}

Create a Table

Tables require a schema definition following the Iceberg specification.

curl -X POST http://localhost:8181/v1/namespaces/analytics/tables \
  -H "Content-Type: application/json" \
  -d '{
    "name": "user_events",
    "schema": {
      "type": "struct",
      "schema-id": 0,
      "fields": [
        {"id": 1, "name": "event_id", "required": true, "type": "string"},
        {"id": 2, "name": "user_id", "required": true, "type": "long"},
        {"id": 3, "name": "event_type", "required": true, "type": "string"},
        {"id": 4, "name": "event_time", "required": true, "type": "timestamptz"},
        {"id": 5, "name": "properties", "required": false, "type": {"type": "map", "key-id": 6, "key": "string", "value-id": 7, "value": "string"}}
      ]
    },
    "partition-spec": {
      "spec-id": 0,
      "fields": [
        {"source-id": 4, "field-id": 1000, "name": "event_day", "transform": "day"}
      ]
    },
    "properties": {
      "format-version": "2",
      "write.parquet.compression-codec": "zstd"
    }
  }'

List Tables

curl http://localhost:8181/v1/namespaces/analytics/tables

Response:

{
  "identifiers": [
    {"namespace": ["analytics"], "name": "user_events"}
  ]
}

Load Table Metadata

curl http://localhost:8181/v1/namespaces/analytics/tables/user_events

This returns the full table metadata including:

  • Current schema
  • Partition specification
  • Sort order
  • Current snapshot
  • Table properties

Check Table Exists

Use HEAD request for lightweight existence check:

curl -I http://localhost:8181/v1/namespaces/analytics/tables/user_events

Returns HTTP 200 if exists, 404 if not.

Update Namespace Properties

curl -X POST http://localhost:8181/v1/namespaces/analytics/properties \
  -H "Content-Type: application/json" \
  -d '{
    "updates": {
      "owner": "platform-team"
    },
    "removals": ["description"]
  }'

Delete Resources

Drop Table

curl -X DELETE http://localhost:8181/v1/namespaces/analytics/tables/user_events

Delete Namespace

Namespaces must be empty before deletion.

curl -X DELETE http://localhost:8181/v1/namespaces/analytics

Using with Spark

Once your catalog is set up, connect from Spark:

from pyspark.sql import SparkSession

spark = SparkSession.builder \
    .appName("Bingsan Example") \
    .config("spark.sql.catalog.bingsan", "org.apache.iceberg.spark.SparkCatalog") \
    .config("spark.sql.catalog.bingsan.type", "rest") \
    .config("spark.sql.catalog.bingsan.uri", "http://localhost:8181") \
    .getOrCreate()

# List tables
spark.sql("SHOW TABLES IN bingsan.analytics").show()

# Query table
spark.sql("SELECT * FROM bingsan.analytics.user_events LIMIT 10").show()

Next Steps

On this page