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