Skip to content

Comments

fix: resolve Pydantic field aliases in nested expression field queries#1278

Open
roman-right wants to merge 5 commits intomainfrom
fix/issue-937-945-field-alias-in-queries
Open

fix: resolve Pydantic field aliases in nested expression field queries#1278
roman-right wants to merge 5 commits intomainfrom
fix/issue-937-945-field-alias-in-queries

Conversation

@roman-right
Copy link
Member

@roman-right roman-right commented Feb 16, 2026

Fixes #937, #945

Problem

When using Pydantic Field aliases on nested BaseModel fields, find queries used the Python attribute name instead of the alias. For example, Doc.nested.unit_class produced nested.unit_class in the MongoDB query instead of nested.unitClass.

This also affected Link fields with aliases (#945).

Fix

ExpressionField now carries optional type information about the nested model. When accessing a sub-attribute, it looks up the alias in the nested model's fields and resolves it. This works at arbitrary nesting depth.

Changes:

  • ExpressionField.__new__ accepts an optional model_class parameter
  • ExpressionField.__getattr__ resolves aliases from the nested model's fields
  • init_document_fields and init_view_fields pass the resolved nested model type to ExpressionField

Tests

Added tests for:

  • Single-level nested alias resolution
  • Multi-level (deep) nested alias resolution
  • Query filter generation with aliased nested fields
  • Backward compatibility with non-aliased fields

Roman and others added 4 commits February 15, 2026 20:27
Fixes #937, #945.

ExpressionField now carries optional type metadata about the nested Pydantic
model. When accessing sub-fields via __getattr__, it looks up the field alias
from the model's field info instead of using the Python attribute name directly.
This works at arbitrary nesting depth.

Added test models and 5 new tests in TestAliasResolution.
…__getattr__

- Remove mid-code import of get_model_fields (already imported at module level)
- Remove bare try/except that silently swallowed all exceptions
@roman-right roman-right force-pushed the fix/issue-937-945-field-alias-in-queries branch from 184884a to 0f5e25b Compare February 16, 2026 04:37
…h resolution

Introduce FieldResolution dataclass (frozen, immutable) that tracks:
- model_class: nested BaseModel for alias resolution during field access
- is_link: whether path crosses a Link/BackLink boundary

ExpressionField now resolves aliases through Link types and carries
is_link metadata. resolve_query_paths() replaces the legacy convert_ids()
hack with metadata-driven DBRef translation (_id <-> ) at query time.

Architecture:
- ExpressionField._resolve_field() returns FieldResolution (was _resolve_nested_model)
- __getattr__ propagates is_link from parent to child expressions
- resolve_query_paths() uses is_link flag for  translation
- convert_ids() kept as deprecated shim

23 new unit tests for FieldResolution and resolve_query_paths.

Fixes #937, #945
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] search criteria not using pydantic Field alias to set the key.

1 participant