Use StatelyDB with Python

Stately Cloud
, 3 minute read

Python developers value pragmatism, clarity, and speed. Yet when it comes to databases, the landscape is often a mix of cumbersome abstractions or unstructured chaos. You’re either navigating the heavy machinery of an ORM like SQLAlchemy, or juggling raw dictionaries from a NoSQL driver and sacrificing the structure that keeps apps robust.

StatelyDB offers a more Pythonic path. Our schema-first workflow generates clean, typed data classes so you interact with data using an elegant async API. Less boilerplate, more shipping.

The Python Data Disconnect

Common pain points you may recognize:

  • ORM Complexity: Sessions, unit-of-work patterns, hidden performance traps. The abstraction meant to help adds cognitive load.
  • Dict Soup: Flexible NoSQL backends leave you passing around dict[str, Any] and sprinkling validation everywhere. Misspell a key; get a runtime error.
  • Migration Risk: Alembic scripts + production changes = stress. Small iterations feel heavyweight.
  • Boilerplate Glue: Hand-written DTOs, validators, serializers—time not spent on product value.

The StatelyDB Developer Experience

Designed to feel natural in modern Python: simple, explicit, productive.

1. Define Your Schema Once

Your single source of truth is a TypeScript-based Elastic Schema™ file that describes your data model.

// schema/schema.ts
import { itemType, string, uuid } from "@stately-cloud/schema";

/** A user of our new application. */
itemType("User", {
    keyPath: "/user-:id",
    fields: {
        id: { type: uuid, initialValue: "uuid" },
        name: { type: string },
        email: { type: string },
    },
});

2. Generate Native Python Data Classes

Run one command to produce a typed client package (works beautifully with MyPy + IDEs):

stately schema generate \
    --language python \
    --schema-id <your-schema-id> \
    ./your_app/stately_client

This yields data classes and a lightweight client you can import directly.

3. Interact with a Clean, Asynchronous API

Compare StatelyDB with raw Boto3 DynamoDB usage.

StatelyDB: Clean and Pythonic

# your_app/user_service.py
from your_app.stately_client import Client, User

async def create_user(client: Client, name: str, email: str) -> User:
        # Instantiate a typed data class.
        user_to_create = User(name=name, email=email)

        # Put returns a fully typed object.
        created_user = await client.put(user_to_create)
        print(f"Created user with ID: {created_user.id}")
        return created_user

Typical Boto3 for DynamoDB: Verbose and Untyped

import boto3, uuid

dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table("my-table")

def create_user(name: str, email: str) -> dict:
        user_id = str(uuid.uuid4())
        # Manually craft the item.
        item = {
                "PK": f"USER#{user_id}",
                "SK": "METADATA",
                "id": user_id,
                "name": name,
                "email": email,
        }
        table.put_item(Item=item)
        return {"id": user_id, "name": name, "email": email}

With StatelyDB you write less, it’s clearer, and it’s type-safe end‑to‑end.

4. Evolve Fearlessly

Need to change a field? Update schema.ts, add a migration command, regenerate, and deploy. Elastic Schema ensures forward + backward compatibility—no brittle manual SQL or risky downtime migrations.

Get Started with Python

Ready to use a database that feels built for Python?

  1. Follow our Getting Started Guide to create your account, store, and schema.
  2. Install the SDK:
    pip install statelydb
    
  3. Generate your Python client code (see step 2 above).
  4. Initialize the client and start building.
import asyncio, os
from your_app.stately_client import Client  # Generated client
from your_app.user_service import create_user

async def main():
        store_id = os.environ["STATELY_STORE_ID"]  # Provided via environment
        # You can also pass region=... if needed.
        async with Client(store_id=store_id) as client:
                _ = await create_user(client, "Ada Lovelace", "ada@example.com")

if __name__ == "__main__":
        asyncio.run(main())

It’s that simple.

Create a FREE account!

Latest from our blog

/images/posts/announcing-java-sdk.png
StatelyDB SDK now available for Java
Author Photo
Stately Team
October 1, 2025
/images/posts/encoding-sortable-binary-database-keys.png
Solving sorting for nested keys with mixed data types
Author Photo
Ben Hollis
August 25, 2025
/images/posts/aws-just-explained-why-you-need-elastic-schema.jpg
It's a lot of work that your database could do for you
Author Photo
Ben Hollis
August 7, 2025
View all posts

Using DynamoDB today? Want to try StatelyDB?