Skip to content

Auto Query

Writing @query methods for basic CRUD is repetitive. Auto Query generates by_id and by_filter for every entity — no decorators needed.

Step 1: Enable AutoQueryConfig

One parameter on GraphQLHandler:

from nexusx import GraphQLHandler, AutoQueryConfig

handler = GraphQLHandler(
    base=SQLModel,
    session_factory=async_session,
    auto_query_config=AutoQueryConfig(session_factory=async_session),
)

Warning

AutoQueryConfig needs its own session_factory parameter — it doesn't inherit from GraphQLHandler.

You can also add auto queries to an existing handler:

from nexusx import add_standard_queries

add_standard_queries(handler, AutoQueryConfig(session_factory=async_session))

Step 2: Use by_id for Single Records

Auto-generated for each entity with exactly one primary key field:

{ userById(id: 1) { name email } }
{ postById(id: 42) { title author { name } } }

That's it — no @query method needed. The framework reads your primary key field and generates the query.

Step 3: Use by_filter for Field Matching

Each entity also gets a FilterInput type and a filter query:

{ userByFilter(filter: { name: "Alice" }, limit: 5) { id name email } }
{ postByFilter(filter: { author_id: 1 }, limit: 10) { id title } }

FilterInput fields correspond one-to-one with entity fields (excluding relationship fields), supporting exact-match filtering.

Tip

by_filter is exact-match only — no LIKE, range queries, or ordering. For anything more complex, write a custom @query method. Auto and manual queries coexist in the same schema.

When Auto Queries Fall Short

Auto queries cover common patterns, but they have limits:

Limitation Detail
Composite primary keys by_id only supports single PK fields — composite PK entities won't get a by_id query
Exact match only by_filter doesn't support LIKE, range queries, or ordering
No joins or aggregation These are read-only single-table queries

When you hit these limits, write a @query method — it coexists naturally:

class Post(SQLModel, table=True):
    id: int | None = Field(default=None, primary_key=True)
    title: str

    @query
    async def get_recent(cls, days: int = 7) -> list['Post']:
        """Get posts from the last N days."""
        ...

handler = GraphQLHandler(
    base=SQLModel,
    session_factory=async_session,
    auto_query_config=AutoQueryConfig(session_factory=async_session),
)

The resulting schema contains all three:

  • postById, postByFilter — auto-generated
  • postGetRecent — your custom query

Recap

  • AutoQueryConfig generates by_id and by_filter for every entity with a single primary key
  • by_id looks up a single record by PK; by_filter does exact-match field filtering
  • Auto and manual @query methods coexist in the same schema
  • For complex queries (ranges, joins, aggregation), write a custom @query

Next Steps