strawberry-chemist
Explicit GraphQL types. Smart SQLAlchemy loading.
- mapped fields
- computed fields
- scoped relationships
- queryable connections
- filters and ordering
- relay IDs
- node lookup
- selection-aware dataloading
strawberry-chemist is a Strawberry + SQLAlchemy integration for applications
that want explicit GraphQL types, and manual control where needed with full
sqlalchemy ORM backing.
That explicitness is intentional. You decide what your GraphQL DTOs look like, which fields exist, how relationships are exposed, and where client-controlled querying is allowed. The package focuses on reducing boilerplate around that work, bringing GQL schema and your code closer.That makes the public contract easier to reason about, easier to adapt over time, and easier to keep production-safe.
And chemist-managed relationship and connections are selection-aware and dataloader-backed, so explicit DTOs do not force per-parent N+1 behavior, and only fetch what they need.
Simple example
Simply define as if writing your GQL schema directly.
import strawberry_chemist as sc
@sc.type(model=AuthorModel)
class Author:
name: str
books: list[Book]
@sc.type(model=BookModel)
class Book:
title: str
year: int
author: Author
A bit closer to reality: filtering, computed fields, pagination on relations, etc.
Server-scoped relationship-backed field:
import strawberry_chemist as sc
from strawberry_chemist.gql_context import context_var
@sc.type(model=BookModel)
class Book:
@sc.relationship(
"bookmarks",
where=lambda: BookmarkModel.user_id == context_var.get().current_user_id,
select=["id"],
)
def is_bookmarked(self, bookmarks: list[BookmarkModel]) -> bool:
return bool(bookmarks)
Note: current_user_id is application data; the package does not ship auth.
Computed field from selected columns:
import strawberry_chemist as sc
@sc.type(model=BookModel)
class Book:
@sc.field(select=["title", "isbn"])
def title_with_isbn(self, title: str, isbn: str) -> str:
return f"{title} ({isbn})"
Queryable relationship-backed connection:
import strawberry_chemist as sc
@sc.type(model=AuthorModel)
class Author:
books: sc.Connection[Book] = sc.connection(
source="books",
filter=BookFilter,
order=BookOrder,
pagination=sc.CursorPagination(max_limit=20),
)
Where to go next
- start with Getting Started
- browse the API Surface
- use the runnable Examples as acceptance targets