Strawchemy generates GraphQL types, inputs and resolvers from SQLAlchemy models. The models already in the application are the schema definition.
Without it, filtering, ordering, pagination and nested selections all need hand-written resolvers — boilerplate that also invites N+1 queries.
- Single-statement resolution
Each root field's selection set compiles to one SQL query, however deep. No dataloaders, no N+1. - Type-aware filtering
Each column gets the comparisons its type supports, from text and dates to arrays, JSON, and PostGIS geometry, combined with and, or, and not to any depth. - Full aggregation support
Aggregate a relationship or the whole result set, and filter on the result — "users with more than three posts" is a filter argument. - Nested mutation trees
Create a parent, its children and their children in one mutation. Link, unlink and insert-or-update in the same call. - Generated GraphQL types
Output types and the filtering, ordering, and mutation inputs all come from the model, and you opt into each separately. - Layered configuration
Set defaults once on the mapper, override them on a type, and override them again on a single field. - Custom fields
A field you write yourself declares what it reads, and the main query loads it. - Multi-dialect
Target PostgreSQL, MySQL, and SQLite from one mapping; Strawchemy absorbs the dialect differences. - Sync/Async compatible
The same mapped types work against a sync or an async session, chosen per schema or per field.
Warning
Please note that strawchemy is currently in a pre-release stage of development. This means that the library is still under active development and the initial API is subject to change. We encourage you to experiment with strawchemy and provide feedback, but be sure to pin and update carefully until a stable release is available.
Full documentation is at https://strawchemy.pages.dev
Strawchemy is available on PyPi
uv add strawchemyStrawchemy has the following optional dependencies:
asyncio: Async sessions, through SQLAlchemy'sasyncioextra (installsgreenlet)geo: Enable Postgis support through geoalchemy2
To install these dependencies along with strawchemy:
uv add strawchemy[geo]Map a model, derive filter and type classes from it, then expose a query field:
class User(Base):
__tablename__ = "user"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str]
posts: Mapped[list[Post]] = relationship("Post", back_populates="author")
strawchemy = Strawchemy(StrawchemyConfig("sqlite"))
@strawchemy.filter(User, include="all")
class UserFilter: ...
@strawchemy.type(User, include="all")
class UserType: ...
@strawberry.type
class Query:
users: list[UserType] = strawchemy.field(filter_input=UserFilter, pagination=True)Querying it filters, paginates and resolves the posts relationship without any resolver code:
{
users(limit: 10, filter: { name: { contains: "Al" } }) {
id
name
posts {
title
}
}
}See the getting started guide for the full walkthrough.
Contributions are welcome! Please see CONTRIBUTING.md for details on how to contribute to this project.
This project is licensed under the terms of the license included in the LICENCE file.