Changelog
- Major (X.0.0): Major new features or breaking changes
- Minor (x.Y.0): New features, backward compatible
- Patch (x.y.Z): Bug fixes and minor improvements
5.7
5.7.0 (2026-5-21)
- feat:
- UseCase MCP selection projection for
call_use_case:call_use_casenow supports response field selection so clients can request focused subsets of nested result data instead of always receiving the full payload - Selection metadata in service introspection: UseCase MCP introspection now exposes selection-aware response information, helping MCP clients discover which fields can be projected
- docs:
- Update English and Chinese UseCase MCP docs with selection projection examples and guidance
- test:
- Add coverage for selection projection behavior across UseCase MCP responses
5.6
5.6.3 (2026-5-21)
- fix:
- UseCase MCP fallback type-hint resolution: unresolved return forward references no longer break runtime parameter coercion or
FromContextinjection incall_use_case, so execution now stays consistent withdescribe_service - refactor:
- Shared type-hint resolution helpers: move use_case fallback annotation resolution into
utils/types.pyand reuse it across introspection, runtime coercion, and return annotation extraction
5.6.2 (2026-5-20)
- fix:
- UseCase MCP type coercion for
call_use_case: arguments received from MCP clients (JSON-native types likeintpassed wherestris expected) are now coerced to the correct Python type using PydanticTypeAdapterbefore being passed to the underlying method
5.6.1 (2026-5-20)
- fix:
- UseCase MCP FromContext parameters are described as optional: parameters annotated with
Annotated[..., FromContext()]now appear as optional in generateddescribe_servicesignatures and parameter metadata, so MCP clients do not need to provide values that are injected from context
5.6.0 (2026-5-9)
This release introduces breaking changes to the UseCaseService API. Methods must now be decorated with @query or @mutation instead of using @classmethod.
- feat:
@query/@mutationdecorators for UseCaseService: UseCaseService methods now use@queryand@mutationdecorators (frompydantic_resolve) instead of@classmethod. The decorators reuse the same implementation as GraphQL, automatically converting methods to classmethods and setting metadataenable_mutationapp-level control: NewUseCaseAppConfig(enable_mutation=False)option to hide mutation methods from MCP tools. When disabled,list_servicesexcludes mutations from count,describe_serviceomits mutation methods, andcall_use_caseblocks mutation callskindfield indescribe_service: Each method indescribe_serviceresponse now includes akindfield ("query"or"mutation") for AI agents to distinguish read vs write operations- break:
- UseCaseService methods require
@query/@mutation: Undecorated async classmethods are no longer automatically discovered byBusinessMeta. All existing UseCaseService subclasses must add@queryor@mutationdecorators __use_case_methods__structure changed: value type changed fromclassmethoddescriptor todictwith keysmethod,kind,description
5.5
5.5.0 (2026-5-9)
This release introduces breaking changes to the AutoLoad API. See Migration Guide — v5.4 to v5.5 for upgrade instructions.
- feat:
- Implicit AutoLoad: fields whose names match a relationship
namein the ER Diagram are automatically resolved without requiringAnnotated[..., AutoLoad()]annotation. ExplicitAutoLoad(origin=...)is still needed when the field name differs from the relationship name - Standalone
AutoLoadfunction:AutoLoadis now a module-level function (from pydantic_resolve import AutoLoad) instead of a factory created viadiagram.create_auto_load(). No diagram binding required - Ambiguity detection for external ErDiagram: when multiple
ErDiagraminstances register conflicting relationships (same name, different FK) for the same entity class,DefineSubsetraisesValueErrorat class-definition time instead of silently using the last registration - break:
ErDiagram.create_auto_load()removed: replaced by standaloneAutoLoad()function. See Migration Guide for detailsLoaderInfo._er_configs_mapremoved: no longer used; relationship lookup now goes through MRO + global registry- refactor:
ErLoaderPreGenerator.prepare()restructured into Phase 1 (explicit AutoLoad) and Phase 2 (implicit matching by field name), consistent withDefineSubsetFK injection logicDefineSubsetFK auto-injection unified via_collect_relationship_candidates_from_mro+_select_relationship, removing direct dependency onLoaderInfo._er_configs_mapResponseBuilderuses implicit AutoLoad for dynamic GraphQL response models, removingAnnotated[..., AutoLoad()]wrappingErDiagramregistration changed from overwrite (kls -> Entity) to append (kls -> [Entity]) to support ambiguity detection
5.4
5.4.0 (2026-5-8)
- feat:
- UseCase MCP server: multi-app management MCP server that exposes UseCaseService methods to AI agents via progressive disclosure (list_apps → list_services → describe_service → call_use_case)
- UseCase
FromContextannotation: methods can declare parameters annotated withFromContextto receive values from request context, withcontext_extractorsupport for async extraction get_return_annotation()utility: extract return type annotation from methods (handles classmethod,__future__annotations, string fallback) for convenient FastAPIresponse_modelusage- refactor:
- Update TypeMapper and SDLBuilder to use new mapping methods and improve type resolution
- Remove unused method for collecting types from method parameters
- Consolidate type checking in
introspector.pyto use shared utilities fromutils/types.py(_is_list,_is_optional,get_core_types), eliminating duplicate type-handling code - Simplify
_collect_dto_typeswithget_core_typesfor one-pass type unwrapping
5.3
5.3.1 (2026-4-22)
- bug:
- fix pagination in many to many relationship
5.3.0 (2026-4-22)
- feat:
- GraphQL limit/offset pagination:
GraphQLHandler(enable_pagination=True)enables server-side pagination for one-to-many relationships. Requirespage_loaderandorder_byconfigured onRelationship. Supports multi-level nested pagination with independent limit/offset per field Resolver(resolved_hooks=...)dependency injection: core Resolver now accepts a list of post-resolve hooks via constructor, decoupling GraphQL-specific pagination logic from the core resolution engine- refactor:
- Extract
inject_nested_paginationinto standalonegraphql/pagination/injector.pymodule, injected viaresolved_hooksinstead of hardcoded in coreResolver - Consolidate pagination hidden field names into
constant.py(GRAPHQL_PAGINATION_FIELD_PREFIX,GRAPHQL_PAGINATION_TREE_FIELD)
5.2
5.2.0 (2026-4-18)
- feat:
Resolver(split_loader_by_type=True): create separate DataLoader instances per request_type so lightweight views (e.g.TaskCardwith 2 columns) don't query all columns needed by heavyweight views (e.g.TaskDetailwith 20 columns). Incompatible withloader_instances. See Resolver API for details.- refactor:
- Improved
validate_and_create_loader_instancereadability with unified split/non-split logic - Deterministic
_query_metaoutput order
5.1
5.1.0 (2026-4-13)
- feat:
- Request context support for GraphQL:
handler.execute()accepts an optionalcontextdict, passed into@query/@mutationmethods via_contextparameter and forwarded to the internalResolver(context=...)for DataLoader context injection _contextparameter in@query/@mutationmethods: declare_context: dictin method signature to receive request-scoped data (e.g.user_idfrom JWT); the parameter is hidden from GraphQL schema — clients cannot see or set it_contextexcluded from SDL and introspection:SDLBuilderandIntrospectionGeneratorskip_contextwhen generating query/mutation field argumentsAppConfig.context_extractorfor MCP: optional callback(Context) -> dict | Awaitable[dict]that extracts request-scoped context from FastMCP HTTP request (e.g. user identity from Authorization header), passed ascontext=tohandler.execute()- RBAC/ABAC demo: new
demo/rbac/showcasing multi-level permission queries with DataLoader batching, FK-based ancestor tracing, ABAC condition evaluation, and mail group permission inheritance - refactor:
- Entity classes updated for context handling in GraphQL API
5.0
5.0.1 (2026-4-11)
- fix:
- fix minor type issues
5.0.0 (2026-4-3)
BREAKING CHANGES — ErDiagram.configs renamed to ErDiagram.entities. See Migration Guide for details.
- feat:
- ORM relationship auto-discovery: new
pydantic_resolve/integrationmodule generatesRelationship+DataLoaderfrom SQLAlchemy, Django, Tortoise ORM model definitions, eliminating hand-written loaderspydantic_resolve.integration.sqlalchemy(pip install pydantic-resolve[sqlalchemy])pydantic_resolve.integration.django(pip install pydantic-resolve[django])pydantic_resolve.integration.tortoise(pip install pydantic-resolve[tortoise])
- Each ORM adapter supports: Many-to-One, One-to-Many, One-to-One, Reverse One-to-One, Many-to-Many
- Generated loaders leverage
_query_metafor field projection (load_only/only) - Per-mapping
filtersanddefault_filterfor query filtering - DTO required-field validation against ORM scalar fields at setup time
Mappingdescriptor (integration.mapping): unified ORM-to-DTO mapping descriptorErDiagram.add_relationship(): merge ORM-generated entities into existing ErDiagram, with duplicate detection by relationship/query/mutation name- Built-in GraphiQL page helper: export
get_graphiql_html()frompydantic_resolve.graphqland addGraphQLHandler.get_graphiql_html()for serving a ready-to-use GraphiQL IDE alongside the GraphQL endpoint - MCP full-schema tool: multi-app MCP servers now expose
get_full_schema(app_name, response_type='sdl'|'introspection')to fetch the entire schema in one call - ORM-first GraphQL response validation: dynamic response models now preserve entity
from_attributes=Trueor enable it viaenable_from_attribute_in_type_adapter, and relationship fields use a syntheticvalidation_aliasto avoid premature lazy-loading of ORM relationships beforeAutoLoadruns - Forward-ref module path syntax:
base_entity()now resolves relationship targets written as'package.module:ClassName'andlist['package.module:ClassName'], reducing same-module ordering constraints - break:
ErDiagram.configs→ErDiagram.entities: parameter renamed; all internal consumers updated
v4.1
v4.1.0 (2026-4-2)
- feat:
- MCP dependencies are now optional:
fastmcpmoved from core dependencies to[project.optional-dependencies]undermcpgroup. Install viapip install pydantic-resolve[mcp]. Core functionality (Resolver, GraphQL, ERD) no longer pulls infastmcp. - MCP imports in
pydantic_resolve/__init__.pynow usetry/exceptfor graceful degradation whenfastmcpis not installed. - fix:
- Remove misleading
config_global_resolvercalls from MCP module docstring examples (__init__.py,server.py). MCP internally usesconfig_resolverviaGraphQLHandlerfor proper isolation.
v4.0
v4.0.1 (2026-4-1)
- fix:
- Auto-added FK fields no longer leak into GraphQL response:
ResponseBuilder._add_fk_fields()now usesField(exclude=True)instead of..., so fields likeidthat are auto-added forAutoLoadresolution are excluded frommodel_dump()serialization while remaining accessible as attributes - Support scalar target relationships in GraphQL:
_build_relationship_field()now handles scalar targets (e.g.,str,int) via_is_scalar_relationship()check, skipping recursive model building for non-BaseModel targets - Allow scalar relationship fields without sub-selections:
_add_relationship_fields()now permits scalar relationship fields to be included even when no sub-fields are selected
v4.0.0 (2026-3-29)
BREAKING CHANGES — ER Diagram API overhaul, simplified Relationship definition. See Migration Guide for details.
- feat:
Relationshipparameter renames:field→fk,target_kls→targetRelationship.namereplacesdefault_field_name: each Relationship must declare a uniquename, used as GraphQL field name and AutoLoad lookup keyRelationship.fk_fnreplacesfield_fnRelationship.fk_none_default/fk_none_default_factoryreplacefield_none_default/field_none_default_factoryAutoLoadreplacesLoadBy: AutoLoad no longer requires FK field name; usesoriginparameter to match by relationship name, defaults to field name- Remove
MultipleRelationshipandLink: multiple relationships to the same target are now separateRelationshipentries with independentname - Remove deprecated
Resolverparameters:loader_filtersandglobal_loader_filter(deprecated since v1.9.3) are removed; useloader_paramsandglobal_loader_param -
_resolve_refsearches registered entities: when module attribute lookup fails, falls back to searching registered entity list, resolving same-module class ordering issues -
refactor:
ResponseBuilderremovesRelationshipInfowrapper, usesRelationshipdirectlyDefineSubsetmodifier logic extracted into_apply_config_modifiers_to_fieldDefineSubsetauto-adds missing AutoLoad FK fields withexclude=True- SDL / Introspection generators unified on
rel.nameandrel.target, allMultipleRelationshipbranches removed - Removed
__pydantic_resolve_relationships__attribute name; use__relationships__only - Added type compatibility check in
ErLoaderPreGenerator.prepare()for early mismatch detection
v3.3
3.3.0 (2026-3-27)
- feat:
- migrate from mcp to fastmcp ver 3
v3.2
v3.2.3 (2026-3-24)
- feat:
- GraphQL hides relationship fields without loaders:
Relationshipfields withloader=Noneare now hidden from GraphQL SDL and introspection, preventing runtime errors when querying unresolvable fields - Applies to both
SDLBuilderandIntrospectionGenerator - test:
- Add
TestHideRelationshipsWithoutLoadertest class intests/graphql/test_sdl_builder.py
v3.2.2 (2026-3-23)
- fix:
- GraphQL datetime serialization: Changed
model_dump(by_alias=True)tomodel_dump(mode='json', by_alias=True)in executor to ensure datetime, date, time, Decimal, and other non-JSON types are properly serialized to JSON-compatible formats - Before:
TypeError: Object of type datetime is not JSON serializable - After: datetime fields are automatically serialized to ISO-8601 strings
- test:
- Add
tests/graphql/test_datetime_support.pyfor datetime, date, time, Decimal serialization
v3.2.1 (2026-3-22)
- fix:
- GraphQL introspection now includes
Relationship.target_klstypes:IntrospectionGenerator._collect_all_typesnow collects types fromRelationship.target_klswhen the target type is not explicitly registered iner_diagram.configs, ensuring consistency with SDL generation - Before: Introspection types list was missing types referenced in relationships, causing field type references to point to undefined types
- After: Both SDL and introspection include the same types, field type references are always valid
- test:
- Add
tests/graphql/test_missing_target_type.pyfor introspection/SDL consistency - Add
tests/graphql/test_forward_ref_resolution.pyfor string reference resolution in__relationships__
v3.2.0 (2026-3-19)
- feat:
- DataLoader context injection: Class-type DataLoaders can now declare a
_contextattribute to access Resolver's global context - Early validation: Raises
LoaderContextNotProvidedErrorif a DataLoader requires context but Resolver doesn't provide one - Useful for permission filtering scenarios where
user_idneeds to be passed to loaders - Example:
v3.1
v3.1.1 (2026-3-18)
- feat:
- Auto-add missing AutoLoad FK fields in DefineSubset: When using
AutoLoadannotation inDefineSubset, the referenced FK field (e.g.,user_idinAutoLoad('user_id')) is now automatically added withexclude=Trueif not explicitly defined in the subset - Early validation for invalid FK references: If
AutoLoadreferences a field that doesn't exist in the parent class, aValueErroris raised at class definition time instead of duringresolve()
- Auto-add missing AutoLoad FK fields in DefineSubset: When using
v3.1.0 (2026-3-16)
- feature:
- add MCP support based on ER diagram, add query/mutation decorator
v3.0
v3.0.7 (2026-3-5)
- perf:
- Two-level METADATA_CACHE with resolver_class isolation: Cache structure changed from
METADATA_CACHE[root_class]toMETADATA_CACHE[id(resolver_class)][root_class], isolating caches for different resolver configurations (created viaconfig_resolver) - Pre-analysis in ResponseBuilder: Dynamic response models are now pre-analyzed immediately after creation in
ResponseBuilder._create_model(), avoiding repeated analysis inResolver.resolve() - Concurrent query execution in GraphQL executor: Moved
query_methodexecution from Phase 1 (serial) to Phase 2 (concurrent), enabling parallel I/O operations for multiple root queries - Before: Phase 1 executes query_methods serially → Phase 2 resolves concurrently
- After: Phase 1 builds models only → Phase 2 executes (query_method + transform + resolve) concurrently
v3.0.6 (2026-3-3)
- feat:
- GraphQL schema now includes
Relationship.target_klstypes: Pydantic types referenced in relationships are automatically collected and generated as GraphQL types, even if not explicitly registered iner_diagram.configs - Supports
Relationshipwithlist[T]generics andload_many=True
v3.0.5 (2026-3-2)
- feat:
- Enum support for GraphQL: Full enum type support across SDL generation, introspection, query execution, and mutation input
- Enum fields now serialize to enum name (e.g.,
"ADMIN") conforming to GraphQL convention - Enum default values in introspection formatted correctly (e.g.,
"USER"instead of"UserRole.USER") - Mutation arguments accept enum names and convert to Python enum members
- refactor:
- Enum serialization optimization: Replaced recursive
_convert_enum_to_namepost-processing with PydanticPlainSerializerfor better performance - Extracted
_add_enum_definitions()helper in SDL generator to reduce code duplication - Fixed
_format_default_value()return type and moved Enum import to module level in introspection generator - Added enum handling in
_map_python_type_to_gql_for_input()for input types
v3.0.4 (2026-3-1)
- feat:
- add LRU cache for GraphQL response model generation in
ResponseBuilder FieldSelectionnow implements__hash__and__eq__to support caching (arguments excluded from comparison)- same query structure with different arguments will hit cache, improving performance
- cache size: 256 entries with LRU eviction
v3.0.3 (2026-3-1)
- refactor:
GraphQLHandlernow creates diagram-specific resolver internally usingconfig_resolver, removingresolver_classparameter- ensures
AutoLoadannotations work without requiringconfig_global_resolver()to be called - convert all relative imports to absolute imports in
pydantic_resolve/directory
v3.0.2 (2026-3-1)
- fix:
- fix introspection for scalar return types (bool, int, float, str) in mutations
v3.0.1 (2026-2-28)
- refactor:
- graphql interface
v3.0.0 (2026-2-27)
- add support for auto-generating graphql interface for ERD.
v2.5
v2.5.0 (2026-2-21)
- stable release
v2.5.0alpha2
- refactor:
- serialization decorator: Use
json_schema_extramechanism instead of monkey-patching- Collects all nested Pydantic types at decoration time via
_collect_nested_types - Sets
json_schema_extraon root class and all nested types automatically - Respects existing configurations (skips types that already have
json_schema_extra) - Removes ~100 lines of code (
_process_schema,_process_nested_type,_process_reference) - File:
pydantic_resolve/utils/openapi.py
- Collects all nested Pydantic types at decoration time via
v2.5.0alpha1
- feat:
- NEW:
@serializationdecorator for recursive JSON schema processing- No-parameter decorator, use
@serializationdirectly - Example:
- No-parameter decorator, use
v2.5.0alpha
- test:
-
Add edge case tests for Pydantic model resolution and collector handling
- Empty classes, missing fields, collector validation, expose conflicts
- Self-reference and circular reference handling
- Inheritance chain testing
- File:
tests/analysis/test_analysis_edge_cases.py
-
refactor:
-
loader management: Enhance loader classes and validation with new architecture
- Improved loader instance creation and validation
- Better error messages for missing or invalid loader configurations
- File:
pydantic_resolve/loader_manager.py
-
ContextVar optimization: Optimize ancestor and collector management
- Use single dict-based ContextVar instead of multiple ContextVars
- Reduces context variable overhead from N+1 to 1 per category
- Pre-create parent ContextVar to avoid repeated creation
- File:
pydantic_resolve/resolver.py
-
doc:
-
Add Entity-First architecture discussion
- Comprehensive documentation on Entity-First design pattern
- Examples of data assembly with automatic resolver
- GraphQL-inspired concepts for FastAPI + Pydantic
- Files:
docs/fastapi-pydantic-architecture-outline.mddocs/fastapi-pydantic-architecture-outline.en.md
-
Update README with detailed Pydantic response schemas and examples
- Clarify ORM and Pydantic schema relationship
v2.4
v2.4.7 (2026-1-29)
- refactor:
- use modern type annotation
- logger
- analysis.py for better readibility
- improve doc, add more details about ErDiagram