A Pythonic ORM for DynamoDB
Prismarine defines DynamoDB models with plain Python TypedDict (or Pydantic) classes and generates fully type-safe client code — CRUD, secondary indexes, streams, and TTL — with almost no boilerplate.
pip install prismarine
Why Prismarine?
Model your data in Python and let Prismarine generate the type-safe client for you.
Model with Python Types
Define tables as TypedDict or pydantic.BaseModel classes decorated with @c.model to declare partition and sort keys.
Auto-Generated Client
Run prismarine generate-client to emit a prismarine_client.py with typed get, put, update, list, scan, and delete methods.
Secondary Indexes
Declare GSIs with the @c.index decorator and get generated, type-safe query methods scoped to each index.
Named-Argument Safety
Operations require named arguments, so renaming a key surfaces as a compile-time error in your IDE and linter — no silent failures.
Streams & TTL
Configure DynamoDB stream triggers and Time-To-Live expiration declaratively on the model via the trigger and ttl options.
TypedDict or Pydantic
Ship with lightweight TypedDict by default, or opt into Pydantic models for runtime validation — the API surface stays the same.
Quick Start
From a model definition to type-safe CRUD in three steps.
Define a Model
In models.py, describe your table with a decorated TypedDict:
from typing import TypedDict, NotRequired
from prismarine import Cluster
c = Cluster('TapgameExample')
@c.model(PK='Foo', SK='Bar')
class Team(TypedDict):
Foo: str
Bar: str
Baz: NotRequired[str]
Generate the Client
Emit a fully typed prismarine_client.py alongside your models:
# TypedDict (default)
prismarine generate-client --base
# Or with Pydantic models
prismarine generate-client --model-library pydantic --base
Use Type-Safe CRUD
Call the generated model methods with named arguments:
# Create
TeamModel.put({'Foo': 'foo', 'Bar': 'bar'})
# Query by partition key
teams = TeamModel.list(foo='foo')
# Get / update / delete
team = TeamModel.get(foo='foo', bar='bar')
TeamModel.update({'Baz': 'new'}, foo='foo', bar='bar')
TeamModel.delete(foo='foo', bar='bar')
Works Great with EasySAM
Prismarine is standalone, but pairs naturally with EasySAM for modular serverless apps.
When used alongside EasySAM, Prismarine models become the source of truth for your DynamoDB tables. Declare a
trigger or ttl right on the model, and EasySAM generates the matching CloudFormation —
enabling streams, wiring an EventSourceMapping to your Lambda, and configuring TTL and IAM permissions automatically.
@c.model(PK='Foo', SK='Bar', trigger='itemlogger', ttl='ExpireAt')
class Item(TypedDict):
Foo: str
Bar: str
ExpireAt: int # Unix timestamp
Documentation & Resources
Learn the model decorators, indexes, and generated client API.
Directory structure, model definition, client generation, and CRUD basics.
Full reference for @c.model, @c.index, and @c.export, including keys, custom names, streams, and TTL.
Opt into Pydantic-backed clients with runtime validation while keeping the same API.
Companion AI agent skills for defining models, generating clients, and wiring resources.
Contributors
Built and maintained by these humans.