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.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